2

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
Gerald
  • 166
  • 1
  • 13
  • Can you show a complete example? The standard cross product is defined only for vectors of dimension 3 -- is there an alternative name for the concept you are trying to implement? – soegaard Sep 03 '15 at 22:14
  • If you have four unit vectors of the form: i={1,0,0,0} j={0,1,0,0} k={0,0,1,0} l={0,0,0,1} And three vectors of the form: a={a1,a2,a3,a4} b=... c=... Then the vector that is perpendicular to all three is found by taking the detminant of this matrix: [[i, j, k, l], [a1,a2,a3,a4], [b1,b2,b3,b4], [c1,c2,c3,c4]] – Gerald Sep 03 '15 at 22:50
  • Ill add all my code to the OP – Gerald Sep 03 '15 at 22:55

2 Answers2

2

In NSpire the elements of a matrix must be scalars.

This implies two things:

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

 2)  the output of det is a scalar

The last is the most troublesome for you. It basically means you need to write your own version of det if you want to use your approach.

Now the second part of the question is how to implement this for arbitrary dimensions. The sad part is that the "programming language" in NSpire is very limited. The first complication is that augment doesn't handle an arbitrary number of arguments.

Instead you will need to write a augment_from_list(vectors) which takes one argument (a list of vectors) and augments them.

And that is just for augment -- you will need similar helpers in order extend the builtin functions to handle an arbitrary number of arguments.

soegaard
  • 30,661
  • 4
  • 57
  • 106
  • Damn, good to know. Do you know of any way to store a function I create and be able to access it from any document on the nspire? – Gerald Sep 04 '15 at 10:52
  • Take a look at `Define LibPub` in the reference manual. Is that what you are after? – soegaard Sep 04 '15 at 10:56
  • So I was able to get libpub to work, however I am running into the issue that {1,2,{3,4}} returns an invalid list, and that the alternative solution I listed in the OP that I did implement doesn't work as there is no value set for the variables in unitlist. – Gerald Sep 04 '15 at 13:54
  • Yeah - `{1,2,{3,4}}` is sadly not allowed. The NSpire "programming language" is rather limited. – soegaard Sep 04 '15 at 13:58
  • Blargh. Is there a replacement OS that I load onto the TI nspire that has all or most of the functionality of the ti nspire, but none of the bullshit? – Gerald Sep 04 '15 at 18:33
  • 1
    Hey, I appreciate your input. I posted the solution I finally got. – Gerald Sep 30 '15 at 01:11
1

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.

Gerald
  • 166
  • 1
  • 13
  • Oh, and v_list is a vector matrix that has to be of the dimensions n by n+1. Thus for vectors in 3d I need a 2x3 matrix like so [[v1,v2,v3],[u1,u2,u3]] This does work with variables, and any number of vectors, but is slow with very complex vectors. – Gerald Sep 30 '15 at 01:12