2013-12-22 55 views
4

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

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

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

+0

当你说“代数“,它是否包含未知数? – Eric

+0

不,它没有变量。另外,当我说“代数”时,我不是说它只能包含algeraic数字。它也可能包含类似log(2)或atan(2)的东西。但我不想寻找一个通用算法。 –

+2

您应该以足够的精度评估表达式。您可能想要使用任意精度算术包,并且可能需要使用区间算术。 –

回答

0

评估函数值

您需要为该函数鉴别发动机(它并不难代码)有是没有办法来评估只签署如果你想支持+, -操作!我所有的功能评估是这样的:

  1. 编译功能的源文本

    首先创建支持的功能表(ID,操作数名NUM,函数指针),如:

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

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

    从表达提取

    现在:

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

    变成某种表/列表:

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

    现在终于construc t编译函数字符串。我的字符串被设置为两个int's。首先是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. 初始化变量

      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. 读编译串

      的第一个记录,如果它是值(数字,常量,变量)设置适当op?值与它和增量操作数计数器opn++

      如果是功能设置fx,fxn代码与它

    3. 如果opn == fxn

      达到需要你如果不能结束的字符串操作数计数,以便执行功能fx和初始化一个功能

      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. 转到#2但与下一个字符串记录

    5. op1应持有的产值

一些示例功能(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; } 

[注意事项]

你有来处理像这样的特殊情况。同时要小心间距,区分大小写,因为编译错误会导致结果无效。

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

你也应该处理的数学错误(溢出,无效的操作数,NaNInf ...)

我通常与相同数量的操作数的组功能,以自己的类型,以简化的东西

+0

我已经有了一个字符串表达式的数字和符号分析器。但是我想知道这是如何在计算机代数(如Mathematica或Maple)中完成的。这真的是由表达式的数值完成的吗? –

+0

我认为是的,因为如果你在公式中有加法或减法,那么符号是由操作数的符号和值来定义的......所以我看不出有其他方式来做符号确定 – Spektre