Octave, GNU Octave, Matlab, Scientific Computing, Language, Interpreter, Compiler, C++, LAPACK, Fortran, Fun , GNU

Friday, January 18, 2008

Octave-2-Matlab and back (2)

Like I mentioned earlier here. I finally managed to put together a AST-visitor pattern that
loads the user-script parses it, and gives it to the conversion tree-walker code. This implements
the changes mentioned in the oct2mat package (find it here) by Paul Kienzle .

The email announcing this code and patch was posted

Hello there,

I have a oct2mat like the one Paul Kienzle mentions in his
README file based on the AST walker. Utilizing Octave's
parse tree to do the conversion is very helpful and accurate
to a larger degree. Its still a work in progress (my disclaimer).

Large parts of the code are directly derived from Octave
source written by JWE.

This script is essentially to help deploy code to your colleagues
who want to use it on Matlab systems for whatever reason. Primary
development is still expected to be based on an Octave based
environment.

You can invoke the script as,

octave:1> oct2mat("full/path/my_cool_octave_function.m",1)
octave:2> oct2mat("full/path/my_cool_octave_script.m")

and the code is output to stdout, where from you can use some shell
scripts to redirect the output to another matlab directory.

I have attached the files. Im waiting for JWE to accept some
global export patches to access some parser information. Once that is
done, I plan to add it to the extras branch of octave-forge.

This code works only on the cvs version of Octave, as a external add-on.

Limitations include

1. Can treat only function files or script files not both.
2. Pollutes your command history, as it pipes out to octave_stdout.
3. Cannot handle a script file with function definitions
4. Doesnot write to a separate directory or file, just all output on
stdout. So you need to create a driver program.
5. Not sure if it works correctly for all cases.

Best,
-Muthu



The Code / Tree Walker

I also made patches against existing code from Octave tree (maybe obsolete right now), so
as to help integrate my tree walker into the existing visitor.

Index: pt-pr-code.cc
===================================================================
RCS file: /cvs/octave/src/pt-pr-code.cc,v
retrieving revision 1.54
diff -u -p -r1.54 pt-pr-code.cc
--- pt-pr-code.cc 12 Oct 2007 21:27:33 -0000 1.54
+++ pt-pr-code.cc 10 Jan 2008 05:56:20 -0000
@@ -35,6 +35,240 @@ along with Octave; see the file COPYING.
#include "pr-output.h"
#include "pt-all.h"

