Sign of a symbolic algebraic expression

311 views Asked by At

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

There are 1 answers

2
Spektre On

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:

  1. 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 is type (which table to use) and second is id (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
    
  2. After compilation you need to interpret the string and evaluate it's value.

    1. 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
      
    2. read first record of compiled string

      if it is value (number,constant,variable) set appropriate op? value with it and increment operand counter opn++.

      if it is function set fx,fxn code with it

    3. if opn == fxn

      You reached needed operand count so execute function fx and init next function

      op1=fxtab[fx].pointer(op1,op2,...)
      fx=none,fxn=1
      opn=1  (some spec functions can return more operands, then set op1,op2,.. opn=...)
      
    4. if not end of string goto #2 but with next string record

    5. 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