2015-09-25 103 views
2

我正在使用MathNet Symbolics來處理我正在處理的程序的符號代數部分。一般用途是創建一對符號公式,然後將這兩個公式分開。這在大多數情況下都很有效。但是,有時候,它不想做更復雜的簡化。例如:使用MathNet提取常用術語Symbolics

     (512*r*t*w + 2048*r*t^2*w) 
----------------------------------------------------------------------- 
(512*r*t*w + 512*r^2*t*w + 3072*r*t^2*w + 3072*r^2*t^2*w + 1024*r*t^3*w) 

一段時間的努力,我已經能夠把它消除w從公式,因爲它是在所有方面的頂部和底部:

    (512*r*t + 2048*r*t^2) 
-------------------------------------------------------------- 
(512*r*t + 512*r^2*t + 3072*r*t^2 + 3072*r^2*t^2 + 1024*r*t^3) 

不過,我想不通如何讓它找到共同的術語:

  (512*r*t)*(1 + 4*t) 
-------------------------------------- 
(512*r*t)(1 + r + 6*t + 6*r*t + 2*t^2) 

和消除這些條款:

  (1 + 4*t) 
----------------------------- 
(1 + r + 6*t + 6*r*t + 2*t^2) 

我一直在使用Wolfram Alpha作爲檢查工作的黃金標準。從LinqPad我一直工作在最午後的代碼,即得到我的w消除:

var h1 = MathNet.Symbolics.Infix.ParseOrUndefined("(1/8)*r*t*w + (1/2)*r*t^2*w"); 
var h2 = MathNet.Symbolics.Infix.ParseOrUndefined("(1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w"); 

Infix.Print(Rational.Expand(h1/h2)).Dump(); //Prints (512*r*t*w + 2048*r*t^2*w)/(512*r*t*w + 512*r^2*t*w + 3072*r*t^2*w + 3072*r^2*t^2*w + 1024*r*t^3*w) 
var tot = Rational.Expand(h1/h2); 

var simplified = true; 
do 
{ 
    simplified=false; 
    foreach (var v in Rational.Variables(tot)) 
    { 
     var result = Polynomial.Divide(v, h1, h2); 
     if (!result.Item1.Equals(MathNet.Symbolics.Expression.Zero)) 
     { 
      simplified = true; 
      tot = result.Item1; 
      break; 
     } 
    } 
}while(simplified); 
tot = Rational.Expand(tot); 

Infix.Print(tot).Dump(); //Prints (512*r*t + 2048*r*t^2)/(512*r*t + 512*r^2*t + 3072*r*t^2 + 3072*r^2*t^2 + 1024*r*t^3) 

能有人給我指點如何與MathNet繼續嗎?我嘗試過RationalPolynomial之間的各種功能組合,並且無法通過這一點。

回答

1

我剛剛發佈了一個新的Symbolics Math.NET釋放v0.6.0其中包括一個新的Rational.Reduce例程消除了這種常見的簡單的因素(也可作爲的Rational.Expand一部分執行):

var h1 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/2)*r*t^2*w"); 
var h2 = Infix.ParseOrThrow("(1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w"); 

var q1 = h1/h2; 
Infix.Print(q1); 
// returns: ((1/8)*r*t*w + (1/2)*r*t^2*w)/((1/8)*r*t*w + (1/8)*r^2*t*w + (3/4)*r*t^2*w + (3/4)*r^2*t^2*w + (1/4)*r*t^3*w) 

var q2 = Rational.Expand(q1); 
Infix.Print(q2); 
// returns: (1 + 4*t)/(1 + r + 6*t + 6*r*t + 2*t^2) 

遺憾的是不少的像新的平方無因式分解這樣的單變量多項式和有理例程還沒有多變量對應。單變量例程需要一個符號參數,而多變量例程需要符號集。

+0

非常好,謝謝。在這之間,以及我在週末做了一些工作(對每個變量重複調用「Rational.Simplify」,然後看看它是否減少了操作數),現在我得到了更自然的結果。我今天晚些時候可能會有另一個問題,關於處理可能更好的小數的有理數(例如:58916322729/2048000000000000000000000)。或者至少可以在打印公式時強制使用小數形式。 –

+0

如果我們有這樣一個變體,什麼樣的規則可以決定什麼時候評估和舍入?所有有理數只有?所有條款包括沒有符號?應該評估功能嗎? –

+0

我一直在思考。在我的特殊用例中,只有在一種情況下才需要它。我會說在Print()上的一個變體將理性轉化爲實數,或者能夠在表達式中包含實數。我嘗試了文檔中提到的可變路由,但由於可能的係數很多,這導致了成千上萬的表達式。如果在圖書館方面沒有簡單的解決方案,我的計劃是尋找只有數字和a /的對的對,然後用小數代替。 –