package org.spaceroots.mantissa.algebra;
import java.util.ArrayList;
public abstract class CoefficientsGenerator {
/** Build a generator with coefficients for two polynomials.
* The first polynomial must be a degree 0 polynomial
* P0(X)=a0,0 and the second polynomial
* must be a degree 1 polynomial P1(X)=a0,1
* +a1,1X
* @param a00 constant term for the degree 0 polynomial
* @param a01 constant term for the degree 1 polynomial
* @param a11 X term for the degree 1 polynomial
*/
protected CoefficientsGenerator(RationalNumber a00,
RationalNumber a01, RationalNumber a11) {
l = new ArrayList();
l.add(a00);
l.add(a01);
l.add(a11);
maxDegree = 1;
}
/** Set the recurrence coefficients.
* @param b2k b2,k coefficient (b2,k = a2,k / a1,k)
* @param b3k b3,k coefficient (b3,k = a3,k / a1,k)
* @param b4k b4,k coefficient (b4,k = a4,k / a1,k)
*/
protected void setRecurrenceCoefficients(RationalNumber b2k,
RationalNumber b3k,
RationalNumber b4k) {
this.b2k = b2k;
this.b3k = b3k;
this.b4k = b4k;
}
/** Set the recurrence coefficients.
* The recurrence relation is
* a1,k Ok+1(X) =(a2,k + a3,k X) Ok(X) - a4,k Ok-1(X)
* the method must call {@link #setRecurrenceCoefficients(RationalNumber,
* RationalNumber, RationalNumber)} to provide the coefficients
* @param k index of the current step
*/
protected abstract void setRecurrenceCoefficients(int k);
/** Compute all the polynomial coefficients up to a given degree.
* @param degree maximal degree
*/
private void computeUpToDegree(int degree) {
int startK = (maxDegree - 1) * maxDegree / 2;
for (int k = maxDegree; k < degree; ++k) {
// start indices of two previous polynomials Ok(X) and Ok-1(X)
int startKm1 = startK;
startK += k;
// a1k Ok+1(X) = (a2k + a3k X) Ok(X) - a4k Ok-1(X)
// we use bik = aik/a1k
setRecurrenceCoefficients(k);
RationalNumber ckPrev = null;
RationalNumber ck = (RationalNumber) l.get(startK);
RationalNumber ckm1 = (RationalNumber) l.get(startKm1);
// degree 0 coefficient
l.add(ck.multiply(b2k).subtract(ckm1.multiply(b4k)));
// degree 1 to degree k-1 coefficients
for (int i = 1; i < k; ++i) {
ckPrev = ck;
ck = (RationalNumber) l.get(startK + i);
ckm1 = (RationalNumber) l.get(startKm1 + i);
l.add(ck.multiply(b2k).add(ckPrev.multiply(b3k)).subtract(ckm1.multiply(b4k)));
}
// degree k coefficient
ckPrev = ck;
ck = (RationalNumber) l.get(startK + k);
l.add(ck.multiply(b2k).add(ckPrev.multiply(b3k)));
// degree k+1 coefficient
l.add(ck.multiply(b3k));
}
maxDegree = degree;
}
/** Get the coefficients array for a given degree.
* @param degree degree of the polynomial
* @return coefficients array
*/
public RationalNumber[] getCoefficients(int degree) {
synchronized (this) {
if (degree > maxDegree) {
computeUpToDegree(degree);
}
}
// coefficient for polynomial 0 is l [0]
// coefficients for polynomial 1 are l [1] ... l [2] (degrees 0 ... 1)
// coefficients for polynomial 2 are l [3] ... l [5] (degrees 0 ... 2)
// coefficients for polynomial 3 are l [6] ... l [9] (degrees 0 ... 3)
// coefficients for polynomial 4 are l[10] ... l[14] (degrees 0 ... 4)
// coefficients for polynomial 5 are l[15] ... l[20] (degrees 0 ... 5)
// coefficients for polynomial 6 are l[21] ... l[27] (degrees 0 ... 6)
// ...
int start = degree * (degree + 1) / 2;
RationalNumber[] a = new RationalNumber[degree + 1];
for (int i = 0; i <= degree; ++i) {
a[i] = (RationalNumber) l.get(start + i);
}
return a;
}
/** List holding the coefficients of the polynomials computed so far. */
private ArrayList l;
/** Maximal degree of the polynomials computed so far. */
private int maxDegree;
/** b2,k coefficient to initialize
* (b2,k = a2,k / a1,k). */
private RationalNumber b2k;
/** b3,k coefficient to initialize
* (b3,k = a3,k / a1,k). */
private RationalNumber b3k;
/** b4,k coefficient to initialize
* (b4,k = a4,k / a1,k). */
private RationalNumber b4k;
}
Ads help maintain this website.