2010-01-21 344 views
9

我想弄清楚如何使用Mathematica来求解方程组,其中一些变量和系数是向量。一个简单的例子是像在Mathematica中求解向量方程

A + Vt = Pt

,我知道一个V,并P的大小,我必须解决和的方向 P.(基本上,给定两条射线A和B,我知道关于A的所有内容,但只知道B的原点和大小,找出B的方向必须与A相交。)

现在,我知道如何通过手工来解决这类问题,但这很慢且容易出错,所以我希望我可以使用Mathematica加快速度并对错误进行检查。但是,我看不出如何让Mathematica象征性地求解包含这种向量的方程。

我查看过VectorAnalysis包,没有找到任何似乎相关的东西;同时线性代数包似乎只有线性系统的解算器(这不是,因为我不知道tP,只是| P |)。

我试着做了头脑简单的事情:扩张向量到他们的组件(假装他们是3D),并解决这些问题,如果我试图相当于2个参数函数,

Solve[ 
     { Function[t, {Bx + Vx*t, By + Vy*t, Bz + Vz*t}][t] == 
      Function[t, {Px*t, Py*t, Pz*t}][t], 
     Px^2 + Py^2 + Pz^2 == Q^2 } , 
     { t, Px, Py, Pz } 
    ] 

但“解决方案”吐出的是大量的系数和拥塞。这也迫使我扩大我喂养它的每个维度。

我要的是在点产品,跨产品,和规范方面具有很好的象征意义的解决方案:

alt text

,但我看不出告诉Solve,一些系数是向量而不是标量。

这可能吗? Mathematica可以为矢量提供符号解决方案吗?或者我应该坚持2号铅笔技术?我只是想问一下,如果我可以使用Mathematica解决像这样的计算几何问题,而不需要将所有内容都表达为一个明确的矩阵{Ax, Ay, Az}等)

+0

也许值得你花时间向Mathematica的人问这个问题。他们可能比我们更了解自己的软件。 – 2010-01-21 05:00:19

+1

