Search code examples
clinear-algebravector-graphics

Generating random vector that's linearly independent of a set of vectors


I'm trying to come up with an algorithm that will allow me to generate a random N-dimensional real-valued vector that's linearly independent with respect to a set of already-generated vectors. I don't want to force them to be orthogonal, only linearly independent. I know Graham-Schmidt exists for the orthogonalization problem, but is there a weaker form that only gives you linearly independent vectors?


Solution

  • Step 1. Generate random vector vr.

    Step 2. Copy vr to vo and update as follows: for every already generated vector v in v1, v2... vn, subtract the projection of vo on vi.

    The result is a random vector orthogonal to the subspace spanned by v1, v2... vn. If that subspace is a basis, then it is the zero vector, of course :)

    The decision of whether the initial vector was linearly independent can be made based on the comparison of the norm of vr to the norm of vo. Non-linearly independent vectors will have a vo-norm which is zero or nearly zero (some numerical precision issues may make it a small nonzero number on the order of a few times epsilon, this can be tuned in an application-dependent way).

    Pseudocode:

    vr = random_vector()
    vo = vr
    for v in (v1, v2, ... vn):
        vo = vo - dot( vr, v ) / norm( v )
    if norm(vo) < k1 * norm(vr):
        # this vector was mostly contained in the spanned subspace
    else:
        # linearly independent, go ahead and use
    

    Here k1 is a very small number, 1e-8 to 1e-10 perhaps?

    You can also go by the angle between vr and the subspace: in that case, calculate it as theta = arcsin(norm(vo) / norm(vr)). Angles substantially different from zero correspond to linearly independent vectors.