I've been noodling with the javax.vecmath.GMatrix and
javax.vecmath.GVector classes.  I believe I've found a
problem in the javax.vecmath.GMatrix.SVD() and
javax.vecmath.GVector.SVDBackSolve() methods.

There's a discussion thread at the Java3D Forum that
traces out the history:

http://forum.java.sun.com/thread.jsp?
forum=21&thread=454002&tstart=0&trange=15

I downloaded the Java3D implementation from the Sun
Java site.  I'm running JDK 1.4.1_03 on a Windows 2000
version 5.0 SP 4 PC.

I tested using two classes: SVDTest.java and
LUTest.java.  Both can be compiled and run by typing
"javac *.java" and "java SVDTest" or "java
LUTest" - no packages.  All the data they need are
hardwired inside for all test cases.

SVDTest.java:

[code]
import javax.vecmath.* ;

public class SVDTest
{
// From http://web.mit.edu/18.06/www/Fall03/ps1.pdf,
problem 3
// Gil Strang's course Web site.
/*
    public static final int nrows = 3;
    public static final int ncols = 3;
    public static final double [] aInput =
    {
        1,  1, 0,
        4,  6, 1,
        -2, 2, 0,
    };
    public static final double [] bInput =
    {
        1, 4, -10,
    };
*/
    // From
http://www.bluebit.gr/matrix/reference/SVD-Example.htm
    // Solution vector: x = { 4.089, 3.066, 2.163, }
/*
    public static final int nrows = 20;
    public static final int ncols = 3;
    public static final double[] aInput =
    {
        6, 5, 5,
        3, 3, 7,
        0, 7, 7,
        6, 0, 4,
        8, 7, 3,
        9, 8, 1,
        9, 3, 5,
        7, 0, 5,
        4, 3, 6,
        6, 2, 3,
        7, 7, 5,
        9, 8, 2,
        6, 9, 2,
        5, 1, 9,
        6, 0, 5,
        1, 1, 7,
        3, 0, 3,
        3, 3, 9,
        9, 4, 3,
        1, 1, 6,
    };
    public static final double[] bInput =
    {
        51, 37, 37, 33, 60, 64, 55, 40, 39, 38, 59,
65, 58, 43, 35, 24,
21,
39, 57, 20,
    };
*/


// From
http://cs.uakron.edu/~quesada/Courses/LinAlg/Projects/svdpaper.pdf
    public static final int nrows = 2;
    public static final int ncols = 3;
    public static final double [] aInput =
    {
        3, 2, 2,
        2, 3, -2,
    };
    public static final double [] bInput =
    {
        3, 2,
    };


    public static void main(String[] args)
    {
        try
        {
            // Create the A matrix
            GMatrix a = new GMatrix(nrows, ncols,
aInput);
            System.out.println("a:");
            System.out.println(a);

            // Perform the SVD
            GMatrix u = new GMatrix(nrows, nrows);
            GMatrix w = new GMatrix(nrows, ncols);
            GMatrix v = new GMatrix(ncols, ncols);

            int rank  = a.SVD(u,w,v);

            System.out.println("rank: " + rank);
            System.out.println("u:");
            System.out.println(u);
            System.out.println("v:");
            System.out.println(v);
            System.out.println("w:");
            System.out.println(w);

            // Check to make sure that transpose(U)*U
= identity
            GMatrix utranspose  = new GMatrix(u);
            utranspose.transpose();
            GMatrix udelta = new GMatrix(ncols,
ncols);
            udelta.mul(utranspose, u);
            System.out.println("udelta:");
            System.out.println(udelta);

            // Check to make sure that transpose(V)*V
= identity
            GMatrix vtranspose  = new GMatrix(v);
            vtranspose.transpose();
            GMatrix vdelta = new GMatrix(ncols,
ncols);
            vdelta.mul(vtranspose, v);
            System.out.println("vdelta:");
            System.out.println(vdelta);

            // Create the RHS vector
            GVector b = new GVector(bInput);
            System.out.println("b:");
            System.out.println(b);

            // Perform back substitution
            GVector x = new GVector(nrows);
            x.SVDBackSolve(u, w, v, b);
            System.out.println("result:");
            System.out.println(x);
        }
        catch (Exception e)
        {
            e.printStackTrace(System.err);
        }
    }
}
[/code]

LUTest.java:

[code]
import javax.vecmath.* ;

public class LUTest
{
    // See
http://web.mit.edu/18.06/www/Fall03/ps1.pdf, problem 3
    public static final int nrows = 3;
    public static final int ncols = 3;
    public static final double [] aInput =
    {
        1,  1, 0,
        4,  6, 1,
        -2, 2, 0,
    };
    public static final double [] bInput =
    {
        1, 4, -10,
    };

    public static void main (String[] args)
    {
        try
        {
            // Create the A matrix
            GMatrix a = new GMatrix(nrows, ncols,
aInput);
            System.out.println("a: ");
            System.out.println(a);

            // Perform LU decomposition
            GVector permutation = new GVector(nrows);
            int numExchanges = a.LUD(a, permutation);

            // Create the RHS vector
            GVector b = new GVector(bInput);
            System.out.println("b:");
            System.out.println(b);

            // Perform back substitution
            GVector x = new GVector(nrows);
            x.LUDBackSolve(a, b, permutation);
            System.out.println("result:");
            System.out.println(x);
        }
        catch (Exception e)
        {
            e.printStackTrace(System.err);
        }
    }
}
[/code]

I used two problems to test the algorithms.  The first
is a homework problem from Gil Strang's linear algebra
class at MIT:

http://web.mit.edu/18.06/www/Fall03/ps1.pdf, problem 3

The second is from an SVD site that Google found for
me:

http://cs.uakron.edu/~quesada/Courses/LinAlg/Projects/svdpaper.pdf

I ran the Strang problem first because it was a
non-singular, square matrix with a solution that was
easily available using LU decomposition.  The LU
decomposition routines in javax.vecmath worked
perfectly and gave me the correct, expected answer:

x = { 3.0, -2.0, 4.0, }

Unfortunately, the SVD routines did not.  They gave
me:

x = { -9.519991330217254, 1.1446425543705807,
-5.005952306535923, }

When I tried running the Univ. of Akron case with m >
n, I got this exception instead of an answer:

java.lang.ArrayIndexOutOfBoundsException: 2
        at
javax.vecmath.GMatrix.computeSVD(GMatrix.java:2055)
        at
javax.vecmath.GMatrix.SVD(GMatrix.java:1574)
        at SVDTest.main(SVDTest.java:107)

Also, I am mystified by the javadocs.  When I look at
the SVD algorithm in "Numerical Recipes" and at
http://kwon3d.com/theory/jkinem/svd.html,
both say that if A is an m x n matrix, then U is m x
n, W is n x n, and V is n x n.  But the javadocs for
javax.vecmath say that U is m x m, W is m x n, and V
is n x n.  Why the difference?

Please let me know if this is a bug or pilot error.
It's my first foray into Java3D, so perhaps I'm
mistaken.  Thanks - MOD

__________________________________
Do you Yahoo!?
The New Yahoo! Shopping - with improved product search
http://shopping.yahoo.com

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to