PDA

查看完整版本 : 如何连接MATLAB来评估C代码中的符号导数?


poster
2019-12-10, 16:49
如何使用MATLAB的Symbolic Toolkit来象征性地评估C或C ++的派生类?


回答:
这是一个使用C的工作示例,以及gcc \ Linux的Makefile 。如果有人可以提供Windows或Mac的构建说明,请这样做。

首先是C代码:

#define _GNU_SOURCE #include #include #include #include #include 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 $@ diff_test: diff_test.o $(CC) $< -o $@ $(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...

更多&回答... (https://stackoverflow.com/questions/986663)