首页 文章

如何在C程序中将向量传递给GNU Octave函数?

提问于
浏览
0

从“How to exit GNU Octave, after running an m file, without closing plot windows?”出来的问题是,是否可以将向量从C程序传递到GNU Octave函数 . 我有这个C程序:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <utility>
#include <unistd.h>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h>
using namespace std;

double N     = 1000.0;
double t0    = 0.0;
double t1    = 10.0;
double x0    = 0.0;
double dx0   = 0.0;
double h     = (t1 - t0) / double(N);

double dx2(double t, double x, double dx)
{
    return {-9.8*cos(x + dx)};
}

std::pair<double, double> RK4(double t, double x, double dx, double h)
{
    // k values are diffs in dy/dx.
    // l values are diffs in x.
    double k1, k2, k3, k4, l1, l2, l3, l4, diff1, diff2;
    k1 = h*dx2(t,x,dx);
    l1 = h*dx;
    k2 = h*dx2(t+h/2,x+l1/2,dx+k1/2);
    l2 = h*(dx+k1/2);
    k3 = h*dx2(t+h/2,x+l2/2,dx+k2/2);
    l3 = h*(dx+k2/2);
    k4 = h*dx2(t+h,x+l3,dx+k3);
    l4 = h*(dx+k3);
    diff1 = (l1+2*l2+2*l3+l4)/float(6); // diff in x.
    diff2 = (k1+2*k2+2*k3+k4)/float(6); // diff in y.
    return {diff1, diff2};
}

int main()
{
    std::vector<double> t;
    t.push_back(t0);
    std::vector<double> x;
    x.push_back(x0);
    std::vector<double> dx;
    dx.push_back(dx0);

    ofstream myfile;
        ofstream myfiledx;
    myfile.open("simppenadj.txt");
        myfiledx.open("simppenadjdx.txt");

    for(int i = 1; i<=N; i++) {
        auto diff = RK4(t[i-1],x[i-1],dx[i-1],h);
        t.push_back(  t[i-1] + h);
        x.push_back(  x[i-1] + diff.first  );
        dx.push_back(dx[i-1] + diff.second );
        myfile << t[i-1];
        myfile << " " << x[i-1] << "\n";
                myfiledx << x[i-1];
                myfiledx << " " << dx[i-1] << "\n";
        usleep(1000);
    }
    myfile << t[N];
        myfile << " " << x[N];
        myfile.close();
        myfiledx << x[N];
        myfiledx << " " << dx[N];
        myfiledx.close();

    pid_t pid = fork();

    if(pid != 0) // parent
    {
        std::cout << "parent, exiting\n";
    }
    else
    {
            // arguments for octave
        string_vector argv (2);
        argv(0) = "embedded";
        argv(1) = "-q"; // quiet

        // start octave, run embedded (third parameter == true)
        octave_main (2, argv.c_str_vec (), true);

        // read the script file
        source_file("simppenadj.m");

        // call the function with an argument
        octave_value_list in;
        in(0) = t;
            in(1) = x;
            in(2) = dx;
        feval("simppenadj",in,1);

        std::cout << "octave (child process) done\n";
        clean_up_and_exit(0); // quit octave. This also quits the program,
                                  // so use this together with atexit, if you
                                  // need to do something else after octave exits
        }
}

in(0)in(1)in(2) 定义行是此代码中存在问题的位置 . 每当编译该程序并运行错误时:

/usr/bin/g++ -Wall -fPIC -L/usr/lib/octave/4.0.3 -I/usr/include/octave-4.0.3 -loctave -loctinterp -o "simppenadj.o" "simppenadj.cpp" && chmod +x simppenadj.o && ./simppenadj.o
simppenadj.cpp: In function ‘int main()’:
simppenadj.cpp:97:14: error: no match for ‘operator=’ (operand types are ‘octave_value’ and ‘std::vector<double>’)
      in(0) = t;
              ^
In file included from /usr/include/octave-4.0.3/octave/oct-obj.h:33:0,
                 from /usr/include/octave-4.0.3/octave/ov-fcn.h:31,
                 from /usr/include/octave-4.0.3/octave/ov-builtin.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-int.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-dld.h:30,
                 from /usr/include/octave-4.0.3/octave/oct.h:36,
                 from simppenadj.cpp:8:
/usr/include/octave-4.0.3/octave/ov.h:356:17: note: candidate: octave_value& octave_value::operator=(const octave_value&)
   octave_value& operator = (const octave_value& a)
                 ^~~~~~~~
/usr/include/octave-4.0.3/octave/ov.h:356:17: note:   no known conversion for argument 1 from ‘std::vector<double>’ to ‘const octave_value&’
simppenadj.cpp:98:12: error: no match for ‘operator=’ (operand types are ‘octave_value’ and ‘std::vector<double>’)
    in(1) = x;
            ^
In file included from /usr/include/octave-4.0.3/octave/oct-obj.h:33:0,
                 from /usr/include/octave-4.0.3/octave/ov-fcn.h:31,
                 from /usr/include/octave-4.0.3/octave/ov-builtin.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-int.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-dld.h:30,
                 from /usr/include/octave-4.0.3/octave/oct.h:36,
                 from simppenadj.cpp:8:
/usr/include/octave-4.0.3/octave/ov.h:356:17: note: candidate: octave_value& octave_value::operator=(const octave_value&)
   octave_value& operator = (const octave_value& a)
                 ^~~~~~~~
/usr/include/octave-4.0.3/octave/ov.h:356:17: note:   no known conversion for argument 1 from ‘std::vector<double>’ to ‘const octave_value&’
simppenadj.cpp:99:12: error: no match for ‘operator=’ (operand types are ‘octave_value’ and ‘std::vector<double>’)
    in(2) = dx;
            ^~
In file included from /usr/include/octave-4.0.3/octave/oct-obj.h:33:0,
                 from /usr/include/octave-4.0.3/octave/ov-fcn.h:31,
                 from /usr/include/octave-4.0.3/octave/ov-builtin.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-int.h:28,
                 from /usr/include/octave-4.0.3/octave/defun-dld.h:30,
                 from /usr/include/octave-4.0.3/octave/oct.h:36,
                 from simppenadj.cpp:8:
/usr/include/octave-4.0.3/octave/ov.h:356:17: note: candidate: octave_value& octave_value::operator=(const octave_value&)
   octave_value& operator = (const octave_value& a)
                 ^~~~~~~~
/usr/include/octave-4.0.3/octave/ov.h:356:17: note:   no known conversion for argument 1 from ‘std::vector<double>’ to ‘const octave_value&’
make: *** [Makefile:3: all] Error 1

退回 . 显然, std::vector<double> 输入存在一些输入问题 . 所以问题是,"How does one pass vectors from C++ programs to GNU Octave functions called in said programs?"

1 回答

  • 0

    我通过一个小循环这样做:

    std::vector<double> x;
    Matrix inMatrix_x( x.size(), 1 );
    for( unsigned int i = 0; i < x.size(); i++ )
    {
        inMatrix_x(i, 0) = x.at(i); // inMatrix_x(i) would also do the job
    }
    octave_value_list in;
    in(0) = inMatrix_x;
    

    如果你想从skript中获取数据,你必须在 outMatrix_y.length() 上进行iterize .

相关问题