11

Mathematica を使用して、変数と係数の一部がベクトルである連立方程式を解く方法を理解しようとしています。簡単な例は次のようになります

A + Vt = Pt

ここで、 AV 、およびPの大きさを知っているので、 tと P の方向を解かなければなりません(基本的に、2 つの光線 A と B が与えられた場合、A についてはすべて知っていますが、B の原点と大きさだけを知っています)。 、A と交差するために B の方向がどうあるべきかを考えてください。)

今では、この種のことを手作業で解決する方法を知っていますが、それは時間がかかり、エラーが発生しやすいので、Mathematica を使用して作業を高速化し、エラーをチェックできることを望んでいました. しかし、Mathematica でこのようなベクトルを含む方程式をシンボリックに解く方法がわかりません。

関連すると思われるものは何も見つかりませんでしたが、VectorAnalysis パッケージを調べました。一方、線形代数パッケージには、線形システム用のソルバーしかないようです (これは、 tまたはPがわからないため、 |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 } 
     ]

しかし、吐き出される「解決策」は、係数と輻輳の巨大な混乱です。また、フィードする各ディメンションを拡張する必要があります。

私が欲しいのは、内積、外積、およびノルムに関する優れた記号ソリューションです。

代替テキスト

Solveしかし、一部の係数がスカラーではなくベクトルであることを確認する方法がわかりません。

これは可能ですか?Mathematica はベクトルの記号解を与えることができますか? それとも、No.2 Pencil テクノロジーをそのまま使用する必要がありますか?

(はっきりさせておきますが、私は上の特定の方程式の解法には興味がありません.Mathematica を使って、すべてを明示的な行列として表現することなく、一般的にそのような計算幾何学の問題を解くことができるかどうか尋ねています.{Ax, Ay, Az}など)

4

3 に答える 3

9

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]

出力:

{{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 のチュートリアルの例を参考にすることをお勧めします。また、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 で記法パッケージを使用すると、いくつかの癖に遭遇したので注意してください。

于 2010-01-21T23:04:35.823 に答える
5

一般的な解決策はありませんが (MathForum の方が適している可能性があります)、いくつかのヒントを提供できます。1 つ目は、より体系的な方法でベクトルをコンポーネントに展開することです。たとえば、あなたが書いた方程式を次のように解きます。

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ので、ノルムとドット積には 2 つのルールしか必要ありません。

これらのルールを使用して、ソリューションをすぐに単純化して、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)}

私が言ったように、これはこの種の問題を解決するための完全な方法ではありませんが、パターン マッチングとルール置換の観点から扱いやすい用語に問題をキャストすることに注意すれば、次のことができます。かなり遠くまで行きます。

于 2010-01-21T16:12:23.517 に答える
2

私はこの問題に対して多少異なるアプローチを取りました。この出力を返すいくつかの定義を作成しました。 vExpandの例 ベクトル量であることがわかっているパターンは、を使用して指定できます。またはラッパー(ベクトルまたはハットが付いたシンボル)をvec[_]持つパターンは、デフォルトでベクトルと見なされます。OverVector[]OverHat[]

定義は実験的なものであり、そのように扱う必要がありますが、うまく機能しているようです。私はこれに時間をかけて追加することを期待しています。

これが定義です。それらを正しく表示するには、Mathematicaノートブックセルに貼り付けて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];
于 2011-09-07T10:12:45.463 に答える