#ifndef _OCTAVEPARSER_CC_
#define _OCTAVEPARSER_CC_
#include "BufferedNode.h"
#include "Matrix.h"
#include "CompositeType.h"
#include "octave/oct.h"
#include "octave/parse.h"
#include "octave/variables.h"
#include "octave/sysdep.h"
#include "octave/pathsearch.h"
#include "octave/defaults.h"
#include "octave/file-io.h"
#include "octave/ops.h"
#include "octave/error.h"
#include "octave/oct-env.h"
namespace FD {
class OctaveParser;
DECLARE_NODE(OctaveParser)
}
/*Node
* @name OctaveParser
* @category Octave
* @description Parse a .m or a .oct file and executes it.
*
* @input_name FILE_NAME
* @input_type string
* @input_description The file name of the script to execute.
*
* @input_name VARIABLES_IN
* @input_type Composite
* @input_description Input variables inside a composite (Matrices)
*
* @output_name VARIABLES_OUT
* @output_type Vector<ObjectRef>
* @output_description Result of the octave code execution
*
* @parameter_name VERBOSE
* @parameter_type bool
* @parameter_value true
* @parameter_description Put Octave in verbose mode
END*/
using namespace std;
extern void install_builtins (void);
class FD::OctaveParser : public FD::BufferedNode {
//inputs
int m_fileID;
int m_variableInID;
//outputs
int m_variableOutID;
//parameters
bool m_verbose;
public:
OctaveParser(string nodeName, FD::ParameterSet params)
: FD::BufferedNode(nodeName, params) {
//inputs
m_fileID = addInput("FILE_NAME");
m_variableInID = addInput("VARIABLES_IN");
//outputs
m_variableOutID = addOutput("VARIABLES_OUT");
//parameters
m_verbose = dereference_cast<bool>(parameters.get("VERBOSE"));
//init octave
// The order of these calls is important. The call to
// install_defaults must come before install_builtins because
// default variable values must be available for the variables to be
// installed, and the call to install_builtins must come before the
// options are processed because some command line options override
// defaults by calling bind_builtin_variable.
//add script path
string OctPath = octave_env::getenv("OCTAVE_PATH");
OctPath += string(":") + string(OCTAVE_SCRIPTS_PATH) + string("//");
octave_env::putenv("OCTAVE_PATH",OctPath);
sysdep_init ();
//initialize_error_handlers ();
install_defaults ();
//initialize_pathsearch ();
//install_signal_handlers ();
initialize_file_io ();
initialize_symbol_tables ();
install_types ();
install_ops ();
install_builtins ();
octave_env::chdir(OCTAVE_SCRIPTS_PATH);
}
void calculate(int output_id, int count, FD::Buffer &out) {
FD::RCPtr<FD::String> file_name = getInput(m_fileID,count);
FD::RCPtr<FD::CompositeType> inputVariables = getInput(m_variableInID,count);
//create output composite
RCPtr<CompositeType> outComposite = RCPtr<CompositeType>(new CompositeType);
//clear symbol table
if (top_level_sym_tab) {
top_level_sym_tab->clear();
}
FD::CompositeType::map_type cMap = inputVariables->getAllFields();
for (FD::CompositeType::map_type::iterator iter = cMap.begin();
iter != cMap.end(); iter++) {
std::string mName = iter->first;
FD::RCPtr<FD::Matrix<complex<double> > > mPtr = iter->second;
//Create octave matrix
ComplexMatrix *octaveMatrix = new ComplexMatrix(mPtr->nrows(), mPtr->ncols());
//copy elements
for (int r = 0; r < mPtr->nrows(); r++) {
for (int c= 0; c < mPtr->ncols(); c++) {
(*octaveMatrix)(r,c) = (*mPtr)(r,c);
}
}
//put input variables in symbol table
symbol_record *record = top_level_sym_tab->lookup(mName,true,true);
if (record) {
record->define(*octaveMatrix,symbol_record::USER_VARIABLE);
}
}
//parse octave file, verbose = m_verbose
parse_and_execute (*file_name, m_verbose);
//get all variables in the symbol table
if (top_level_sym_tab) {
//top_level_sym_tab->print_info(cerr);
string_vector variableNames = top_level_sym_tab->variable_name_list();
//variableNames.list_in_columns(cerr);
for (int i = 0; i <variableNames.length(); i++) {
symbol_record* symbol = top_level_sym_tab->lookup(variableNames[i]);
if (symbol) {
octave_value &value = symbol->variable_value();
//conversion to matrix
ComplexMatrix matrix_value = value.complex_matrix_value(true);
int rows = matrix_value.rows();
int cols = matrix_value.cols();
//create an equivalent FD object
FD::Matrix<complex<double> > *FDMatrix = new FD::Matrix<complex<double> >(rows,cols);
//copy content
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
(*FDMatrix)(r,c) = matrix_value(r,c);
}
}
//add in the Composite
outComposite->addField(variableNames[i],ObjectRef(FDMatrix));
}
}
}
//output them
out[count] = outComposite;
}//calculate
};
#endif
syntax highlighted by Code2HTML, v. 0.9.1