+
+static std::string
+matlab_unary_op_as_string (octave_value::unary_op op)
+{
+ std::string retval;
+
+ switch (op)
+ {
+ case octave_value::op_not:
+ retval = "~";
+ break;
+
+ case octave_value::op_uplus:
+ retval = "+";
+ break;
+
+ case octave_value::op_uminus:
+ retval = "-";
+ break;
+
+ case octave_value::op_transpose:
+ retval = ".'";
+ break;
+
+ case octave_value::op_hermitian:
+ retval = "'";
+ break;
+
+ case octave_value::op_incr:
+ retval = "++";
+ break;
+
+ case octave_value::op_decr:
+ retval = "--";
+ break;
+
+ default:
+ retval = "
";
+ }
+
+ return retval;
+}
+
+static std::string
+matlab_binary_op_as_string (octave_value::binary_op op)
+{
+ std::string retval;
+
+ switch (op)
+ {
+ case octave_value::op_add:
+ retval = "+";
+ break;
+
+ case octave_value::op_sub:
+ retval = "-";
+ break;
+
+ case octave_value::op_mul:
+ retval = "*";
+ break;
+
+ case octave_value::op_div:
+ retval = "/";
+ break;
+
+ case octave_value::op_pow:
+ retval = "^";
+ break;
+
+ case octave_value::op_ldiv:
+ retval = "\\";
+ break;
+
+ case octave_value::op_lshift:
+ retval = "<<"; + break; + + case octave_value::op_rshift: + retval = ">>";
+ break;
+
+ case octave_value::op_lt:
+ retval = "<"; + break; + + case octave_value::op_le: + retval = "<="; + break; + + case octave_value::op_eq: + retval = "=="; + break; + + case octave_value::op_ge: + retval = ">=";
+ break;
+
+ case octave_value::op_gt:
+ retval = ">";
+ break;
+
+ case octave_value::op_ne:
+ retval = "~=";
+ break;
+
+ case octave_value::op_el_mul:
+ retval = ".*";
+ break;
+
+ case octave_value::op_el_div:
+ retval = "./";
+ break;
+
+ case octave_value::op_el_pow:
+ retval = ".^";
+ break;
+
+ case octave_value::op_el_ldiv:
+ retval = ".\\";
+ break;
+
+ case octave_value::op_el_and:
+ retval = "&";
+ break;
+
+ case octave_value::op_el_or:
+ retval = "|";
+ break;
+
+ case octave_value::op_struct_ref:
+ retval = ".";
+ break;
+
+ default:
+ retval = "
";
+ }
+
+ return retval;
+}
+
+static void
+do_oct2mat_oper(std::ostream &os, tree_binary_expression &expr)
+{
+ std::string oprval="
";
+
+ // this converts code into whatever form
+ // oct2mat requires.
+ if ( expr.is_boolean_expression() )
+ {
+ const tree_boolean_expression & tbr
+ = dynamic_cast
(expr);
+
+ oprval="
";
+
+ switch ( tbr.op_type() )
+ {
+ case tree_boolean_expression::bool_and:
+ oprval = "&";
+ break;
+
+ case tree_boolean_expression::bool_or:
+ oprval = "|";
+ break;
+
+ defualt:
+ oprval = "
";
+ }
+ }
+ else
+ {
+ oprval=matlab_binary_op_as_string(expr.op_type());
+ }
+
+ os << " " << oprval="">";
+
+ oprval=matlab_unary_op_as_string(expr.op_type());
+ os << " " <<>accept(omat);
+ buf_str = buf.str();
+ os << idx="0;">= 0);
+
+ s << ""; + if (printing_newlines) + { + if (beginning_of_line) + { + s << i =" 0;" beginning_of_line =" false;">accept (*this);

- os << " " << op2 =" expr.rhs">accept (*this);

@@ -237,7 +474,10 @@ tree_print_code::visit_simple_for_comman

indent ();

- os << "endfor"; + if ( convert_to_matlab ) + os << "end"; + else + os << "endfor"; } void @@ -280,7 +520,10 @@ tree_print_code::visit_complex_for_comma indent (); - os << "endfor"; + if ( convert_to_matlab ) + os << "end"; + else + os << "endfor"; } void @@ -401,7 +644,10 @@ tree_print_code::visit_octave_user_funct indent (); - os << "endfunction"; + if ( convert_to_matlab ) + os << "%% endfunction"; + else + os << "endfunction"; newline (); } @@ -414,7 +660,17 @@ tree_print_code::visit_identifier (tree_ print_parens (id, "("); std::string nm = id.name (); - os << (nm.empty () ? std::string ("(empty)") : nm); + + if ( convert_to_matlab ) + { + std::map
::iterator iter= identifier_lut.find(nm);
+ if ( iter != identifier_lut.end() )
+ os <<>second ;
+ else
+ os << (nm.empty () ? std::string ("(empty)") : nm); + } + else + os << (nm.empty () ? std::string ("(empty)") : nm); print_parens (id, ")"); } @@ -459,7 +715,10 @@ tree_print_code::visit_if_command (tree_ indent (); - os << "endif"; + if ( convert_to_matlab ) + os << "end"; + else + os << "endif"; } void @@ -693,11 +952,75 @@ tree_print_code::visit_no_op_command (tr void tree_print_code::visit_constant (tree_constant& val) { + std::string buf_str; + std::ostringstream buf; + int idx = 0; + octave_value sval=val.rvalue(); indent (); print_parens (val, "("); - val.print_raw (os, true, print_original_text); + + if ( convert_to_matlab ) + { + if ( sval.is_string() ) + { + buf_str=sval.string_value(); + // see if you need to escape the string stxt. + os << "'"; + for( idx=0; idx < buf_str =" buf.str();" idx="0;">accept (*this);

- os << e =" expr.operand" s =" indent_to_string">accept (*this);
+ // print a commented code.
+ if ( convert_to_matlab )
+ {
+ std::string ind_prfx = indent_to_string( );
+ do_print_commented_code(unwind_protect_code,os,ind_prfx);
+ }
+ else
+ unwind_protect_code->accept (*this);

decrement_indent_level ();
}
@@ -1022,7 +1374,10 @@ tree_print_code::visit_unwind_protect_co

indent ();

- os << "unwind_protect_cleanup"; + if ( convert_to_matlab ) + os << "%%unwind_protect_cleanup"; + else + os << "unwind_protect_cleanup"; newline (); @@ -1032,7 +1387,13 @@ tree_print_code::visit_unwind_protect_co { increment_indent_level (); - cleanup_code->accept (*this);
+ if ( convert_to_matlab )
+ {
+ std::string ind_prfx = indent_to_string( );
+ do_print_commented_code(cleanup_code,os,ind_prfx);
+ }
+ else
+ cleanup_code->accept (*this);

decrement_indent_level ();
}
@@ -1041,7 +1402,10 @@ tree_print_code::visit_unwind_protect_co

indent ();

- os << "end_unwind_protect"; + if ( convert_to_matlab ) + os << "%%end_unwind_protect"; + else + os << "end_unwind_protect"; } void @@ -1075,7 +1439,10 @@ tree_print_code::visit_while_command (tr indent (); - os << "endwhile"; + if ( convert_to_matlab ) + os << "end"; + else + os << "endwhile"; } void @@ -1192,7 +1559,10 @@ tree_print_code::print_comment_elt (cons if (c == '\n') { if (prev_char_was_newline) - os << "##"; + if ( convert_to_matlab ) + os << "%" ; + else + os << "##"; newline (); @@ -1206,7 +1576,11 @@ tree_print_code::print_comment_elt (cons indent (); - os << "##"; + + if ( convert_to_matlab ) + os << "%%"; + else + os << "##"; if (! (isspace (c) || c == '!')) os << " "; Index: pt-pr-code.h =================================================================== RCS file: /cvs/octave/src/pt-pr-code.h,v retrieving revision 1.36 diff -u -p -r1.36 pt-pr-code.h --- pt-pr-code.h 12 Oct 2007 21:27:33 -0000 1.36 +++ pt-pr-code.h 10 Jan 2008 05:56:20 -0000 @@ -26,6 +26,7 @@ along with Octave; see the file COPYING. #include

#include

+#include


#include "comment-list.h"
#include "pt-walk.h"
@@ -41,14 +42,23 @@ public:

tree_print_code (std::ostream& os_arg,
const std::string& pfx = std::string (),
- bool pr_orig_txt = true)
+ bool pr_orig_txt = true, bool to_matlab = false)
: os (os_arg), prefix (pfx), nesting (),
- print_original_text (pr_orig_txt),
+ print_original_text (pr_orig_txt), convert_to_matlab( to_matlab ),
curr_print_indent_level (0), beginning_of_line (true),
printing_newlines (true)
{
// For "none".
nesting.push ('n');
+ if ( convert_to_matlab )
+ {
+ identifier_lut["SEEK_CUR"]="0";
+ identifier_lut["SEEK_END"]="1";
+ identifier_lut["SEEK_SET"]="-1";
+ identifier_lut["usage"]="error";
+ identifier_lut["print_usage"]="error";
+ identifier_lut["__error_text__"]="lasterr";
+ }
}

~tree_print_code (void) { }
@@ -147,6 +157,12 @@ private:

bool print_original_text;

+ // flag controls if tree print code converts to Matlab.
+ bool convert_to_matlab;
+
+ //
+ std::map
identifier_lut;
+
// Current indentation.
int curr_print_indent_level;

@@ -176,6 +192,8 @@ private:

void print_indented_comment (octave_comment_list *comment_list);

+ std::string indent_to_string( );
+
// Must create with an output stream!

tree_print_code (void);




I still have bugs in the driver routine, but hey it works!.
-Muthu

Saturday, January 5, 2008

Octave-3.0 released on 12/21/07!

Tired of paying exorbitant license fees for toolboxes and packages
that are severely restricted? Does your vendor allow only "Educational"
use of the software, and not for research purposes?

Whatever your reason, you are going to love Octave-3.0. Distributed under
the GNU GPL license Octave is freely available software, that does not
restrict you from installing only X number of copies, or using the package
only for doing Y only. Octave gives you freedom from proprietary vendors,
while providing you every other feature as the competition.

Switch to Octave Today! With 3.0 release GNU Octave on 21st Dec 2007,
has plenty of new features including N-dimensional arrays, support for sparse
matrices, enhanced 2/3-D graphics integration with gnuplot, platform
specific binaries for easy installation, image toolbox and much more.

Enjoy the following advantages, including but not limited to,

1. Liberal licensing terms allow any number of installation.
- this means no more 20-user seat license + 12-toolbox license and
all that mess!
- Focus on problem solving instead of worrying about
licensing, and if a computer is available with all license. Old style.

2. Octave ships with excellent documentation and a 600+ page manual.
- Excellent community support available through help@octave.org
mailing lists.

>>>>>>>>> Extremely Rich Documentation <<<<<<<<<
1. a 600 page manual, http://omega.uta.edu/~mxa6471/octave.pdf
2. FAQ booklet, http://omega.uta.edu/~mxa6471/Octave-FAQ.pdf

3. LibOctave Documentation on C++ extensions for Octave,
http://omega.uta.edu/~mxa6471/liboctave.pdf

4. Handy reference card in 2 pages of all syntax you'll ever need!
http://omega.uta.edu/~mxa6471/refcard-a4.pdf



3. Octave runs on Windows, Linux, Unix and all of these platforms, and
includes graphic user interface too!
- Download the source code from www.octave.org/downloads
- Windows binaries available from Octave-forge project at
https://sourceforge.net/project/showfiles.php?group_id=2888
Octave-3.0.0 : https://sourceforge.net/project/showfiles.php?group_id=2888&package_id=40078&release_id=564586
4. Extra 60+ Toolboxes available for use from octave-forge project.
- want to do communications analysis? advanced signal processing,
3D, and 2D plotting, neural networks, graphs, sparse matrix, protein database,
optimization, linear-programming, all supported through our toolboxes.

>>>>>>> Extra-Packages/Toolboxes : 60 <<<<<<<<<
Additional packages ( toolbox in Matlab lingo ) are available from
the Octave-Forge project. About 60 packages are ready for use listed
at the website http://octave.sourceforge.net/packages.html

* Supporting development of GNU Octave, Today!
GNU Octave has been in continued development atleast since 1992.
Octave is primarily developed by Dr. John W. Eaton, from the
University of Wisconsin at Madison, and other volunteers. As a community
driven project, GNU Octave support heavily relies on contributions from
schools and universities that use Octave software. While donations are not
mandatory, they are welcome and ensure the longevity and continued
development of Octave. A rising tide, lifts all boats.

If you are interested in contributing/donating to GNU Octave, please visit
http://www.gnu.org/software/octave/funding.html , for the details.

* Feel free to checkout GNU-Octave project today.
Visit: www.gnu.org/software/octave for current upto-date information on
on installing Octave from prebuilt binaries or source code, or to join
the development of Octave.

For questions and comments please contact muthuspost [AT] gmail [DOT] com.


* This advertisement was written by Muthiah Annamalai, on 3, Jan, 2008.

Creative Commons License