Re: [問題] 簡化向量的方法

作者: jurian0101 (Hysterisis)   2014-01-15 22:08:26
※ 引述《ToMoveJizz (土木技師)》之銘言:
: 向量通常使用List來表示
: 比如說{Ax^2,Ay^2,Az^2}
: 有沒有辦法讓mathematica把這個A提出來?
: A可能是很複雜的expression
原本想推把List換成Plus,這樣就可以用Simplify提出公因數。
對{Ax^2,Ay^2,Az^2}可以這樣做。
但細想,要是原始List長得像{-1,1,1-x^2,1-x} 就完蛋了XD
順便提一下,原本乘法能進不能出的原因是 Times 的 Attribute 含有 Listable
於是Times[A, List[1,2,3]] 自動轉變成 List[Times[A,1], Times[A,2], Times[A,3]]
^^^^^ ^^^^餓虎撲羊
可執行代碼
Unprotect[Times];
ClearAttributes[Times, Listable];
SetAttribute[Times, Protected];
讓 A {1,2,3} 即使沒有Hold[]也乖乖保持原樣。
復原代碼
Unprotect[Times];
SetAttribute[Times, {Listable,Protected}];
=====
寫出來也不難,當作練習。
我考量之內最快最通用的寫法是利用內建函數FactorList,
然後作一些步驟去人工找最小公因式 <- 內建函數GCD當然"沒有"這個功能
=====
Clear[common];
common[exp_List] := Module[{a, b, int, sym, out},
a = FactorList /@ exp; (*factor乘數表*)
b = Union @@ a[[All, 2 ;;, 1]]; (*"非整數"符號表*)
int = GCD @@ a[[All, 1, 1]] ; (*公共整數因子*)
sym = Times @@ (*公共符號因子*)
MapThread[Power, {b, Min /@ Table[
If[MemberQ[#[[All, 1]], sym],
Cases[#, {sym, x_Integer} :> x][[1]], 0] & /@ a, {sym, b}]}];
out = int*sym; (*"最大公因式"*)
{out, Simplify[exp/out]} (*輸出*)
]
兩組測資
= =
In[1]:= common[{2 A x^2, 6 A y^2, 2 A z^2, 8 A}]
Out[1]= {2 A, {x^2, 3 y^2, z^2, 4}}
= =
In[2]:=
common[{2A x^2 (-1+x^2), 6A(2-3x+x^2) y^2, 2A (3-4x+x^2) z^2, 8A(-2+x+x^2)}]
Out[2]=
{2A (-1+x), {x^2 (1+x), 3 (-2+x) y^2, (-3+x) z^2, 4 (2+x)}}
作者: LPH66 (-6.2598534e+18f)   2014-01-15 22:12:00
GCD 不行可是有 PolynomialGCD...
作者: jurian0101 (Hysterisis)   2014-01-15 22:15:00
喵的你不早推= =每次都這樣XD
作者: ToMoveJizz ( )   2014-01-18 12:21:00
好像挺威的...SetAttribute"s" 少打了個s喔

Links booklink

Contact Us: admin [ a t ] ucptt.com