Cra*_*rks 9 wolfram-mathematica linear-algebra
我试图弄清楚如何使用Mathematica来求解方程组,其中一些变量和系数是向量.一个简单的例子就是这样的

我知道A,V和P的大小,我必须求解t和P 的方向.(基本上,给出两条光线A和B,我知道关于A的所有内容,但只知道B的起源和大小) ,弄清楚B的方向必须是什么,使它与A相交.)
现在,我知道如何手动解决这类问题,但这很慢且容易出错,因此我希望我可以使用Mathematica来加快速度并对错误进行检查.但是,我看不出如何让Mathematica象征性地解决涉及这样的向量的方程.
我查看了VectorAnalysis软件包,但没有发现任何看似相关的东西; 同时线性代数包似乎只有线性系统的求解器(这不是,因为我不知道t或P,只是| P |).
我尝试做一些简单的事情:将矢量扩展到它们的组件中(假装它们是3D)并解决它们,好像我试图将两个参数函数等同起来,
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 }
]
Run Code Online (Sandbox Code Playgroud)
但是吐出的"解决方案"是系数和拥塞的混乱.它还迫使我扩展我喂它的每个维度.
我想要的是点产品,交叉产品和规范方面的一个很好的符号解决方案:

但我看不出如何判断Solve一些系数是向量而不是标量.
这可能吗?Mathematica可以给我矢量符号解决方案吗?或者我应该坚持使用No.2 Pencil技术?
(为了清楚起见,我对顶部特定方程的解决方案不感兴趣 - 我问我是否可以使用Mathematica来解决计算几何问题,因为通常不需要将所有内容表达为显式矩阵{Ax, Ay, Az}等)
使用Mathematica 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]
Run Code Online (Sandbox Code Playgroud)
输出:
{{P1 -> 1 + 4 t, P2 -> 2 + 5 t, P3 -> 3 (1 + 2 t)}}
Run Code Online (Sandbox Code Playgroud)
如果阵列或矩阵很大,则输入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]
Run Code Online (Sandbox Code Playgroud)
输出:
{{P[1] -> 1 + 4 t, P[2] -> 2 + 5 t, P[3] -> 3 (1 + 2 t)}}
Run Code Online (Sandbox Code Playgroud)
矩阵向量内积:
Clear[A, xx, bb];
A = {{1, 5}, {6, 7}};
xx = Array[x, 2];
bb = Array[b, 2];
Solve[A.xx == bb, xx]
Run Code Online (Sandbox Code Playgroud)
输出:
{{x[1] -> 1/23 (-7 b[1] + 5 b[2]), x[2] -> 1/23 (6 b[1] - b[2])}}
Run Code Online (Sandbox Code Playgroud)
矩阵乘法:
Clear[A, BB, d];
A = {{1, 5}, {6, 7}};
BB = Array[B, {2, 2}];
d = {{6, 7}, {8, 9}};
Solve[A.BB == d]
Run Code Online (Sandbox Code Playgroud)
输出:
{{B[1, 1] -> -(2/23), B[2, 1] -> 28/23, B[1, 2] -> -(4/23), B[2, 2] -> 33/23}}
Run Code Online (Sandbox Code Playgroud)
点积有内置的中缀表示法,只需使用点的句点.
但我不认为交叉产品会这样做.这是你使用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}
Run Code Online (Sandbox Code Playgroud)
输出:
{-c y + b z, c x - a z, -b x + a y}
Run Code Online (Sandbox Code Playgroud)
上面看起来很糟糕但是当使用Notation Palette时它看起来像:
Clear[X]
Needs["Notation`"]
Notation[x_ X y_\[DoubleLongLeftRightArrow]Cross[x_, y_]]
{a, b, c} X {x, y, z}
Run Code Online (Sandbox Code Playgroud)
我在mathematica的过去版本中使用符号包遇到了一些怪癖,所以要小心.
我无论如何也没有一般的解决方案(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}]]];
Run Code Online (Sandbox Code Playgroud)
然后,您可以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};
Run Code Online (Sandbox Code Playgroud)
这些规则将简化向量规范和点积的关系(交叉产品留给读者可能是痛苦的练习).编辑: rcollyer指出你可以c在点数产品的规则中做出选择,所以你只需要两个规范和点积的规则.
有了这些规则,我立即能够将解决方案简化为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)}
Run Code Online (Sandbox Code Playgroud)
就像我说的那样,它不是以任何方式解决这类问题的完整方式,但是如果你小心地将问题转化为易于使用的模式匹配和规则替换的立场,你可以走得很远.