2010-01-21 10 views
9

J'essaie de comprendre comment utiliser Mathematica pour résoudre des systèmes d'équations où certaines des variables et des coefficients sont des vecteurs. Un exemple simple serait quelque chose commeRésolution d'équations vectorielles dans Mathematica

A + Vt = Pt

où je sais A, V, et l'ampleur de P, et je dois résoudre pour t et la direction de P. (Fondamentalement, étant donné deux rayons A et B, où je sais tout sur A mais seulement l'origine et la magnitude de B, déterminer quelle doit être la direction de B telle qu'elle croise A.)

Maintenant, je sais comment résoudre ce genre de chose à la main, mais c'est lent et sujet aux erreurs, alors j'espérais pouvoir utiliser Mathematica pour accélérer les choses et vérifier les erreurs. Cependant, je ne vois pas comment Mathematica pourrait résoudre symboliquement des équations impliquant des vecteurs comme celui-ci.

J'ai regardé dans le paquet VectorAnalysis, sans y trouver quoi que ce soit qui semble pertinent; pendant ce temps le paquet algèbre linéaire semble seulement avoir un solveur pour les systèmes linéaires (ce qui n'est pas, puisque je ne sais pas t ou P, juste | P |).

J'ai essayé de faire la chose simplette: l'expansion des vecteurs dans leurs composants (faire semblant qu'ils sont en 3D) et de les résoudre comme si j'essaie d'assimiler deux fonctions paramétriques,

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 } 
    ] 

mais la « solution » cela crache est un énorme gâchis de coefficients et de congestion. Cela me force aussi à étendre chacune des dimensions que je nourris.

Ce que je veux est une solution symbolique bien en termes de produits de points, des produits croisés, et les normes:

alt text

Mais je ne vois pas comment dire Solve que certains des coefficients sont des vecteurs au lieu de scalaires.

Est-ce possible? Est-ce que Mathematica peut me donner des solutions symboliques sur les vecteurs? Ou devrais-je m'en tenir à la technologie No.2 Pencil? (Juste pour être clair, je ne suis pas intéressé par la solution à l'équation en haut - je demande si je peux utiliser Mathematica pour résoudre des problèmes de géométrie de calcul comme ça en général sans avoir à tout exprimer comme

+0

Il vaudrait peut-être mieux que vous posiez cette question aux autres membres de Mathematica. Ils connaissent probablement mieux leur propre logiciel que nous. –

+1

Je vais essayer de poster sur les forums MathGroup (http://forums.wolfram.com/). Il ne semble pas que le simple envoi de [email protected] fournisse des résultats utiles. – Crashworks

+1

Il est toutefois surprenant de constater à quel point le rapport signal sur bruit (et tout le système en général) est meilleur ici que dans une liste de diffusion/forum/groupe de discussion «démodé». –

Répondre

5

Je n'ai pas de solution générale pour vous (MathForum est peut-être la meilleure solution), mais il y a quelques conseils que je peux vous offrir. Le premier est de faire l'expansion de vos vecteurs dans des composants de manière plus systématique. Par exemple, je résoudrais l'équation que vous avez écrite comme suit.

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

Ensuite, vous pouvez travailler avec la variable rawSol plus facilement. Ensuite, étant donné que vous référencez les composants vectoriels de manière uniforme (en respectant toujours le modèle Mathematica v_[x|y|z]), vous pouvez définir des règles qui vous aideront à les simplifier.J'ai joué un peu avant de venir avec les règles suivantes:

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}; 

Ces règles simplifieront les relations pour les normes de vecteur et de produits de points (produits croisés sont laissés comme un exercice douloureux probable pour le lecteur). EDIT: rcollyer a souligné que vous pouvez rendre c optionnel dans la règle pour les produits scalaires, vous n'avez donc besoin que de deux règles pour les produits normalisés et les produits scalaires.

Avec ces règles, j'ai été immédiatement en mesure de simplifier la solution pour t en une forme très proche de la vôtre:

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)} 

Comme je l'ai dit, ce n'est pas une façon complète de résoudre ce genre de problèmes par tout signifie, mais si vous êtes prudent sur la façon de traiter le problème en termes faciles à utiliser à partir d'un point de vue d'appariement et de remplacement de règles, vous pouvez aller assez loin.

+1

Les deux règles de produit scalaire peuvent être fusionnées en une en remplaçant le 'c_' dans la première règle par' c_.' ou 'c: 1', où la période indique à Mathematica d'utiliser la valeur par défaut standard pour la multiplication. – rcollyer

8

Avec 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] 

sorties:

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

taper P = {P1, P2, P3} peut être gênant si le tableau ou la matrice est grande.

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

sorties:

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

vecteur de matrice de produit scalaire:

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

sorties:

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

multiplication matricielle:

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

sorties:

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

Le produit scalaire a une notation infixe construit il suffit d'utiliser une période pour le point.

Je ne pense pas que le produit croisé fait cependant. C'est ainsi que vous utilisez le package Notation pour en créer un. "X" deviendra notre forme infixe de Cross. Je suggère de suivre l'exemple du didacticiel Notation, Symbolize et InfixNotation. Utilisez également la Palette de notation qui permet d'éliminer une partie de la syntaxe 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} 

sorties:

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

Les looks ci-dessus horrible, mais en utilisant la palette de notation, il ressemble à:

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

J'ai couru dans quelques bizarreries en utilisant le package de notation dans le passé versions de mathematica alors soyez prudent.

+0

Dans 'Résoudre [A + V t == P, P]' vous avez manqué le 't' multipliant' P'. – rcollyer

+2

Vous tapez un produit croisé avec ': esc: cross: esc:'. – kennytm

+0

@rcollyer Mon erreur, devrait fonctionner correctement avec l'addition. @KennyTM Merci d'avoir signalé cela. – Davorak

1

J'ai adopté une approche quelque peu différente de ce problème. Je l'ai fait quelques définitions qui renvoient cette sortie: vExpand examples modèles qui sont connus pour être des quantités de vecteur peut être spécifié à l'aide vec[_], les modèles qui ont une enveloppe (symboles avec un vecteur ou un chapeau sur eux) OverVector[] ou OverHat[] sont supposés être vecteurs par défaut.

Les définitions sont expérimentales et doivent être traitées en tant que telles, mais elles semblent bien fonctionner. Je m'attends à ajouter à cela au fil du temps.

Voici les définitions. Le besoin d'être collé dans une cellule Mathematica Notebook et converti en StandardForm pour les voir correctement.

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];