Hi,
I’m experimenting with embedding the Octave interpreter in C++ (so I can give users runtime model scripting). It sort of works, but I’m getting some unexpected behaviour.
First, I’ve created a test function, which looks like this…
function out = myFunction(params,bulkIn,bulkOut)
fprintf('bulkIn is %d \n',bulkIn);
fprintf('bulkOut is %d \n',bulkOut);
out = [1 2 3 ; params(1) params(2) params(3) ; 5 6 7];
endfunction
Then, I’ve created a c++ function to embed the interpreter, and call the routine twice, just to test it. When I run the code (below), it works fine on the first pass through but the second time it gives a nonsense value (essentially zero) for the second element of the array, with the others being just fine.
Does this have something to do with the fact that I’m trying only to do the initialisation (setting paths etc) on the first pass by making it static and setting an initialisation flag? I’m a bit stuck here and would welcome some help… this almost works except for the strange value of the second element.
The output from the code below is:
Function start:
Value of started is 0
In interpreter initialise loop
bulkIn is 2.073e-06
bulkOut is 6.35e-06
Output is 1 2 3
10 20 30
5 6 7
Number of elements is 9
element number 0 is 1
element number 1 is 10
element number 2 is 5
element number 3 is 2
element number 4 is 20
element number 5 is 6
element number 6 is 3
element number 7 is 30
element number 8 is 7
Function start:
Value of started is 1
bulkIn is 2.073e-06
bulkOut is 6.35e-06
Output is 1 2 3
1.01362e-316 20 30
5 6 7
Number of elements is 9
element number 0 is 1
element number 1 is 1.01362e-316
element number 2 is 5
element number 3 is 2
element number 4 is 20
element number 5 is 6
element number 6 is 3
element number 7 is 30
element number 8 is 7
And the code is (sorry - can’t quite work out how to use the code formatting properly here!)
#include <iostream>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>
#include <vector>
using namespace std;
static void octaveCallerFunction() {
cout << "Function start:" << endl;
static int started = 0;
static octave::interpreter interpreter;
std::cout << "Value of started is "
<< started
<< std::endl;
// check to see if the interpreter has started
// and initialise it if not.
if (started == 0) {
interpreter.initialize_history(false);
interpreter.initialize();
interpreter.execute();
string path = "/home/arwel/eclipseWorkspace_new/functionOctave_new/src";
octave_value_list p;
p(0) = path;
octave_value_list o1 = octave::feval ("addpath", p, 1);
cout << "In interpreter initialise loop" << endl;
started = 1;
}
vector<double> pars = {10, 20, 30, 40};
double bulkIn = 2.073e-6;
double bulkOut = 6.35e-6;
Matrix inPars(pars.size(),1);
for (unsigned int i; i < pars.size(); i++) {
inPars(i) = pars.at(i);
}
octave_value_list in;
in(0) = inPars;
in(1) = octave_value(bulkIn);
in(2) = octave_value(bulkOut);
octave_value_list out = octave::feval ("myFunction", in, 1);
if (out.length () > 0)
std::cout << "Output is "
<< out(0).matrix_value()
<< std::endl;
else
std::cout << "invalid\n";
Matrix v = out(0).matrix_value();
Array<double> rv = v.as_row(); //Maybe easier to deal with variable sized output as a vector?? (m always = 3)
// Pointer to start of our row vector
double *s = rv.fortran_vec();
octave_idx_type num = rv.dim2();
int n = num; // length of the row vector
cout << "Number of elements is " << n // check we get the right value for n
<< endl;
vector<double> vs(num); // eventually going to put the elements in here....
// print the values in the array pointed to by s
for (int i=0; i<n; i++) {
cout << "element number "<< i << " is " <<*(s + i) << endl;
}
cout << endl;
}
int main(void) {
octaveCallerFunction();
std::cout << std::endl;
octaveCallerFunction();
return 0;
}