i - nspire动态创建向量叉积变量



好的,我正在尝试在TI-NSpire中创建一个叉积函数它取n-1个n维向量并取一个矩阵的行列式,像这样

[[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

在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不能处理任意数量的参数。

相反,您需要编写一个augment_from_list(vectors),它接受一个参数(一个向量列表)并对它们进行增广。

这只是为了增强——您将需要类似的帮助程序来扩展内置函数以处理任意数量的参数。

这里。我觉得我想出的解决方案是一个恰当的回应,而不是一个简单的更新。

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
:  listoperationsreverselist(v_coeff)→v_coeff
:  For i,1,n_coeff
:    v_coeff[i]→vec[i]
:  EndFor
:  listoperationsreverselist(vec)→vec
:  Return vec
:Else
:  Return v_coeff
:EndIf
:Return new_v
:Return expand(det_v)
:EndFunc

这个函数实际上工作得很好。函数reverselist()简单地反转列表。代码很简单。

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,等等。因此,一旦它做了行列式,"单位"变量的系数就是向量的组成部分。此外,在测试过程中我发现,如果行列式的结果是零乘以多项式的主次幂(比如单位^3),那么向量将是短分量(但如果0乘以任何低幂项,但不是主次幂,则没有问题)。如果行列式的结果是0,那么结果就是一个空列表。带有嵌套for循环的if-loop通过确保每个组件都在适当长度的列表中(从而防止混淆并导致执行器不得不做额外的工作以返回适当的列表长度)以及这些组件位于正确的位置来解决这个问题。

我确信代码可以改进并更快,但我对结果很满意。谢谢大家的帮助。

最新更新