2015-09-03 5 views
2

Хорошо, я пытаюсь создать функцию кросс-произведения в TI-NSpire, которая приняла n-1 векторов размерности n и взяла определитель матрицы следующим образом:TI-NSpire динамически создает переменные для векторного кросс-продукта

[[u_x,u_y,u_z,u_w], 
[a_1,a_2,a_3,a_4], 
[b_1,b_2,b_3,b_4], 
[c_1,c_2,c_3,c_4]] 

Верхний ряд - это единичные векторы, направленные в направлении осей. К сожалению, проблема заключается в том, что, если я не дам неопределенным переменным калькулятора, поиск детерминанта этой матрицы приведет к ошибке, так как либо u_x, u_y ... и т. Д. Являются векторами, а матрица не является надлежащей матрицей, или векторы значения, а определитель приводит к одному значению, а не вектору. Однако я могу оставить неопределенные единичные векторы и выполнить определитель, а затем определить переменные после выполнения детерминанта.

То, что у меня осталось, ограничивает себя максимальным размером вектора (не необоснованным, но я бы предпочел не использовать это) или динамически создавать список n неопределенных локальных переменных, которые я могу установить на единичные векторы после вычисление завершено.

Мой вопрос: как выполнить второй вариант, если это вообще возможно?

Редактировать для кода: (Примечание: в настоящее время используется список переменных, о котором я упоминал. К сожалению, проблема с этим связана с ошибками «5 → {a, b, c, d} [1,2]» .)

Define LibPub cross_p(mat)= 
Func 
:Local i_,n_,unit_v,unit_list 
:Local dim_v,num_v,len_v,new_v 
:Local det_v 
:[a,b,c,d,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]→unit_list 
:dim(mat)→dim_v 
:dim_v[1]→num_v 
:dim_v[2]→len_v 
:newMat(len_v,len_v)→unit_v 
:For n_,1,len_v 
: 1→unit_v[n_,n_] 
:EndFor 
:If num_v=len_v-1 Then 
: newMat(len_v,len_v)→new_v 
: subMat(unit_list,1,1,1,len_v)→new_v[1] 
: For i_,1,num_v 
: mat[i_]→new_v[i_+1] 
: EndFor 
: det(new_v)→det_v 
: For i_,1,len_v 
: unit_v[i_]→unit_list[1,i_] 
: EndFor 
: Return det_v 
:EndIf 
:EndFunc 
+0

Можете ли вы показать полный пример? Стандартный кросс-продукт определяется только для векторов размерности 3 - существует ли альтернативное название для концепции, которую вы пытаетесь реализовать? – soegaard

+0

Если у вас есть четыре единичных вектора формы: i = {1,0,0,0} j = {0,1,0,0} k = {0,0,1,0} l = {0,0,0,1} И три вектора вида: а = {a1, a2, a3, a4} Ь = ... с = ... Тогда вектор, перпендикулярный все три найден, беря detminant этой матрицы: [[I, J, K, L], [а1, а2, а3, а4], [b1, b2, b3, b4], [c1 , c2, c3, c4]] – CopaceticMan

+0

Поместить все мой код в OP – CopaceticMan

ответ

1

ОП здесь. Я чувствовал, что решение, которое я придумал, подходит для правильного ответа, а не простого обновления.

Define LibPub v_crossp(v_list)= 
Func 
:Local i,num_v,new_v,det_v,vec,v_coeff,n_coeff 
:dim(v_list)[2]→num_v 
:newMat(num_v,num_v)→new_v 
:newList(num_v)→vec 
:For i,1,num_v 
:unit^(i-1)→new_v[1,num_v+1-i] 
:EndFor 
:For i,1,num_v-1 
: v_list[i]→new_v[i+1] 
:EndFor 
:det(new_v)→det_v 
:polyCoeffs(det_v,unit)→v_coeff 
:dim(v_coeff)→n_coeff 
:If n_coeff<num_v Then 
: listoperations\reverselist(v_coeff)→v_coeff 
: For i,1,n_coeff 
: v_coeff[i]→vec[i] 
: EndFor 
: listoperations\reverselist(vec)→vec 
: Return vec 
:Else 
: Return v_coeff 
:EndIf 
:Return new_v 
:Return expand(det_v) 
:EndFunc 

