summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fun.cpp309
-rw-r--r--src/fun.h96
2 files changed, 302 insertions, 103 deletions
diff --git a/src/fun.cpp b/src/fun.cpp
index 4eeb24c..71b7d45 100644
--- a/src/fun.cpp
+++ b/src/fun.cpp
@@ -17,116 +17,183 @@
#include <octave/interpreter.h>
#include <math.h>
#include <string>
+#include <cstring>
#include "fun.h"
extern "C"
{
+ /*!
+ * \brief Function to Interact with Octave's API.
+ *
+ * This Function will be communicating with Octave to access it's function.
+ */
int fun(FUNCARGS *inp, FUNCCALL *funcall)
{
- static octave::interpreter interpreter;
+ static octave::interpreter interpreter;
bool status = interpreter.initialized();
-
- if(status==false)
+ // Check octave interpreter loaded
+ if (status == false)
{
- interpreter.initialize ();
- int status_exec = interpreter.execute ();
+ interpreter.initialize();
+ int status_exec = interpreter.execute();
if (status_exec != 0)
{
std::cerr << "creating embedded Octave interpreter failed!"
- << std::endl;
+ << std::endl;
}
}
-
+
try
- {
+ {
octave_value_list in;
unsigned int k;
int l;
int str_count = 0;
char str_fun[20];
char str_pkg[20];
- int pkg=0;
+ int pkg = 0;
int nouts;
- for(l=0;l<funcall->n_in_arguments;l++)
+ // Format the input data values into data type acceptable by Octave
+ for (l = 0; l < funcall->n_in_arguments; l++)
{
- if(inp[l].type==TYPE_DOUBLE)
+ //check if Input type is Double
+ if (inp[l].type == TYPE_DOUBLE)
{
- if(inp[l].is_in_cmplx==1)
+ if (inp[l].is_in_cmplx == 1)
{
- ComplexMatrix matr = ComplexMatrix (inp[l].n_in_rows,inp[l].n_in_cols);
- double* id_real = (double *)inp[l].in_data_real;
- double* id_img = (double *)inp[l].in_data_img;
- k=0;
- for (int r=0;r<inp[l].n_in_rows;r++)
- {
- for(int c=0;c<inp[l].n_in_cols;c++)
- {
- Complex cc(id_real[k],id_img[k]);
- matr(r,c) = cc;
+ ComplexMatrix matr = ComplexMatrix(inp[l].n_in_rows, inp[l].n_in_cols);
+ double *id_real = (double *)inp[l].in_data_real;
+ double *id_img = (double *)inp[l].in_data_img;
+ k = 0;
+ for (int r = 0; r < inp[l].n_in_rows; r++)
+ {
+ for (int c = 0; c < inp[l].n_in_cols; c++)
+ {
+ Complex cc(id_real[k], id_img[k]);
+ matr(r, c) = cc;
k++;
- }
- }
- in(l-str_count) = octave_value(matr);
+ }
+ }
+ in(l - str_count) = octave_value(matr);
}
else
{
- Matrix inMatrix_x(inp[l].n_in_rows,inp[l].n_in_cols);
- double* id = (double *)inp[l].in_data_real;
- k=0;
- for( unsigned int i = 0; i < inp[l].n_in_rows; i++ )
+ Matrix inMatrix_x(inp[l].n_in_rows, inp[l].n_in_cols);
+ double *id = (double *)inp[l].in_data_real;
+ k = 0;
+ for (unsigned int i = 0; i < inp[l].n_in_rows; i++)
{
- for( unsigned int j = 0; j < inp[l].n_in_cols; j++ )
+ for (unsigned int j = 0; j < inp[l].n_in_cols; j++)
{
- inMatrix_x(i, j) = id[k];
- k++;
+ inMatrix_x(i, j) = id[k];
+ k++;
}
}
- in(l-str_count) = inMatrix_x;
+ in(l - str_count) = inMatrix_x;
}
}
- else if(inp[l].type==TYPE_STRING)
+ //check if Input type is string
+ else if (inp[l].type == TYPE_STRING)
{
//std::cout << "In fun string. l is : " << l << '\n';
-
- char* c = (char *)inp[l].in_data_real;
+
+ char *c = (char *)inp[l].in_data_real;
//std::cout << "String is: " << c << '\n';
- if(l==0)
- strcpy(str_fun,c);
- else if(l==1)
+ if (l == 0)
+ strcpy(str_fun, c);
+ else if (l == 1)
{
- strcpy(str_pkg,c);
- pkg=1;
- }
+ strcpy(str_pkg, c);
+ pkg = 1;
+ }
else
- in(l-str_count) = c;
+ in(l - str_count) = c;
str_count++;
//std::cout << "String is: " << c << '\n';
}
- }
+ //check if Input type is struct
+ else if (inp[l].type == TYPE_STRUCT){
+ FUNCSTRUCT* inStruct = inp[l].in_struct;
+
+ octave_scalar_map inOctaveStruct;
+
+ // populate the octave structure
+ for (int j = 0; j < inp[l].n_in_struct_len; j++){
+ std::string currKey;
+ octave_value currValue;
- if(pkg==1)
+ // converting wchar_t* to string for octave
+ std::wstring currKeyWStr((wchar_t *) inStruct[j].key);
+ currKey = std::string(currKeyWStr.begin(), currKeyWStr.end());
+
+
+ // get Value
+ if (inStruct[j].type == TYPE_COMPLEX){
+ ComplexMatrix currValueMatrix = ComplexMatrix(inStruct[j].rows, inStruct[j].cols);
+ double* dReal = (double *)inStruct[j].dataReal;
+ double* dImg = (double *)inStruct[j].dataImg;
+ k = 0;
+ for (int r = 0; r < inStruct[j].rows; r++)
+ {
+ for (int c = 0; c < inStruct[j].cols; c++)
+ {
+ Complex currItem(dReal[k], dImg[k]);
+ currValueMatrix(r, c) = currItem;
+ k++;
+ }
+ }
+ currValue = currValueMatrix;
+ }
+ else if(inStruct[j].type == TYPE_DOUBLE){
+ Matrix currValueMatrix = Matrix(inStruct[j].rows, inStruct[j].cols);
+ double* dReal = (double *)inStruct[j].dataReal;
+ k = 0;
+ for (int r = 0; r < inStruct[j].rows; r++)
+ {
+ for (int c = 0; c < inStruct[j].cols; c++)
+ {
+ currValueMatrix(r, c) = dReal[k];
+ k++;
+ }
+ }
+ currValue = currValueMatrix;
+ }
+ else if (inStruct[j].type == TYPE_STRING){
+ std::wstring currValueWStr((wchar_t *) inStruct[j].str);
+ std::string currValueStr(currValueWStr.begin(), currValueWStr.end());
+ currValue = octave_value(currValueStr);
+ }
+ inOctaveStruct.assign(currKey, currValue);
+ }
+
+ // insert struct to input octave list
+ in(l - str_count) = inOctaveStruct;
+ }
+ }
+ // Load the octave package
+ if (pkg == 1)
{
//std::cout << "loading package " << str_pkg << '\n';
- octave::feval ("pkg", ovl ("load", str_pkg), 0);
+ octave::feval("pkg", ovl("load", str_pkg), 0);
}
+ // Use feval to compute the required values
+ octave_value_list out = octave::feval(str_fun, in, funcall->n_out_user);
- octave_value_list out = octave::feval (str_fun, in, funcall->n_out_user);
-
-
- int row;
- int col;
+ int row = 0;
+ int col = 0;
nouts = out.length();
funcall->n_out_arguments = nouts;
-//std::cout << "funcall->n_out_arguments is: " << funcall->n_out_arguments << '\n';
-
- for( unsigned int ii = 0; ii < nouts; ii++ )
+ // DEBUG // std::cout << "funcall->n_out_arguments is: " << funcall->n_out_arguments << '\n';
+ // Format and set the output data values from Octave into the FUNCARGS
+ for (unsigned int ii = 0; ii < nouts; ii++)
{
- if(out(ii).iscomplex()==1)
+ //Format complex data
+ if (out(ii).iscomplex() == 1)
{
- inp[ii].is_out_cmplx=1;
+ inp[ii].is_out_cmplx = 1;
//std::cout << "out "<< ii<< " is complex" << '\n';
ComplexMatrix cmOut(out(ii).complex_matrix_value());
//std::cout << "cmOut "<< cmOut << '\n';
@@ -136,54 +203,144 @@ extern "C"
col = cmOut.columns();
inp[ii].n_out_rows = row;
inp[ii].n_out_cols = col;
- k=0;
- inp[ii].out_data_real = malloc(sizeof(double)*(row*col));
- inp[ii].out_data_img = malloc(sizeof(double)*(row*col));
- double* rd = (double *)inp[ii].out_data_real;
- double* cd = (double *)inp[ii].out_data_img;
- for(unsigned int i=0;i<row;i++)
+ k = 0;
+ inp[ii].out_data_real = malloc(sizeof(double) * (row * col));
+ inp[ii].out_data_img = malloc(sizeof(double) * (row * col));
+ double *rd = (double *)inp[ii].out_data_real;
+ double *cd = (double *)inp[ii].out_data_img;
+ for (unsigned int i = 0; i < row; i++)
{
- for(unsigned int j=0;j<col;j++)
+ for (unsigned int j = 0; j < col; j++)
{
- rd[k]=real(cmOut(k));
- cd[k]=imag(cmOut(k));
+ rd[k] = real(cmOut(k));
+ cd[k] = imag(cmOut(k));
//std::cout << "out img "<< k << " is :" << (double)imag(cmOut(k)) << '\n';
k++;
}
}
}
+ //Format Struct data
+ else if(out(ii).isstruct()){
+ inp[ii].is_out_struct = 1;
+
+ octave_scalar_map outOctaveStruct = out(ii).scalar_map_value();
+
+ int structLen = outOctaveStruct.nfields();
+ inp[ii].n_out_struct_len = structLen;
+
+ inp[ii].out_struct = (FUNCSTRUCT *) malloc(sizeof(FUNCSTRUCT) * structLen);
+ FUNCSTRUCT* outStruct = inp[ii].out_struct;
+
+ octave_scalar_map::iterator idx = outOctaveStruct.begin();
+ int j = 0;
+
+ // std::cout << "data in fun.cpp\n";
+ // populating structure
+ while (idx != outOctaveStruct.end()){
+ std::string currKey = outOctaveStruct.key(idx);
+ octave_value currValue = outOctaveStruct.contents(idx);
+
+ // storing key by converting string to wchar_t* for scilab
+ outStruct[j].key = malloc(sizeof(wchar_t) * (currKey.length() + 1));
+ mbstowcs((wchar_t *) outStruct[j].key, currKey.c_str(), currKey.length() + 1);
+
+ // storing value
+ if (currValue.iscomplex()){
+ outStruct[j].type = TYPE_COMPLEX;
+
+ ComplexMatrix currValueComplexMatrix(currValue.complex_matrix_value());
+
+ row = currValueComplexMatrix.rows();
+ col = currValueComplexMatrix.columns();
+ outStruct[j].rows = row;
+ outStruct[j].cols = col;
+
+ outStruct[j].dataReal = malloc(sizeof(double) * (row * col));
+ outStruct[j].dataImg = malloc(sizeof(double) * (row * col));
+
+ double* dReal = (double *) outStruct[j].dataReal;
+ double* dImg = (double *) outStruct[j].dataImg;
+
+ k = 0;
+ for (int r = 0; r < row; r++)
+ {
+ for (int c = 0; c < col; c++)
+ {
+ dReal[k] = real(currValueComplexMatrix(k));
+ dImg[k] = imag(currValueComplexMatrix(k));
+ k++;
+ }
+ }
+
+ }
+ else if (currValue.is_string()){
+ outStruct[j].type = TYPE_STRING;
+ std::string currValueStr = currValue.string_value();
+ outStruct[j].str = malloc(sizeof(wchar_t) * (currValueStr.length() + 1));
+ mbstowcs((wchar_t*) outStruct[j].str, currValueStr.c_str(), currValueStr.length() + 1);
+ }
+ else {
+ outStruct[j].type = TYPE_DOUBLE;
+
+ Matrix currValueMatrix(currValue.matrix_value());
+
+ row = currValueMatrix.rows();
+ col = currValueMatrix.columns();
+ outStruct[j].rows = row;
+ outStruct[j].cols = col;
+
+ outStruct[j].dataReal = malloc(sizeof(double) * (row * col));
+ double* dReal = (double *) outStruct[j].dataReal;
+
+ k = 0;
+ for (int r = 0; r < row; r++)
+ {
+ for (int c = 0; c < col; c++)
+ {
+ dReal[k] = currValueMatrix(k);
+ k++;
+ }
+ }
+ }
+
+ j++;
+ idx++;
+ }
+ }
+ // Format Matrix data
else
{
//std::cout << "out "<< ii<< " is NOT complex" << '\n';
- inp[ii].is_out_cmplx=0;
+ inp[ii].is_out_cmplx = 0;
Matrix mOut(out(ii).matrix_value());
row = mOut.rows();
col = mOut.columns();
inp[ii].n_out_rows = row;
inp[ii].n_out_cols = col;
- k=0;
- inp[ii].out_data_real = malloc(sizeof(double)*(row*col));
- double* dd = (double *)inp[ii].out_data_real;
- for(unsigned int i=0;i<row;i++)
+ k = 0;
+ inp[ii].out_data_real = malloc(sizeof(double) * (row * col));
+ double *dd = (double *)inp[ii].out_data_real;
+ for (unsigned int i = 0; i < row; i++)
{
- for(unsigned int j=0;j<col;j++)
+ for (unsigned int j = 0; j < col; j++)
{
- dd[k]=mOut(k);
+ dd[k] = mOut(k);
k++;
}
}
}
}
}
- catch (const octave::exit_exception& ex)
+ // Exception handling Octave
+ catch (const octave::exit_exception &ex)
{
std::cerr << "Octave interpreter exited with status = "
- << ex.exit_status () << std::endl;
+ << ex.exit_status() << std::endl;
return 1;
}
- catch (const octave::execution_exception&)
+ catch (const octave::execution_exception &)
{
- //std::cerr << "error encountered in Octave evaluator!" << std::endl;
+ //DEBUG//std::cerr << "error encountered in Octave evaluator!" << std::endl;
return 1;
}
return 0;
diff --git a/src/fun.h b/src/fun.h
index e5e1fff..673ad70 100644
--- a/src/fun.h
+++ b/src/fun.h
@@ -13,37 +13,79 @@
//extern "C" int fun (double* answ, double* in1, int in1_row, std::string name, std::string opt);
extern "C"
-{
+{
- typedef enum
- {
- TYPE_DOUBLE,
- TYPE_STRING,
+ /**
+ *
+ * @brief Enumeration for the data types suported by the fun()
+ *
+ */
+ typedef enum {
+ TYPE_DOUBLE, /**similar to scilab double*/
+ TYPE_COMPLEX, /**similar to scilab complex*/
+ TYPE_STRING, /**similar to scilab string*/
+ TYPE_STRUCT, /**similar to scilab struct*/
}FUNCTYPE;
- typedef struct
- {
- FUNCTYPE type;
- int n_in_rows;
- int n_in_cols;
- int n_out_rows;
- int n_out_cols;
- int is_in_cmplx;
- int is_out_cmplx;
- void* in_data_real;
- void* in_data_img;
- void* out_data_real;
- void* out_data_img;
- }FUNCARGS;
-
+ /**
+ * @struct FUNCSTRUCT
+ * @brief Struct used to pass structs to Octave from the fun library
+ * @var type
+ *
+ */
+
typedef struct {
- int n_in_arguments; // number of input arguments
- int n_out_arguments; // number of output arguments
- int n_out_user; // number of output arguments
- char *err; // Name
- //char *package; //Name of octave package to be loaded
- FUNCARGS *argument;
-} FUNCCALL;
+ FUNCTYPE type; /// Type of value in struct's field
+ void* key; /// key of struct field
+ int rows; /// rows dimension of struct field's value
+ int cols; /// cols dimension of struct fields' value
+ void* dataReal; /// Real data if struct field's value is real
+ void* dataImg; /// Img data if struct field's value is complex
+ void* str; /// String data if struct field's value is string
+ } FUNCSTRUCT;
+
+ /**
+ * @brief Struct used to send/receive Scilab data to/from the gateway to fun.cpp API
+ *
+ */
+ typedef struct {
+ FUNCTYPE type; /// Type of data
+ int n_in_rows; /// Input rows dimension of data
+ int n_in_cols; /// Input cols dimension of data
+ int n_in_struct_len; /// input struct length
+ int n_out_rows; /// Ouput rows dimension of data
+ int n_out_cols; /// Output cold dimension of data
+ int n_out_struct_len; /// Output struct length
+ int is_in_cmplx; /// Input is a Complex data type
+ int is_out_cmplx; /// Output is a Complex data type
+ int is_out_struct; /// Output is a Struct data type
+ void* in_data_real; /// Input real part (complex) array
+ void* in_data_img; /// Input imaginary part (complex) array
+ void* out_data_real; /// Output real part (complex) array
+ void* out_data_img; /// Output imaginary part (complex) array
+ FUNCSTRUCT* in_struct; /// Input struct
+ FUNCSTRUCT* out_struct; /// Output struct
+ } FUNCARGS;
+ /**
+ * @brief Struct used to call and pass the data to fun.cpp API
+ *
+ */
+ typedef struct {
+ int n_in_arguments; /// Number of input arguments
+ int n_out_arguments; /// Number of output arguments
+ int n_out_user; /// Number of output arguments
+ char *err; /// Return errors
+ //char *package; //Name of octave package to be loaded
+ FUNCARGS *argument; /// Struct defining and containing the data
+ } FUNCCALL;
+ /**
+ * @brief API Function to call/receive and pass the data to fun API
+ *
+ *
+ * @param arr Input data FUNCARGS
+ * @param call Input Arguments FUNCCALL
+ * @return int
+ */
int fun(FUNCARGS *arr, FUNCCALL *call);
}