1

I'm using the Jscience linear algebra module to solve a linear system of rational numbers. This works as expected and gives the correct result:

public static void main(String[] args) {
    DenseMatrix<Rational> m = DenseMatrix.valueOf(
        DenseVector.valueOf(r(1, 1), r(-1, 1), r(0, 1), r(0, 1), r(1, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(1, 1), r(-1, 1), r(0, 1), r(2, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(-1, 1), r(1, 1)),
        DenseVector.valueOf(r(1, 1), r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(1, 1), r(0, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(-1, 1), r(1, 1), r(0, 1), r(0, 1), r(0, 1)));

    DenseVector<Rational> v = DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(1, 1), r(1, 2));

    Vector<Rational> sol = m.solve(v);

    System.out.println(sol);
}

private static Rational r(int n, int d) {
    return Rational.valueOf(n, d);
}

The code will print {0/1, 1/6, 2/3, 1/1, 1/6, 1/6} when executed.

My intention is to solve this system with many different values of one of the components of v, so I converted the code to use RationalFunction<Rational> instead of Rational. In the first step, I've not introduced a Variable yet and every RationalFunction<Rational> is a constant. My understanding is that this should give the same result as before:

public static void main(String[] args) {
    DenseMatrix<RationalFunction<Rational>> m = DenseMatrix.valueOf(
        DenseVector.valueOf(r(1, 1), r(-1, 1), r(0, 1), r(0, 1), r(1, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(1, 1), r(-1, 1), r(0, 1), r(2, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(-1, 1), r(1, 1)),
        DenseVector.valueOf(r(1, 1), r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(1, 1), r(0, 1), r(0, 1)),
        DenseVector.valueOf(r(0, 1), r(-1, 1), r(1, 1), r(0, 1), r(0, 1), r(0, 1)));

    DenseVector<RationalFunction<Rational>> v = DenseVector.valueOf(r(0, 1), r(0, 1), r(0, 1), r(0, 1), r(1, 1), r(1, 2));

    Vector<RationalFunction<Rational>> sol = m.solve(v);

    System.out.println(sol);
}

private static RationalFunction<Rational> r(int n, int d) {
    return RationalFunction.valueOf(Polynomial.valueOf(Rational.valueOf(n, d), Term.ONE), Polynomial.valueOf(Rational.ONE, Term.ONE));
}

But this prints the following when executed, i.e. 0/0 for each component:

{([0/1])/([0/1]), ([0/1])/([0/1]), ([0/1])/([0/1]), ([0/1])/([0/1]), ([0/1])/([0/1]), ([0/1])/([0/1])}

Does Matrix.solve() actually support using RationalFunction? It did work when I tested it with a one-by-one matrix.

Where should I look next to solve this problem?

Feuermurmel
  • 9,490
  • 10
  • 60
  • 90

1 Answers1

2

In a rational function, the coefficients of the component polynomials can be taken from any field, including rational numbers. A RationalFunction<Rational> reflects this usage, but solve() never evaluates the function defined by each matrix entry.

One approach would be to construct a new matrix in which each entry is set to the result returned by r.evaluate(). In effect, you would convert the problem in your second example to one that could be solved as shown in your first example.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • Do I understand this right: For each value for the variables in the `RationalFunction`s, `solve()` will find a solution, if it exists, but it will refuse to find a solution that is correct for all values of the variables? The second example does not contain a variable, which may be misleading of what I'm trying to do. – Feuermurmel May 07 '13 at 11:11
  • In your second example, `solve()` concatenates the operations that it normally uses to decompose a matrix of rational values. Examine the result of `r.evaluate()` for each element of `sol` to see the effect. – trashgod May 07 '13 at 11:24
  • For each element `sol.get(i).evaluate()` throws an exception: `java.lang.ArithmeticException: Dividend is zero`. – Feuermurmel May 07 '13 at 11:50
  • Exactly; the stack trace shows the accumulated operations. You're asking `solve()` to find a vector of ration functions that meets the `solve()` contract; it can't. – trashgod May 07 '13 at 11:54