Эта функция работает довольно хорошо, на самом деле. Функция reverseelist() просто меняет список. Код прост.

Define LibPub reverselist(list)= 
Func 
:Local i,size,l_new 
:size:=dim(list) 
:l_new:=newList(size) 
:For i,1,size 
: list[i]→l_new[size+1-i] 
:EndFor 
:Return l_new 
:EndFunc 

Я также, кажется, наткнулся на несколько векторов, где единственный вектор, перпендикулярный все три (< 1,2,3,4>, < 5,6,7,8>, < 9,10, 11,12>) составляет < 0,0,0,0>. Однако, если кто-то может это подтвердить, я был бы очень признателен.

Вся эта функция работает из-за того, как калькулятор обрабатывает полиномы. Итак, мои «единичные» векторы в функции: 1, единица, единица^2, единица^3 и т. Д.Таким образом, когда он определяет определитель, коэффициенты «единичной» переменной являются компонентами вектора. Кроме того, в процессе тестирования я обнаружил, что если детерминант приводит к нулю, умноженному на ведущую силу полиномиального (например, unit^3), тогда вектор будет коротким компонентом (но если бы значение 0 умножилось на любое из ниже приведенных в действие условий, но не в качестве ведущей, проблем не было). В случае, когда определитель привел к 0, результатом был просто пустой список. Петля if с вложенным циклом for заботится об этом, гарантируя, что каждый из компонентов находится в списке надлежащей длины (таким образом предотвращая путаницу и заставляя исполнителя выполнять дополнительную работу, чтобы вернуться к правильной длине списка) и что эти компоненты находятся в правильном месте.

Я уверен, что код можно улучшить и сделать быстрее, но я доволен результатом. Спасибо за помощь каждого.

+0

О, а v_list - векторная матрица, которая должна иметь размеры n на n + 1. Таким образом, для векторов в 3d мне нужна матрица 2x3, такая как [[v1, v2, v3], [u1, u2, u3]] Это работает с переменными и любым числом векторов, но медленным с очень сложными векторами , – CopaceticMan

2

В NSpire элементы матрицы должны быть скалярами.

Это означает две вещи:

1) `[i, j, k, l]` must be written `augment(i,augment(j,augment(k,l)))` 

2) the output of det is a scalar 

Последнее является наиболее трудным для вас. Это в основном означает, что вам нужно написать свою собственную версию det, если вы хотите использовать свой подход.

Теперь вторая часть вопроса заключается в том, как реализовать это для произвольных измерений. Печальная часть состоит в том, что «язык программирования» в NSpire очень ограничен. Первое осложнение заключается в том, что дополнение не обрабатывает произвольное количество аргументов.

Вместо этого вам нужно будет написать augment_from_list(vectors), который принимает один аргумент (список векторов) и дополняет их.

И это только для увеличения - вам понадобятся похожие помощники, чтобы расширить встроенные функции для обработки произвольного количества аргументов.

+0

Черт, это хорошо знать. Знаете ли вы, как сохранить функцию, которую я создаю, и иметь доступ к ней из любого документа на nspire? – CopaceticMan

+0

Взгляните на 'Define LibPub' в справочном руководстве. Это то, что вам нужно? – soegaard

+0

Итак, я смог заставить libpub работать, однако я столкнулся с проблемой, что {1,2, {3,4}} возвращает недопустимый список и что альтернативное решение, указанное в OP, которое я действительно выполнял, Не работайте, так как нет значения, установленного для переменных в списке элементов. – CopaceticMan