Search code examples
ti-basicti-nspire

TI-NSpire dynamically create variables for vector cross product


Ok, I am trying to create a cross product function in the TI-NSpire that took n-1 vectors of dimension n and take the determinant of a matrix like this:

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

The top row is the unit vectors pointed in the direction of the axes. Unfortunately, the issue is that unless I give the calculator undefined variables, finding the determinant of this matrix results in an error, since either u_x, u_y... etc are vectors, and the matrix is not a proper matrix, or the vectors are values, and the determinant results in a single value, rather than a vector. What I can do, however is leave the unit vectors undefined and perform the determinant, then define the variables after the determinant is done.

What I am left with is either limiting myself to a maximum vector size (not unreasonable, but I'd prefer to not use this) or dynamically create a list of n undefined local variables that I can set to unit vectors after the computation is complete.

My question is, how would one perform the second option, if at all possible?

edit for the code: (Note: this is currently using the list of variables that I mentioned. Unfortunately, the issue with this is "5→{a,b,c,d}[1,2]" errors.)

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

Solution

  • OP here. I felt the solution I came up with is a fitting for a proper response rather than a simple update.

    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
    

    This function works quite well, actually. The function reverselist() simply reverses the list. The code is simple.

    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
    

    I also seem to have stumbled across some vectors where the only vector perpendicular to all three (<1,2,3,4>, <5,6,7,8>, <9,10,11,12>) is <0,0,0,0>. However, If someone could confirm that, I would greatly appreciate it.

    This whole function works because of the way the calculator treats polynomials. So my 'unit' vectors in the function are 1, unit, unit^2, unit^3, etc. Thus once it does the determinant the coefficients of the 'unit' variable are the components of the vector. In addition, in the process of testing I found that if the determinant results in a zero multiplied by the leading power of the poly nomial (say unit^3) then the vector would be short a component (but if the 0 was multiplied by any of the lower powered terms, but not the leading power, there was no issue). In the event that the determinant resulted in 0, the result was simply an empty list. The if-loop with a nested for-loop takes care of this by ensuring that each of components is in a list of the proper length (thus preventing confusion and causing the executor to have to do extra work to get back to the proper list length) and that those components are in the right place.

    I am sure the code could be improved and made faster, but I am happy with the result. Thanks for everyone's help.