Я пытаюсь выяснить, как использовать 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 }
]
но "решением", которое выкладывает, является огромная путаница коэффициентов и перегрузки. Это также вынуждает меня развернуть каждый из размеров, я подаю его.
То, что я хочу, является хорошим символьным решением с точки зрения скалярных произведений, векторных произведений и норм:
Но я не вижу, как сказать Solve
то, что некоторые коэффициенты являются векторами вместо скаляров.
Действительно ли это возможно? Mathematica может дать мне символьные решения на векторах? Или я должен просто придерживаться № 2 технологии Карандашей?
(Только, чтобы быть ясным, я не интересуюсь решением конкретного уравнения в вершине - я спрашиваю, могу ли я использовать Mathematica для решения вычислительных проблем геометрии как этот обычно без того, что я имел необходимость выразить все как явную матрицу {Ax, Ay, Az}
, и т.д.)
Все мой код использует NSnotifications
, как так:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateView) name:@"ScanCompleted" object:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"ScanCompleted" object:nil];
Первый зарегистрирован уведомление и вторая публикация уведомления.
-121--2434820-с помощью 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}}
Точечный продукт имеет инфиксированную запись, встроенный, просто используйте период для точки.
Я не думаю, что перекрестный продукт, однако. Вот как вы используете пакет нотации, чтобы сделать один. «Х» станет нашей инфиксной формой креста. Я предлагаю справиться с примером от обозначения, символизирующего и инфикснотационного учебного пособия. Также используйте палитру нотации, которая помогает абстрагированию некоторых из синтаксиса коробки.
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, поэтому будьте осторожны.
У меня нет общего решения для вас (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};
Эти правила упростят отношения для векторных норм и точечных продуктов (перекрестные продукты оставляются как вероятное болезненное упражнение для читателя). EDIT: 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)}
Как я уже говорил, это не полный способ решения такого рода проблем любыми средствами, но если вы будете осторожны с тем, чтобы изложить проблему в понятиях, с которыми легко работать с точки зрения сопоставления паттернов и замены правил, вы можете зайти довольно далеко.