/** * @param y vector of measurements. * @param cy covaariance matrix of measurements. * @param x vector of first approximations of unknowns. * @param list array containing the elements of a list specifying which of the n variables are * fixed (list element = 0) and which are adjustable (list element = 1). m number of constaint * equations * @param uf user function which must be an extension of the abstract class DatanUserFunction. */ public LsqGen( DatanVector y, DatanMatrix cy, DatanVector x, int[] list, int m, DatanUserFunction uf) { this.y = y; this.cy = cy; this.x = x; this.list = list; this.m = m; this.uf = uf; n = y.getNumberOfElements(); r = list.length; nred = 0; for (int i = 0; i < r; i++) { if (list[i] == 1) nred++; } l = n + nred; t = new DatanVector(l); f = new DatanMatrix(cy); f.choleskyInversion(); fy = f.choleskyDecomposition(); mfvec = new DatanVector(1); ok = new boolean[1]; mf = 0.; nstep = 100; d = new DatanVector(m); loop: for (int istep = 0; istep < nstep; istep++) { mflast = mf; f = new DatanMatrix(l, l); f.putSubmatrix(nred, nred, fy); e = new DatanMatrix(m, l); computeMatrixOfDerivatives(); for (int k = 0; k < m; k++) { d.setElement(k, -uf.getValue(y, x, k)); } b = f.choleskyMultiply(t); b = b.multiply(-1.); u = f.leastSquaresWithConstraints(b, e, d, mfvec, 0., ok); converged = ok[0]; if (!converged) break loop; mf = mfvec.getElement(0); if (nred > 0) { // update x int ired = -1; for (int i = 0; i < r; i++) { if (list[i] != 0) { ired++; x.setElement(i, x.getElement(i) + u.getElement(ired)); } } } // update y and t for (int i = 0; i < n; i++) { y.setElement(i, y.getElement(i) + u.getElement(i + nred)); t.setElement(i + nred, t.getElement(i + nred) + u.getElement(i + nred)); } // test for convergence if (istep > 0 && Math.abs(mf - mflast) < mf * EPSILON + T) break loop; } if (converged) { computeMatrixOfDerivatives(); a = e.getSubmatrix(m, n, 0, nred); help = cy.multiplyWithTransposed(a); gb = a.multiply(help); gb.choleskyInversion(); if (nred > 0) { help2 = e.getSubmatrix(m, nred, 0, 0); help3 = help2.multiplyTransposedWith(gb); cx = help3.multiply(help2); cx.choleskyInversion(); // cx contains covariance matrx of unknowns } else { cx = new DatanMatrix(1, 1); // for nred ==0 the matrix cx is set to be the (1 x 1) zero matrix } a = e.getSubmatrix(m, n, 0, nred); help = a.multiply(cy); help2 = gb.multiply(a.multiply(cy)); help3 = help.multiplyTransposedWith(help2); cyimproved = cy.sub(help3); // cyimproved contains covariance matrix of "improved" measurements } }
/** * @param y data * @param k parameter giving the length 2 * k + 1 of the averaging interval * @param l oder of the averaging polynomial * @param p probability defining confidence limits */ public TimeSeries(double[] y, int k, int l, double p) { this.y = y; this.k = k; this.l = l; this.p = p; n = y.length; eta = new double[n + 2 * k]; coneta = new double[n + 2 * k]; // quantile of Student's distribution pprime = 0.5 * (p + 1.); nf = 2 * k - l; talpha = StatFunct.quantileStudent(pprime, nf); // compute matrices depending on k and l k21 = 2 * k + 1; l1 = l + 1; a = new DatanMatrix(k21, l1); for (int i = 0; i < k21; i++) { for (int j = 0; j < l1; j++) { if (j == 0) a.setElement(i, j, -1.); else a.setElement(i, j, a.getElement(i, j - 1) * (double) (i - k)); } } ata1 = a.multiplyTransposedWith(a); ata1.choleskyInversion(); ata1at = ata1.multiplyWithTransposed(a); ata1at = ata1at.multiply(-1.); // moving averages and confidence limits for inner part ymat = new DatanMatrix(y); for (int i = 2 * k; i < n; i++) { ytmp = ymat.getSubmatrix(k21, 1, i - 2 * k, 0); x = ata1at.multiply(ytmp); eta[i] = x.getElement(0, 0); etatmp = a.multiply(x); etatmp = etatmp.add(ytmp); sy2 = etatmp.multiplyTransposedWith(etatmp); double s = sy2.getElement(0, 0) / (double) nf; double a0 = Math.sqrt(Math.abs(ata1.getElement(0, 0))); coneta[i] = a0 * Math.sqrt(s) * talpha; // moving averages and confidence limits for end sections if (i == 2 * k || i == n - 1) { tt = new double[l + 1]; if (i == 2 * k) { iadd = 2 * k; is = -1; } else { iadd = n - 1; is = 1; } for (int i1 = 1; i1 <= 2 * k; i1++) { j = is * i1; for (int i2 = 0; i2 < l + 1; i2++) { for (int i3 = 0; i3 <= i2; i3++) { if (i3 == 0) tt[i2] = 1.; else tt[i2] = tt[i2] * (double) j; } } tmat = new DatanMatrix(tt); seta2 = tmat.multiplyTransposedWith(ata1.multiply(tmat)); double se2 = s * seta2.getElement(0, 0); etai = tmat.multiplyTransposedWith(x); eta[iadd + j] = etai.getElement(0, 0); coneta[iadd + j] = Math.sqrt(Math.abs(se2)) * talpha; } } } }