在C中调用GNU Octave函数吗? [英] Call GNU Octave functions in C?

查看:110
本文介绍了在C中调用GNU Octave函数吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用矩阵代数和优化.我已经为矩阵代数测试了不同的C和C ++库,但是它们的问题是它们不能像GNU Octave一样处理垃圾数据. C和C ++中的垃圾数据降低到了e-8的水平,但是在GNU Octave中,数据将被降低到e-17的水平.如果您打算在计算中使用例如测量中的垃圾数据,这将非常有用.它们不会影响您的结果.

I want to use matrix algebra and optimization. I have tested different C and C++ libraries for matrix algebra but the problem with those is they cannot handle garbage data as good as GNU Octave does. Garbage data in C and C++ goes low to like e-8 but in GNU Octave it will be pushed down way to low as e-17. That's very useful if you planning to use garbage data from e.g measurement in calculations. They don't effect nothing of your results.

但是GNU Octave有一个C ++ API,我不太了解如何使用.但是我想使用C并从C​​调用GNU Octave函数.

But GNU Octave have a C++ API, which I don't really understand how to use. But I want to use C and call GNU Octave functions from C.

有可能我可以创建一个包含2D数组和维度的结构,然后将其发送到GNU Octave,然后我将再次返回一个具有结果和维度的结构,例如解决方案.

Is that possible that I can create a struct that contains a 2D array and dimensions, and send it to GNU Octave and I will return a struct again that have the result and the dimension e.g solution.

推荐答案

有交流 mex 界面.但是,在调用任何mex函数之前,必须先嵌入并初始化八度音阶解释器.从链接的答案建议,从Octave 4.4开始,octave_main已被弃用,并且还需要进行一些其他更改才能实现对mex程序有用.因此,我准备了一个包含函数mexCallOctavefree_arg_list及其头文件calloctave.h的c ++源文件.

There is a c mex interface. However the octave interpreter must be embedded and initialized before any mex function can be called. As of Octave 4.4 octave_main as suggested by the linked answer has been deprecated and some other changes also are needed for it to be useful for mex programs. So I have prepared a c++ source file calloctave.cc containing the functions mexCallOctave and free_arg_list and its header calloctave.h.

calloctave.cc

// calloctave.cc

#include "interpreter.h"
#include "mxarray.h"
#include "parse.h"

extern "C"
int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
               mxArray *argin[], const char *fname)
{

  static octave::interpreter embedded_interpreter;
  if (!embedded_interpreter.initialized())
    embedded_interpreter.execute ();

  octave_value_list args;

  args.resize (nargin);

  for (int i = 0; i < nargin; i++)
    args(i) = mxArray::as_octave_value (argin[i]);

  bool execution_error = false;

  octave_value_list retval;


  retval = octave::feval (fname, args, nargout);

  int num_to_copy = retval.length ();

  if (nargout < retval.length ())
    num_to_copy = nargout;

  for (int i = 0; i < num_to_copy; i++)
    {
      argout[i] = new mxArray (retval(i));
    }

  while (num_to_copy < nargout)
    argout[num_to_copy++] = nullptr;

  return execution_error ? 1 : 0;
}

extern "C"
void 
free_arg_list (int nargs, mxArray* arglist[])
{
    for(int i = 0; i < nargs; i++)
            delete arglist[i];
}

calloctave.h

// calloctave.h
#pragma once
#include "mex.h"

#if defined  (__cplusplus)
extern "C" {
#endif

int
mexCallOctave (int nargout, mxArray *argout[], int nargin,
               mxArray *argin[], const char *fname);
void 
free_arg_list (int nargs, mxArray* arglist[]);

#if defined  (__cplusplus)
}
#endif

此处是对mex文件的基本介绍.您可以编译示例hello world程序,在其中添加选项--verbose作为mkoctfile --mex --verbose hello.c,以获得需要使用它们来编译实际程序的编译器选项的列表.请注意,由于calloctave.cc是c ++源代码,因此应使用c ++编译器(例如g ++)进行编译. 在以下示例中,调用了m函数"myfunction".它获得一个输入并产生一个输出. mexCallOctave用于调用八度音程函数,它具有与 mexCallMATLAB相同的签名.

Here is a basic introduction into mex files. You can compile an example hello world program adding the option --verbose as mkoctfile --mex --verbose hello.c to get the list of compiler options that you need to use them for compilation of your actual programs. Note that because calloctave.cc is a c++ source it should be compiled using a c++ compiler such as g++. In the following example a m function "myfunction" is called. It gets one input and produces one output. mexCallOctave is used for calling the octave function and it has the same signature as mexCallMATLAB.

myfunction.m

% myfunction.m
function out=  myfunction( a )
    out = sum(a);
endfunction

main.c

//main.c
#include <stdio.h>
#include "calloctave.h"   
int main()
{
    double input_data[] = {0,1,2,3,4,5,6,7,8,9,10};

    const int nargin = 1;
    const int nargout = 1;
    mxArray* rhs[nargin];
    mxArray* lhs[nargout];

    // allocate mex array
    rhs[0] = mxCreateDoubleMatrix( 10, 1, mxREAL);
    double* rhs_ptr = mxGetPr( rhs[0] );

    // copy data from input buffer to mex array
    for (int i = 0 ; i < 10; i++)
        rhs_ptr[i] = input_data[i];

    // call octave function
    mexCallOctave(nargout, lhs, nargin, rhs, "myfunction");

    double* lhs_ptr = mxGetPr( lhs[0] );

    double output_data = *lhs_ptr;

    // show the result
    printf ("result = %f", output_data);

    // free memory

    mxDestroyArray(rhs[0]);
    free_arg_list(nargout, lhs);
}

这篇关于在C中调用GNU Octave函数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