符号代数表达式的标志

时间:2013-12-22 11:35:48

标签: algorithm algebra computer-algebra-systems

是否有任何算法可以找到“树形”中给出的任意符号代数表达式的符号?

我知道一般算法不存在,因为零识别问题对于任意表达式是不可判定的,但我该如何处理找到表达式符号的问题呢? (这是如何在计算机代数中完成的?)

例如:sign(sqrt(2)-1) = ?

1 个答案:

答案 0 :(得分:0)

评估功能值

你需要功能评估器引擎​​(代码并不难)如果你想支持+,没办法评估仅签名 , - 操作!!!我所有的函数评估器都是这样的:

  1. 编译函数的源文本

    首先创建支持的函数表(id,操作数,名称,函数指针),如:

    +,-,*,/,sin,cos,....
    

    这些将是您需要评估的任何受支持表达式的构建块。不要忘记编写代码中的所有函数。将括号()也作为函数(push,pop)处理。按操作数的数量对函数进行分组,以便+,-有1个和2个操作数(每个操作数有两个不同的函数!!!)。

    现在来自表达式提取:

    • 变量名称
    • 常数名称和值
    • 数值

    进入某种表/列表:

    variables[](id,name,value)
    constants[](id,name,value)
    numbers  [](id,    ,value)
    

    现在最后构造编译的函数字符串。我的字符串设置为两个int。首先是type(使用哪个表),第二个是id(表中的索引)。

    例如表达式:

    sign(sqrt(2)-1)
    

    <强>类型:

    id type
    0  function
    1  number
    2  constant
    3  variable
    

    <强>功能

    id name   pointer
    0  '('    ???
    1  ')'    ???
    2  '+'    ???
    3  '-'    ???
    4  '*'    ???
    5  '/'    ???
    6  'sqrt' ???
    7  'sign' ???
    

    没有变量常量数字是:

    id value
    0  2  
    1  1
    

    已编译的字符串:

    type id
    0    7   // sign(1 operand)
    0    6   // sqrt(1 operand)
    1    0   // 2
    0    3   // - (2 operands)
    1    1   // 1
    
  2. 编译完成后,您需要解释字符串并评估其值。

    1. init变量

      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. 读取已编译字符串的第一条记录

      如果是值(number,constant,variable),则用它设置适当的op?值并增加操作数计数器opn++

      如果它是函数集fx,fxn代码

    3. 如果opn == fxn

      您达到了所需的操作数,因此执行函数fx和init next函数

      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. 如果不是字符串的结尾goto #2 但是有下一个字符串记录

    5. 在结尾op1应保留您的输出值

  3. 一些示例函数(C ++实现):

    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; }
    

    <强> [注释]

    您必须处理function = "";等特殊情况。还要注意间距,区分大小写,因为编译中的任何错误都会使结果无效。

    速度不是一个大问题,这是解释 - 评估而不是数值解决方案。所有操作都与您在纸上所做的操作相同。

    您还应该处理数学错误(溢出,无效操作数,NaNInf ...)

    我通常将具有相同数量的操作数的函数分组为自己的类型以简化事情