2009-06-12 6 views
1

MATLABのSymbolic Toolkitを使用して、CまたはC++の派生物を記号的に評価するにはどうすればよいですか?Cコードからシンボリックな派生を評価するにはどうすればMATLABにフックできますか?

+0

が、これは問題でしょうか? – second

+0

いいえ..それは私が他の人が役に立つと思うかもしれない情報です。 – eduffy

+0

それから質問と回答の形で語ってください。 http://stackoverflow.com/questions/18557/how-does-stackoverflow-work-the-unofficial-faq#119658 – dmckee

答えて

2

gcc \ Linuxの場合はMakefileとともに、Cの実例があります。誰かがWindowsやMac用のビルド手順を提供できる場合は、してください。

まずCコード:

#define _GNU_SOURCE 
#include <stdio.h> 
#include <ctype.h> 
#include <stdlib.h> 
#include <string.h> 
#include <engine.h> 

int main (int argc, char *argv[]) 
{ 
    Engine *engine; 
    mxArray *f; 
    mxChar *output; 
    char  *input; 
    char  *command; 
    size_t  input_size; 
    int  i; 

    engine = engOpen ("matlab -nojvm"); 
    engEvalString (engine, "syms x"); 

    input = NULL; 
    printf (">> "); getline (&input, &input_size, stdin); 
    while (!feof (stdin)) { 
     // remove the \n character 
     input[strlen (input) - 1] = '\0'; 
     command = (char *)malloc (strlen (input) + 19); 
     sprintf (command, "f=simple(diff(%s,x))", input); 

     // execute the `diff` command on the user input expression 
     engEvalString (engine, command); 

     // the MATLAB engine does not understand the Symbolic Toolbox 
     // therefore you have to convert the output expression into 
     // some textual form (ccode,fortran,matlabFunction,latex) 
     engEvalString (engine, "fstr=ccode(f)"); 
     f = engGetVariable (engine, "fstr"); 
     output = mxGetChars (f); 

     // the expression is prefixed with some left-hand line (eg, "t0=") 
     // so, discard everything to the left of the =, and display just 
     // the derivative 
     for (i = 0; output[i] != '='; i++); 
     i++; // skip the = 

     // `mxChar` is a 16-bit character, and `printf ("%ls")` is giving 
     // me errors, so go through the string one character at a time, until 
     // the semicolon is found (it is C-code), ignoring non-printable 
     // characters along the way. 
     for (; output[i] != ';'; i++) { 
      if (isgraph (output[i])) { 
       putchar (output[i]); 
      } 
     } 
     putchar ('\n'); 
     printf (">> "); getline (&input, &input_size, stdin); 
    } 

    printf ("exiting...\n"); 
    engClose (engine); 
    return EXIT_SUCCESS; 
} 

あなたが式を使用する必要がある場合は、代わりに、単にそれをエコーで、あなたがあなた自身のパーサを記述する必要があります。しかし、シンプルなC式(math.hの関数を使って)はとても簡単です。

ここに私のMakefileはありません。何も想像しないでください。あなたのパスを適切に設定してください。

CC=gcc 
CFLAGS=-O0 -g -Wall -I$(MATLAB_DIR)/extern/include 
LDFLAGS=-L$(MATLAB_DIR)/bin/glnxa64 -leng -lmx -lmat -lut -licudata -licuuc -licui18n -licuio -lhdf5 
MATLAB_DIR=/opt/matlab/2008a 

%.o: %.c 
    $(CC) $(CFLAGS) -c $< -o [email protected] 

diff_test: diff_test.o 
    $(CC) $< -o [email protected] $(LDFLAGS) 

そして最後に、迅速デモ:

# ./diff_test 
>> sin(x) 
cos(x) 
>> 2*x^2*tan(x) 
2.0*x*(2.0*tan(x)+x+x*pow(tan(x),2.0)) 
>> log(x^2) 
2.0/x 
>> ^D 
exiting... 
関連する問題