RE: RE: Generating Two Unit Orthogonal Vectors
- To: mathgroup at smc.vnet.net
- Subject: [mg36460] RE: [mg36429] RE: Generating Two Unit Orthogonal Vectors
- From: "DrBob" <drbob at bigfoot.com>
- Date: Sat, 7 Sep 2002 02:54:52 -0400 (EDT)
- Reply-to: <drbob at bigfoot.com>
- Sender: owner-wri-mathgroup at wolfram.com
I checked again the six solutions I had previously timed, and they DO give orthogonal results. (None of them depend on NullSpace for that.) By the way, I reused my "combinations" function (from a recent problem on adding fractions to get 1) to check for orthogonality: ClearAll[orthogonalQ] orthogonalQ[v : {__?VectorQ}] := And @@ (Chop@( Dot @@ #) == 0 & /@ combinations[v, {2}]) << DiscreteMath`Combinatorica`; ClearAll[combinations]; r = Range[1, 9]; combinations::usage = "combinations[list,n:{__Integer}] lists the combinations of list taken n at a time"; combinations[r_List, n_Integer, {}] := If[n > Length@r, {}, DiscreteMath`Combinatorica`KSubsets[r, n]]; combinations[r_List, n_Integer, e_?VectorQ] := Join[e, #] & /@ \ DiscreteMath`Combinatorica`KSubsets[Complement[r, e], n]; combinations[r_List, n_Integer, e : {__?VectorQ}] := Flatten[ combinations[r, n, #] & /@ e, 1]; combinations[r_List, n : {__Integer}] := Which[Plus @@ n == Length@r, \ Join[#, Complement[r, #]] & /@ combinations[r, Drop[n, -1]], Plus @@ n > Length@r, {}, True, Fold[ combinations[r, #2, #1] &, {}, n]] Bobby -----Original Message----- From: David Park [mailto:djmp at earthlink.net] To: mathgroup at smc.vnet.net Subject: [mg36460] [mg36429] RE: Generating Two Unit Orthogonal Vectors Daniel Lichtblau has pointed out that NullSpace does not generally give orthogonal vectors. Therefore the routines that depended upon that were in error. He says that it does give orthogonal vectors when the input vector contains approximate numbers. For graphical purposes this will be good enough for me. Therefore I modify Ted's routine to OrthogonalUnitVectors[vect__?(VectorQ[#, NumericQ] &)] /; (SameQ @@ Length /@ {vect}) && (Length[First[{vect}]] > 1) := #/Sqrt[#.#] & /@ NullSpace[{vect}// N] and the short version for 3D vectors OrthogonalUnitVectors[v : {_, _, _}] := #/Sqrt[#.#] & /@ NullSpace[{v//N}] For exact vectors I might use for 3D OrthogonalUnitVectors[v : {_, _, _}] := #/Sqrt[#.#] & /@ {temp = First[NullSpace[{v}]], v\[Cross]temp} I'm still looking for something that is easy to remember. David Park djmp at earthlink.net http://home.earthlink.net/~djmp/ From: Ersek, Ted R [mailto:ErsekTR at navair.navy.mil] To: mathgroup at smc.vnet.net Hugh Goyder and David Park gave a most elegant function to find two vectors that are orthogonal to one vector in 3D. The key to coming up with the elegant solution is an understanding of Mathematica's NullSpace function. We can easily make the version from Hugh and David much more general with the version below. ------------- OrthogonalUnitVectors[vect__?VectorQ]:= #/Sqrt[#.#]&/@NullSpace[{vect}] ------------- The version above will give a set of unit orthogonal vectors if given any number of vectors in any dimension. So besides giving it a 3D vector we can give it the following: OrthogonalUnitVectors[{2,1,0,-1,1}] or OrthogonalUnitVectors[{0,1,0,1/2,1},{1,0,-1,1/2}] ------------ But the short version above isn't very robust. (1) Clear[x,y,z];NullSpace[{{x,y,z}}] returns two vectors orthogonal to {x,y,z}, but the two vectors NullSpace returns aren't orthogonal to each other. So (OrthogonalUnitVectors) should only work with numeric vectors. (2) We should ensure all the vectors have the same dimension and length >1. I give a less concise version below that corrects these problems. ------------ OrthogonalUnitVectors[vect__?(VectorQ[#,NumericQ]&)]/; (SameQ@@Length/@{vect})&&(Length[First[{vect}]]>1):= #/Sqrt[#.#]&/@NullSpace[{vect}] -------------- Regards, Ted Ersek Get Mathematica tips, tricks from http://www.verbeia.com/mathematica/tips/Tricks.html