Embedding octave in c++ - How to pas a variable sized vector

Viewed 161

I'm trying to embed the Octave interpreter in C++, and the m files that will be called will always be of this type...

function out = myFunction(pars, val1, val2)

% pars will always be a variable sized row vector of doubles
% val1 will always be a 1 x 1 double
% val2 will also be a  1 x 1 double

% out will always be a [n x 3] array e.g

out = [1 2 3 ; 4 5 6 ; 7 8 9];

endfunction

I have sort of got this working but only if I pass a single value for pars. So, if I have in as an octave_value_list, then



double pars = 10;
double bulkIn = 20;
double bulkOut = 30;

octave_value_list in;
in(0) = pars;
in(1) = bulkIn;
in(2) = bulkOut;

octave_value_list out = octave::feval("myFunction", in);

..this works. What I can't figure out is how to put an array into in(0). I've tried the approach below, but if fails because "no known conversion for argument 1 from 'std::vector<double? to const octave_value&"

Eventually, pars will come in to octaveCallerFunction as an argument of std::vector from 'main'. So my question is how do I correctly get a variable sized row vector into in(0)?

#include <iostream>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>
#include <vector>

using namespace std;

int octaveCallerFunction() {

    static int started = 0;
    static octave::interpreter interpreter;

    // 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 = "<the relevant path goes here>";
        octave_value_list p;
        p(0) = path;
        octave_value_list o1 = octave::feval ("addpath", p, 1);
        cout << "In interpreter initialise loop" << endl;
        started = 1;
    }

    octave_value_list in;

    vector<double> pars = {1, 2, 3, 4};

    double bulkIn = 2.073e-6;
    double bulkOut = 6.35e-6;

    in(0) = pars;
    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(0)
                << std::endl;
    else
      std::cout << "invalid\n";

    return 0;
}

int main(void) {


    octaveCallerFunction();
    return 0;
}
1 Answers

I'm still not 100% what you're trying to achieve (your comment sounds the reverse of the original question), but I hope this example helps regardless :)

%% in file myFunction.m
function Out = myFunction( pars, val1, val2 )
    Out = (val1 + val2) .* pars;
endfunction

// In file octtest.cpp
#include <iostream>
#include <vector>
#include <oct.h>
#include <octave.h>
#include <parse.h>
#include <interpreter.h>

void octaveCallerFunction() {
    octave::interpreter interpreter;
    Matrix P(1,3), A(1,3), B(1,3);
    octave_value_list in, out;

    P(0,0)= 1; P(0,1) = 2; P(0,2) = 3;
    A(0,0)= 4; A(0,1) = 5; A(0,2) = 6;
    B(0,0)= 7; B(0,1) = 8; B(0,2) = 9;
    in(0) = P; in(1) = A; in(2) = B;

    interpreter.execute();
    out = octave::feval ("myFunction", in, 1);
    interpreter.shutdown ();

 // Use normal octave facilities to print
    std::cout << "Output directly from Matrix type =" << out(0).matrix_value(); // std::endl implied by Matrix

 // Collect into std::vector first and print using that
    std::vector<double>  outvector = { out(0).matrix_value()(0), out(0).matrix_value()(1), out(0).matrix_value()(2)  };
    std::cout << "Output from standard std::vector =";
    for( int i = 0; i < outvector.size(); i++ ) { std::cout << ' ' << outvector[i]; }
    std::cout << std::endl;
}

int main(void) { octaveCallerFunction(); }

Compile:

mkoctfile --link-stand-alone octtest.cpp -o octtest

Output:

Output directly from Matrix type = 11 26 45
Output from standard std::vector = 11 26 45
Related