39 private double[][] mat;
43 private static double[] cPade = { 17643225600d, 8821612800d, 2075673600d, 302702400, 30270240, 2162160, 110880, 3960,
47 private static double[] p_em1 = { 1.0, 1.0 / 30, 1.0 / 30, 1.0 / 936, 1.0 / 4680, 1.0 / 171600, 1.0 / 3603600,
51 private static double[] q_em1 = { 1.0, -(7.0 / 15), 1.0 / 10, -(1.0 / 78), 1.0 / 936, -(1.0 / 17160), 1.0 / 514800,
65 private static void innerMultBand(DoubleMatrix2D A0,
int sa, DoubleMatrix2D B0,
int sb, DoubleMatrix2D C) {
76 final int n = A.rows();
79 for (
int i = 0; i < n; ++i) {
80 int jmax = Math.min(i + sa + sb, n - 1);
81 for (
int j = i; j <= jmax; ++j) {
82 kmin = Math.max(i, j - sb);
83 kmax = Math.min(i + sa, j);
85 for (
int k = kmin; k <= kmax; ++k) {
97 private static int getScale(
final DoubleMatrix2D A,
double theta) {
99 final double norm = norm1bidiag(A) / theta;
102 s = (int) Math.ceil(
Num.
log2(norm));
110 private static DoubleMatrix2D m_taylor(
final DoubleMatrix2D A) {
113 final double EPS = 1.0e-12;
114 final int k = A.rows();
115 final int JMAX = 2 * k + 100;
116 DoubleMatrix2D Sum = A.copy();
117 DoubleMatrix2D Term = A.copy();
119 Functions F = Functions.functions;
120 Algebra alge =
new Algebra();
123 for (
int j = 2; j <= JMAX; ++j) {
124 Term = alge.mult(A, Term);
125 Term.assign(F.mult(1.0 / j));
126 Sum.assign(Term, F.plus);
128 normS = alge.normInfinity(Sum);
129 normT = alge.normInfinity(Term);
130 if (normT <= normS * EPS)
139 private static DoubleMatrix1D m_taylor(
final DoubleMatrix2D A,
final DoubleMatrix1D b) {
142 final double EPS = 1.0e-12;
143 final int k = A.rows();
144 final int JMAX = 2 * k + 100;
145 DoubleFactory1D factory = DoubleFactory1D.dense;
146 DoubleMatrix1D Term = b.copy();
147 DoubleMatrix1D Sum = factory.make(k);
149 Functions F = Functions.functions;
150 Algebra alge =
new Algebra();
153 for (
int j = 1; j <= JMAX; ++j) {
154 Term = alge.mult(A, Term);
155 Term.assign(F.mult(1.0 / j));
156 Sum.assign(Term, F.plus);
158 Tnorm = alge.norm1(Term);
159 Snorm = alge.norm1(Sum);
160 if (Tnorm <= Snorm * EPS)
169 private static DoubleMatrix2D m_expmiBidiag(
final DoubleMatrix2D A) {
176 final int n = A.rows();
177 DoubleMatrix2D B = A.copy();
178 DoubleFactory2D fac = DoubleFactory2D.dense;
179 final DoubleMatrix2D I = fac.identity(n);
180 final DoubleMatrix2D B2 = fac.make(n, n);
181 final DoubleMatrix2D B4 = fac.make(n, n);
182 final DoubleMatrix2D B6 = fac.make(n, n);
183 DMatrix.multBand(B, 1, B, 1, B2);
184 DMatrix.multBand(B2, 2, B2, 2, B4);
185 DMatrix.multBand(B4, 4, B2, 2, B6);
187 DoubleMatrix2D V = B6.copy();
188 DoubleMatrix2D U = B4.copy();
189 DMatrix.addMultBand(p_em1[4], U, 4, p_em1[2], B2, 2);
190 DMatrix.addMultBand(p_em1[6], V, 6, p_em1[0], I, 0);
191 DMatrix.addMultBand(1.0, V, 6, 1.0, U, 6);
193 DoubleMatrix2D W = B6.copy();
195 DMatrix.addMultBand(p_em1[5], U, 4, p_em1[3], B2, 2);
196 DMatrix.addMultBand(p_em1[7], W, 6, p_em1[1], I, 0);
197 DMatrix.addMultBand(1.0, W, 6, 1.0, U, 6);
198 DMatrix.multBand(W, 6, B, 1, U);
200 DMatrix.addMultBand(1.0, V, 6, 1.0, U, 7);
201 DoubleMatrix2D N = V.copy();
205 DMatrix.addMultBand(q_em1[4], U, 4, q_em1[2], B2, 2);
206 DMatrix.addMultBand(q_em1[6], V, 6, q_em1[0], I, 0);
207 DMatrix.addMultBand(1.0, V, 6, 1.0, U, 6);
211 DMatrix.addMultBand(q_em1[5], U, 4, q_em1[3], B2, 2);
212 DMatrix.addMultBand(q_em1[7], W, 6, q_em1[1], I, 0);
213 DMatrix.addMultBand(1.0, W, 6, 1.0, U, 6);
214 DMatrix.multBand(W, 6, B, 1, U);
216 DMatrix.addMultBand(1.0, V, 6, 1.0, U, 7);
219 DMatrix.solveTriangular(V, N, W);
220 DMatrix.multBand(B, 1, W, n - 1, U);
226 static void addMultTriang(
final DoubleMatrix2D A, DoubleMatrix1D b,
double h) {
231 final int n = A.rows();
233 for (
int i = 0; i < n; ++i) {
234 for (
int j = i; j < n; ++j) {
235 z = A.getQuick(i, j) * b.getQuick(j);
236 b.setQuick(i, h * z);
250 private static double norm1bidiag(DoubleMatrix2D B) {
251 final int n = B.rows();
253 double norm = Math.abs(B.getQuick(0, 0));
254 for (
int i = 1; i < n; ++i) {
255 x = Math.abs(B.getQuick(i - 1, i)) + Math.abs(B.getQuick(i, i));
269 mat =
new double[r][c];
282 public DMatrix(
double[][] data,
int r,
int c) {
284 for (
int i = 0; i < r; i++)
285 for (
int j = 0; j < c; j++)
286 mat[i][j] = data[i][j];
295 this(that.mat, that.r, that.c);
308 DoubleMatrix2D MM =
new DenseDoubleMatrix2D(M);
309 DoubleMatrix2D LL =
new DenseDoubleMatrix2D(d, d);
310 CholeskyDecomposition decomp =
new CholeskyDecomposition(MM);
312 for (
int i = 0; i < L.length; i++)
313 for (
int j = 0; j <= i; j++)
314 L[i][j] = LL.get(i, j);
315 for (
int i = 0; i < L.length; i++)
316 for (
int j = i + 1; j < L.length; j++)
329 CholeskyDecomposition decomp =
new CholeskyDecomposition(M);
330 return decomp.getL();
345 public static void PCADecompose(
double[][] M,
double[][] A,
double[] lambda) {
347 DoubleMatrix2D MM =
new DenseDoubleMatrix2D(M);
348 DoubleMatrix2D AA =
new DenseDoubleMatrix2D(d, d);
351 for (
int i = 0; i < d; i++)
352 for (
int j = 0; j < d; j++)
353 A[i][j] = AA.get(i, j);
367 public static DoubleMatrix2D
PCADecompose(DoubleMatrix2D M,
double[] lambda) {
372 SingularValueDecomposition sv =
new SingularValueDecomposition(M);
374 DoubleMatrix2D D = sv.getS();
376 for (
int i = 0; i < D.rows(); ++i)
377 lambda[i] = D.getQuick(i, i);
380 for (
int i = 0; i < D.rows(); ++i)
381 D.setQuick(i, i, Math.sqrt(lambda[i]));
382 DoubleMatrix2D P = sv.getV();
384 return P.zMult(D,
null);
396 public static double[]
solveLU(
double[][] A,
double[] b) {
397 DoubleMatrix2D M =
new DenseDoubleMatrix2D(A);
398 DoubleMatrix1D c =
new DenseDoubleMatrix1D(b);
399 LUDecompositionQuick lu =
new LUDecompositionQuick();
414 public static void solveTriangular(DoubleMatrix2D U, DoubleMatrix2D B, DoubleMatrix2D X) {
415 final int n = U.rows();
416 final int m = B.columns();
419 for (
int j = 0; j < m; ++j) {
420 for (
int i = n - 1; i >= 0; --i) {
421 z = B.getQuick(i, j);
422 for (
int k = i + 1; k < n; ++k)
423 z -= U.getQuick(i, k) * X.getQuick(k, j);
424 z /= U.getQuick(i, i);
436 public static double[][]
exp(
double[][] A) {
437 DoubleMatrix2D V =
new DenseDoubleMatrix2D(A);
438 DoubleMatrix2D R =
exp(V);
450 public static DoubleMatrix2D
exp(
final DoubleMatrix2D A) {
455 DoubleMatrix2D B = A.copy();
457 Algebra alge =
new Algebra();
458 final double mu = alge.trace(B) / n;
462 for (
int i = 0; i < n; ++i) {
463 x = B.getQuick(i, i);
464 B.setQuick(i, i, x - mu);
471 final double THETA9 = 2.097847961257068;
472 int s = getScale(B, THETA9);
474 Functions F = Functions.functions;
476 double v = 1.0 / Math.pow(2.0, s);
478 throw new IllegalArgumentException(
" v <= 0");
481 DoubleFactory2D fac = DoubleFactory2D.dense;
482 final DoubleMatrix2D B0 = fac.identity(n);
483 final DoubleMatrix2D B2 = alge.mult(B, B);
484 final DoubleMatrix2D B4 = alge.mult(B2, B2);
486 DoubleMatrix2D T = B2.copy();
487 DoubleMatrix2D W = B4.copy();
488 W.assign(F.mult(cPade[9]));
489 W.assign(T, F.plusMult(cPade[7]));
490 DoubleMatrix2D U = alge.mult(B4, W);
494 W.assign(F.mult(cPade[5]));
495 W.assign(T, F.plusMult(cPade[3]));
496 W.assign(B0, F.plusMult(cPade[1]));
502 W.assign(F.mult(cPade[8]));
503 W.assign(T, F.plusMult(cPade[6]));
504 DoubleMatrix2D V = alge.mult(B4, W);
508 W.assign(F.mult(cPade[4]));
509 W.assign(T, F.plusMult(cPade[2]));
510 W.assign(B0, F.plusMult(cPade[0]));
516 T.assign(U, F.minus);
519 LUDecomposition lu =
new LUDecomposition(T);
525 for (
int i = 0; i < s; i++)
538 for (
int i = 0; i < s; i++)
560 DoubleMatrix2D B = A.copy();
561 final int n = B.rows();
562 Algebra alge =
new Algebra();
563 final double mu = alge.trace(B) / n;
567 for (
int i = 0; i < n; ++i) {
568 x = B.getQuick(i, i);
569 B.setQuick(i, i, x - mu);
572 final double THETA9 = 2.097847961257068;
573 int s = getScale(B, THETA9);
574 final double v = 1.0 / Math.pow(2.0, s);
576 throw new IllegalArgumentException(
" v <= 0");
579 DoubleFactory2D fac = DoubleFactory2D.dense;
580 DoubleMatrix2D T = fac.make(n, n);
581 DoubleMatrix2D B4 = fac.make(n, n);
582 DMatrix.multBand(B, 1, B, 1, T);
583 DMatrix.multBand(T, 2, T, 2, B4);
585 DoubleMatrix2D W = B4.copy();
586 DMatrix.addMultBand(cPade[9], W, 4, cPade[7], T, 2);
587 DoubleMatrix2D U = fac.make(n, n);
588 DMatrix.multBand(W, 4, B4, 4, U);
591 DMatrix.addMultBand(cPade[5], W, 4, cPade[3], T, 2);
592 for (
int i = 0; i < n; ++i) {
593 x = W.getQuick(i, i);
594 W.setQuick(i, i, x + cPade[1]);
596 DMatrix.addMultBand(1.0, U, 8, 1.0, W, 4);
597 DMatrix.multBand(B, 1, U, 8, U);
600 DMatrix.addMultBand(cPade[8], W, 4, cPade[6], T, 2);
601 DoubleMatrix2D V = B;
602 DMatrix.multBand(W, 4, B4, 4, V);
605 DMatrix.addMultBand(cPade[4], W, 4, cPade[2], T, 2);
606 for (
int i = 0; i < n; ++i) {
607 x = W.getQuick(i, i);
608 W.setQuick(i, i, x + cPade[0]);
610 DMatrix.addMultBand(1.0, V, 8, 1.0, W, 4);
613 DMatrix.addMultBand(1.0, W, 9, 1.0, U, 9);
615 DMatrix.addMultBand(1.0, T, 9, -1.0, U, 9);
618 DMatrix.solveTriangular(T, W, B);
627 for (
int i = 0; i < s; i++) {
628 DMatrix.multBand(B, n - 1, B, n - 1, T);
646 public static DoubleMatrix1D
expBidiagonal(
final DoubleMatrix2D A,
final DoubleMatrix1D b) {
649 Algebra alge =
new Algebra();
650 return alge.mult(U, b);
667 DoubleMatrix2D B = A.copy();
668 final double THETA = 1.13;
669 int s = getScale(B, THETA);
670 final double v = 1.0 / Math.pow(2.0, s);
672 throw new IllegalArgumentException(
" v <= 0");
674 DoubleMatrix2D U = m_expmiBidiag(B);
676 DoubleMatrix2D N = U.copy();
678 DoubleMatrix2D V = N.copy();
684 Algebra alge =
new Algebra();
685 for (
int i = 1; i <= s; i++) {
708 public static DoubleMatrix1D
expmiBidiagonal(
final DoubleMatrix2D A,
final DoubleMatrix1D b) {
709 DoubleMatrix2D F = A.copy();
710 int s = getScale(F, 1.0 / 16.0);
711 final double v = 1.0 / Math.pow(2.0, s);
713 throw new IllegalArgumentException(
" v <= 0");
717 DoubleMatrix2D N = U.copy();
718 DoubleMatrix1D C = m_taylor(F, b);
719 DoubleMatrix1D D = C.copy();
720 Algebra alge =
new Algebra();
725 for (
int i = 1; i <= s; i++) {
737 private static void addIdentity(DoubleMatrix2D A) {
739 final int n = A.rows();
741 for (
int i = 0; i < n; ++i) {
742 x = A.getQuick(i, i);
743 A.setQuick(i, i, x + 1.0);
747 private static void calcDiagm1(DoubleMatrix2D A, DoubleMatrix2D R) {
749 final int n = A.rows();
751 for (
int i = 0; i < n; ++i) {
752 x = A.getQuick(i, i);
772 static void multBand(
final DoubleMatrix2D A,
int sa,
final DoubleMatrix2D B,
int sb, DoubleMatrix2D C) {
773 innerMultBand(A, sa, B, sb, C);
786 static void multBand(DoubleMatrix2D A,
int sa,
double h) {
787 final int n = A.rows();
789 for (
int i = 0; i < n; ++i) {
790 int jmax = Math.min(i + sa, n - 1);
791 for (
int j = i; j <= jmax; ++j) {
792 z = A.getQuick(i, j);
793 A.setQuick(i, j, z * h);
812 static void addMultBand(
double g, DoubleMatrix2D A,
int sa,
double h,
final DoubleMatrix2D B,
int sb) {
815 final int n = A.rows();
817 for (
int i = 0; i < n; ++i) {
818 int jmax = Math.max(i + sa, i + sb);
819 jmax = Math.min(jmax, n - 1);
820 for (
int j = i; j <= jmax; ++j) {
821 z = g * S.getQuick(i, j) + h * B.getQuick(i, j);
833 public static void copy(
double[][] M,
double[][] R) {
834 for (
int i = 0; i < M.length; i++) {
835 for (
int j = 0; j < M[i].length; j++) {
848 StringBuffer sb =
new StringBuffer();
851 for (
int i = 0; i < M.length; i++) {
853 for (
int j = 0; j < M[i].length; j++) {
854 sb.append(M[i][j] +
" ");
855 if (j < M.length - 1)
862 return sb.toString();
903 public double get(
int row,
int column) {
904 if (row >= r || column >= c)
905 throw new IndexOutOfBoundsException();
907 return mat[row][column];
919 public void set(
int row,
int column,
double value) {
920 if (row >= r || column >= c)
921 throw new IndexOutOfBoundsException();
923 mat[row][column] = value;
934 for (
int i = 0; i < r; i++)
935 for (
int j = 0; j < c; j++)
936 result.mat[j][i] = mat[i][j];