2013-12-22 58 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