@Override public DoubleMatrix2D transitionMatrix(double from_time, double to_time) { double from_time_reminder = from_time % 1.0; double from_time_div = from_time - from_time_reminder; double to_time_reminder = to_time - from_time_div; DoubleMatrix2D cached = cachedTransitionMatrices.get( new Pair<Double, Double>(from_time_reminder, to_time_reminder)); if (cached != null) { return cached; } else { double step_start_time = from_time; double step_end_time = step_start_time; DoubleMatrix2D result = F.identity(num_states); while (step_start_time < to_time) { double step_start_time_reminder = step_start_time % 1.0; double step_start_time_div = step_start_time - step_start_time_reminder; if (isInSeason1(step_start_time)) { step_end_time = Math.min( to_time, step_start_time_div + season1Start + season1Length + infitesimalTimeInterval); result = result.zMult( season1MigrationModel.transitionMatrix(step_start_time, step_end_time), null); } else { // In Season 2 if (step_start_time_reminder < season1Start) { step_end_time = Math.min(to_time, step_start_time_div + season1Start + infitesimalTimeInterval); } else { step_end_time = Math.min( to_time, step_start_time_div + 1.0 + season1Start + infitesimalTimeInterval); } result = result.zMult( season2MigrationModel.transitionMatrix(step_start_time, step_end_time), null); } step_start_time = step_end_time; } // cache result if (cachedTransitionMatrices.size() >= maxCachedTransitionMatrices) { for (int i = 0; i < cachedTransitionMatrices.size() / 2; i++) { cachedTransitionMatrices.remove(cachedTransitionMatrices.keySet().iterator().next()); } } cachedTransitionMatrices.put( new Pair<Double, Double>(from_time_reminder, to_time_reminder), result); return result; } }
@Test public void testInclinedPlane() throws IOException { DoubleMatrix1D normal = new DenseDoubleMatrix1D(3); normal.assign(new double[] {.0, .0, 1.0}); InclinedPlane3D inclinedPlane = new InclinedPlane3D(); inclinedPlane.setRandomGenerator(new MersenneTwister(123456789)); inclinedPlane.setNormal(normal); inclinedPlane.setBounds(new Rectangle(-5, -5, 10, 10)); inclinedPlane.setNoiseStd(0.5); DoubleMatrix2D data = inclinedPlane.generate(10); SVDPCA pca = new SVDPCA(data); System.out.println("Eigenvalues:"); System.out.println(pca.getEigenvalues()); System.out.println("Eigenvectors:"); System.out.println(pca.getEigenvectors()); System.out.println("Meanvector:"); System.out.println(pca.getMean()); // Recalculate the input from a truncated SVD, first calculate the mean DoubleMatrix1D mean = new SparseDoubleMatrix1D(3); for (int i = 0; i < data.rows(); ++i) { mean.assign(data.viewRow(i), Functions.plus); } mean.assign(Functions.div(data.rows())); // Truncate the SVD and calculate the coefficient matrix DenseDoubleMatrix2D coefficients = new DenseDoubleMatrix2D(data.rows(), 2); DoubleMatrix2D centeredInput = data.copy(); for (int i = 0; i < data.rows(); ++i) { centeredInput.viewRow(i).assign(mean, Functions.minus); } centeredInput.zMult( pca.getEigenvectors().viewPart(0, 0, 2, 3), coefficients, 1, 0, false, true); // Reconstruct the data from the lower dimensional information DoubleMatrix2D reconstruction = data.copy(); for (int i = 0; i < reconstruction.rows(); ++i) { reconstruction.viewRow(i).assign(mean); } coefficients.zMult( pca.getEigenvectors().viewPart(0, 0, 2, 3), reconstruction, 1, 1, false, false); // Output to file (can be read by GNU Plot) String fileName = "inclined-plane-svd-pca.dat"; String packagePath = this.getClass().getPackage().getName().replaceAll("\\.", "/"); File outputFile = new File("src/test/resources/" + packagePath + "/" + fileName); PrintWriter writer = new PrintWriter(outputFile); writer.write(data.toString()); writer.close(); }