I found a method that makes me much happier. There may be possible improvements, so if you have a better method or find an error in this code, definitely please share. Although here is what I have now: (everything is written in SciLab)
Step 1: Find out the maximum ranges. Thanks for ElKamina for the vague suggestion, as well as for answering another question on math.se from chappers: https://math.stackexchange.com/a/1230160/49989
function I=findMaxComponents(A,r) //returns matrix I, takes matrix A, scalar r [dims,vecs]=size(A); //figure out how many vectors there are in A (and, unnecessarily, how long they are) U=eye(vecs,vecs); //builds matching unit matrix iATA=pinv(A'*A); //finds the (pseudo-)inverse of A^TA iAT=pinv(A'); //finds the (pseudo-)inverse of A^T I=[]; //initializes I as an empty vector for i=1:vecs t=r*(iATA*U(:,i))/norm(iAT*U(:,i)) //put it all together as per above link I=[I,t(i)]; //take only the maximized component and store it in I. end I=[-I;I]; //I want to go from minimum to maximum value. endfunction
In my question, I asked only for a general basis, i.e. for n dimensions, a set of n arbitrary, but linearly independent vectors. The above code, due to the use of pseudo-inversions, works for arbitrary-form matrices and, similarly, Scilab "A" returns conjugate transposition, and not just transposition of A, so it should work the same for complex matrices.
In the last step, I put the appropriate minimal components.
For one such A, as an example, this gives me the following in the Scilab console:
A = 0.9701425 - 0.2425356 0. 0.2425356 0.4850713 0.7276069 0.2425356 0.7276069 - 0.2425356 r=3; I=findMaxComponents(A,r) I = - 2.9494438 - 3.4186986 - 4.0826424 2.9494438 3.4186986 4.0826424 I=int(I) I = - 2. - 3. - 4. 2. 3. 4.
For each component, the above values ​​are the maximum ones that still land on the sphere, so I can safely reset the part after the decimal point to get the maximum integers. Therefore, for a given matrix A, I will have to go from -2 to 2 in the first component, from -3 to 3 in the second and from -4 to 4 in the third, and I'm sure that I will land on all points inside the sphere. Further:
Step 2: Using the information above, find all the combinations.
function K=findAllCombinations(I) //takes a matrix of the form produced by findMaxComponents() and returns a matrix which lists all the integer linear combinations in the respective ranges. v=I(1,:); //starting from the minimal vector K=[]; next=1; //keeps track of what component to advance next changed=%F; //keeps track of whether to add the vector to the output while or(v~=I(2,:)) //as long as not all components of v match all components of the maximum vector if v <= I(2,:) then //if each current component is smaller than each largest possible component if ~changed then K=[K;v]; //store the vector and end v(next)=v(next)+1; //advance the component by 1 next=1; //also reset next to 1 changed=%F; else v(1:next)=I(1,1:next); //reset all components smaller than or equal to the current one and next=next+1; //advance the next larger component next time changed=%T; end end K=[K;I(2,:)]'; //while loop ends a single iteration early so add the maximal vector too //also transpose K to fit better with the other functions endfunction
So, now that I have it, it remains only to check whether this combination really lies inside or outside the sphere. All I have to do for this:
Step 3: Create Actual Points
function points=generatePoints(A,K,r) possiblePoints=A*K;
And I get all the combinations that fall within the scope of radius r.
In the above example, the output is quite long: initially 315 possible points for a sphere of radius 3, I get 163 remaining points.
First 4: (each column is one)
- 0.2425356 0.2425356 1.2126781 - 0.9701425 - 2.4253563 - 2.6678919 - 2.4253563 - 2.4253563 1.6977494 0. 0.2425356 0.4850713
so the rest of the work is optimization. Presumably, some of these cycles could be done faster, and especially as the number of measurements increases, I have to generate a lot of points that I have to drop, so there may be a better way than to take (distorted at this coordinate frame) bounding the hyperfield of the n-sphere as a starting point.