问题
Is there any algorithm that can find the sign of an arbitrary symbolic algebraic expression given in a "Tree - Form"?
I know that a general algorithm doesn't exist because the zero recognizion problem is undecidable for an arbitrary expression, but how should I approach the problem of finding the sign of an expression? (how is this done in computer algebra?)
For example: sign(sqrt(2)-1) = ?
回答1:
Evaluate the function value
You need function evaluator engine for that (it is not that hard to code) there is no way to evaluate sign only if you want to support +,- operations !!! All my function evaluators works like this:
compile the source text of the function
First create supported functions table (id,num of operands,name,pointer to function) like:
+,-,*,/,sin,cos,....
These will be the building blocks to any supported expression you need to evaluate. Do not forget to code all functions in your code too. Handle brackets
(
,)
also as functions (push,pop
). Group your functions by number of operands so+,-
are with 1 and 2 operands (two different functions each !!!).Now from expression extract:
- variable names
- constant names and values
- number values
Into some kind of table/list:
variables[](id,name,value) constants[](id,name,value) numbers [](id, ,value)
And now finally construct compiled function string. My strings are set of two
int
's. First istype
(which table to use) and second isid
(index in table).for example expression:
sign(sqrt(2)-1)
types:
id type 0 function 1 number 2 constant 3 variable
functions:
id name pointer 0 '(' ??? 1 ')' ??? 2 '+' ??? 3 '-' ??? 4 '*' ??? 5 '/' ??? 6 'sqrt' ??? 7 'sign' ???
There are no variables or constants. The numbers are:
id value 0 2 1 1
compiled string:
type id 0 7 // sign(1 operand) 0 6 // sqrt(1 operand) 1 0 // 2 0 3 // - (2 operands) 1 1 // 1
After compilation you need to interpret the string and evaluate it's value.
init variables
op1=0`,`op2=0, // set all operands to zero (number depends on supported functions usually 2) opn=0 // actual operands number fx=none // actual function (for example none=-1) fxn=0 // actual function operands number
read first record of compiled string
if it is value (number,constant,variable) set appropriate
op?
value with it and increment operand counteropn++
.if it is function set
fx,fxn
code with itif
opn == fxn
You reached needed operand count so execute function
fx
and init next functionop1=fxtab[fx].pointer(op1,op2,...) fx=none,fxn=1 opn=1 (some spec functions can return more operands, then set op1,op2,.. opn=...)
if not end of string goto #2 but with next string record
at the end
op1
should hold your output value
some example functions (C++ implementation):
double sign(double op1)
{
if (op1>0.0) return +1.0;
if (op1<0.0) return -1.0;
return 0.0;
}
double sqrt1(double op1) { return sqrt(op1); }
double plus1(double op1) { return op1; }
double minus1(double op1) { return -op1; }
double plus2(double op1,double op2) { return op1+op2; }
double minus2(double op1,double op2) { return op1-op2; }
[Notes]
You have to handle special cases like function = "";
. Also beware spacing, case sensitivity because any error in compilation invalidates the result.
Speed is not a big issue this is interpreting-evaluation not numerical solution. All operations are called the same times as you would do on the paper.
You should also handle mathematic errors (overflows,invalid operands,NaN
,Inf
...)
I usually group functions with the same number of operands to own type to simplify things
来源:https://stackoverflow.com/questions/20728954/sign-of-a-symbolic-algebraic-expression