我会尝试发布到MathGroup论坛(http://forums.wolfram.com/)。它似乎不像邮件[email protected]会提供有用的结果。 – Crashworks 2010-01-21 05:06:42

+1

然而,令人惊讶的是,信噪比(以及整个系统)在这里比在“老式”邮件列表/论坛/新闻组中更好。 – 2010-01-22 01:52:40

回答

5

我没有任何通用的解决方案给你(MathForum可能是更好的方法),但有一些提示,我可以为你提供。首先是以更系统的方式将矢量扩展为组件。例如,我会解决你写的等式如下。

rawSol = With[{coords = {x, y, z}}, 
    Solve[ 
    Flatten[ 
    {A[#] + V[#] t == P[#] t & /@ coords, 
    Total[P[#]^2 & /@ coords] == P^2}], 
    Flatten[{t, P /@ coords}]]]; 

然后,您可以更轻松地使用rawSol变量。接下来,因为您以统一的方式引用矢量组件(总是匹配Mathematica模式v_[x|y|z]),您可以定义有助于简化它们的规则。我逛了一下打过来了下列规则之前:

vectorRules = 
    {forms___ + vec_[x]^2 + vec_[y]^2 + vec_[z]^2 :> forms + vec^2, 
    forms___ + c_. v1_[x]*v2_[x] + c_. v1_[y]*v2_[y] + c_. v1_[z]*v2_[z] :> 
    forms + c v1\[CenterDot]v2}; 

这些规则将简化为载体的规范和点积(跨产品留很有可能成为一种痛苦的练习留给读者)的关系。 编辑: rcollyer指出,你可以使c在dot产品的规则中是可选的,所以你只需要两个规则和点积的规则。

有了这些规则,我立刻能为t解决方案简化成非常接近你的一种形式:

In[3] := t /. rawSol //. vectorRules // Simplify // InputForm 
    Out[3] = {(A \[CenterDot] V - Sqrt[A^2*(P^2 - V^2) + 
            (A \[CenterDot] V)^2])/(P^2 - V^2), 
      (A \[CenterDot] V + Sqrt[A^2*(P^2 - V^2) + 
            (A \[CenterDot] V)^2])/(P^2 - V^2)} 

就像我说的,这是没有任何解决这类问题的完整方法的意思,但如果你仔细地将问题转换为易于使用的术语,从模式匹配和规则替换的角度来看,你可以走得很远。

+1

这两个点积规则可以合并为一个,方法是用'c_.'或'c:1'替换第一条规则中的'c_',其中句点告诉Mathematica使用标准的乘法默认值。 – rcollyer 2010-01-22 19:09:10

8

随着数学7.0.1.0

Clear[A, V, P]; 
A = {1, 2, 3}; 
V = {4, 5, 6}; 
P = {P1, P2, P3}; 
Solve[A + V t == P, P] 

输出:

{{P1 -> 1 + 4 t, P2 -> 2 + 5 t, P3 -> 3 (1 + 2 t)}} 

打字出P = {P1,P2,P3}可以是恼人如果阵列或矩阵是大的。

Clear[A, V, PP, P]; 
A = {1, 2, 3}; 
V = {4, 5, 6}; 
PP = Array[P, 3]; 
Solve[A + V t == PP, PP] 

输出:

{{P[1] -> 1 + 4 t, P[2] -> 2 + 5 t, P[3] -> 3 (1 + 2 t)}} 

矩阵矢量内积:

Clear[A, xx, bb]; 
A = {{1, 5}, {6, 7}}; 
xx = Array[x, 2]; 
bb = Array[b, 2]; 
Solve[A.xx == bb, xx] 

输出:

{{x[1] -> 1/23 (-7 b[1] + 5 b[2]), x[2] -> 1/23 (6 b[1] - b[2])}} 

矩阵乘法:

Clear[A, BB, d]; 
A = {{1, 5}, {6, 7}}; 
BB = Array[B, {2, 2}]; 
d = {{6, 7}, {8, 9}}; 
Solve[A.BB == d] 

输出:

{{B[1, 1] -> -(2/23), B[2, 1] -> 28/23, B[1, 2] -> -(4/23), B[2, 2] -> 33/23}} 

点积内置了只使用一个周期点的中缀表示法。

但我不认为交叉产品确实如此。这是你如何使用Notation包制作一个包。 “X”将成为我们Cross的中缀形式。我建议应用Notation,Symbolize和InfixNotation教程中的示例。还可以使用Notation Palette来帮助抽象出一些Box语法。

Clear[X] 
Needs["Notation`"] 
Notation[x_ X y_\[DoubleLongLeftRightArrow]Cross[x_, y_]] 
Notation[NotationTemplateTag[ 
    RowBox[{x_, , X, , y_, }]] \[DoubleLongLeftRightArrow] 
    NotationTemplateTag[RowBox[{ , 
RowBox[{Cross, [, 
RowBox[{x_, ,, y_}], ]}]}]]] 
{a, b, c} X {x, y, z} 

输出:

{-c y + b z, c x - a z, -b x + a y} 

上面看起来可怕,但使用的符号调色板时的模样:

Clear[X] 
Needs["Notation`"] 
Notation[x_ X y_\[DoubleLongLeftRightArrow]Cross[x_, y_]] 
{a, b, c} X {x, y, z} 

我遇到了使用符号包在过去的一些怪癖注意mathematica的版本。

+0

在解决[A + V t == P,P]'你错过了't'乘以'P'。 – rcollyer 2010-01-22 19:10:41

+2

用':esc:cross:esc:'键入cross产品。 – kennytm 2010-01-22 20:33:58

+0

@rcollyer 我的错误,应该与加法工作正常。 @KennyTM 感谢您指出。 – Davorak 2010-01-25 06:27:03

1

我对这个问题采取了一些不同的方法。我做了一些定义,返回此输出:被称为是向量的数量可以用vec[_]指定 vExpand examples 模式,有一个OverVector[]OverHat[]包装(超过它们的载体或帽子符号)模式被认为是载体默认情况下。

这些定义是实验性的,应该这样对待,但它们似乎工作得很好。我期望随着时间的推移而增加这一点。

下面是定义。需要粘贴到Mathematica Notebook单元格中并转换为StandardForm以正确查看它们。

Unprotect[vExpand,vExpand$,Cross,Plus,Times,CenterDot]; 

(* vec[pat] determines if pat is a vector quantity. 
vec[pat] can be used to define patterns that should be treated as vectors. 
Default: Patterns are assumed to be scalar unless otherwise defined *) 
vec[_]:=False; 

(* Symbols with a vector hat, or vector operations on vectors are assumed to be vectors *) 
vec[OverVector[_]]:=True; 
vec[OverHat[_]]:=True; 

vec[u_?vec+v_?vec]:=True; 
vec[u_?vec-v_?vec]:=True; 
vec[u_?vec\[Cross]v_?vec]:=True; 
vec[u_?VectorQ]:=True; 

(* Placeholder for matrix types *) 
mat[a_]:=False; 

(* Anything not defined as a vector or matrix is a scalar *) 
scal[x_]:=!(vec[x]\[Or]mat[x]); 
scal[x_?scal+y_?scal]:=True;scal[x_?scal y_?scal]:=True; 

(* Scalars times vectors are vectors *) 
vec[a_?scal u_?vec]:=True; 
mat[a_?scal m_?mat]:=True; 

vExpand$[u_?vec\[Cross](v_?vec+w_?vec)]:=vExpand$[u\[Cross]v]+vExpand$[u\[Cross]w]; 
vExpand$[(u_?vec+v_?vec)\[Cross]w_?vec]:=vExpand$[u\[Cross]w]+vExpand$[v\[Cross]w]; 
vExpand$[u_?vec\[CenterDot](v_?vec+w_?vec)]:=vExpand$[u\[CenterDot]v]+vExpand$[u\[CenterDot]w]; 
vExpand$[(u_?vec+v_?vec)\[CenterDot]w_?vec]:=vExpand$[u\[CenterDot]w]+vExpand$[v\[CenterDot]w]; 

vExpand$[s_?scal (u_?vec\[Cross]v_?vec)]:=Expand[s] vExpand$[u\[Cross]v]; 
vExpand$[s_?scal (u_?vec\[CenterDot]v_?vec)]:=Expand[s] vExpand$[u\[CenterDot]v]; 

vExpand$[Plus[x__]]:=vExpand$/@Plus[x]; 
vExpand$[s_?scal,Plus[x__]]:=Expand[s](vExpand$/@Plus[x]); 
vExpand$[Times[x__]]:=vExpand$/@Times[x]; 

vExpand[e_]:=e//.e:>Expand[vExpand$[e]] 

(* Some simplification rules *) 
(u_?vec\[Cross]u_?vec):=\!\(\*OverscriptBox["0", "\[RightVector]"]\); 
(u_?vec+\!\(\*OverscriptBox["0", "\[RightVector]"]\)):=u; 
0v_?vec:=\!\(\*OverscriptBox["0", "\[RightVector]"]\); 

\!\(\*OverscriptBox["0", "\[RightVector]"]\)\[CenterDot]v_?vec:=0; 
v_?vec\[CenterDot]\!\(\*OverscriptBox["0", "\[RightVector]"]\):=0; 

(a_?scal u_?vec)\[Cross]v_?vec :=a u\[Cross]v;u_?vec\[Cross](a_?scal v_?vec):=a u\[Cross]v; 
(a_?scal u_?vec)\[CenterDot]v_?vec :=a u\[CenterDot]v; 
u_?vec\[CenterDot](a_?scal v_?vec) :=a u\[CenterDot]v; 

(* Stealing behavior from Dot *) 
Attributes[CenterDot]=Attributes[Dot]; 

Protect[vExpand,vExpand$,Cross,Plus,Times,CenterDot];