@Override @SuppressWarnings("unchecked") public <M extends Number, O extends Number> Matrix<O> outerProduct( Vector<M> y, Vectors.Factory<O> using) { if (using == Vectors.AS_INTS) { int[][] data2 = new int[n][y.length()]; for (Map.Entry<Integer, Integer> e : entrySet()) { for (int j = 0; j < y.length(); j++) { data2[e.getKey()][j] = e.getValue().intValue() * y.intValue(j); } } return (Matrix<O>) new IntArrayMatrix(data2); } else if (using == Vectors.AS_REALS) { double[][] data2 = new double[n][y.length()]; for (Map.Entry<Integer, Integer> e : entrySet()) { for (int j = 0; j < y.length(); j++) { data2[e.getKey()][j] = y.doubleValue(j) * e.getValue().intValue(); } } return (Matrix<O>) new DoubleArrayMatrix(data2); } else { final SparseMatrix<O> matrix = new SparseMatrix<O>(n, y.length(), using); for (Map.Entry<Integer, Integer> e : entrySet()) { for (Map.Entry<Integer, M> e2 : y.entrySet()) { matrix.set( e.getKey(), e2.getKey(), e2.getValue().doubleValue() * e.getKey().doubleValue()); } } return matrix; } }
@Override public <M extends Number, O extends Number> Vector<O> mult( Vector<M> x, Vectors.Factory<O> using) { assert (x.length() == alpha.length); final Vector<O> product = using.make(alpha.length, 0.0); for (int i = 0; i < alpha.length; i++) { double value = 0.0; if (i > 0) { value += x.doubleValue(i - 1) * beta[i - 1]; } value += x.doubleValue(i) * alpha[i]; if (i < beta.length) { value += x.doubleValue(i + 1) * beta[i]; } product.put(i, value); } return product; }
/** * Find w, such that Mw = v * * @param v the vector * @return w */ public Vector<Double> invMult(Vector<Double> v) { final int n = v.length(); if (n != alpha.length) { throw new IllegalArgumentException(); } double[] delta = new double[n - 1]; double[] gamma = new double[n - 1]; delta[0] = v.doubleValue(0) / alpha[0]; gamma[0] = -1.0 * beta[0] / alpha[0]; for (int i = 1; i < n - 1; i++) { final double bga = beta[i - 1] * gamma[i - 1] + alpha[i]; if (bga != 0.0) { delta[i] = (v.doubleValue(i) - beta[i - 1] * delta[i - 1]) / bga; gamma[i] = -1.0 * beta[i] / bga; } else { final double bga2 = beta[i] * gamma[i] + alpha[i + 1]; if (bga2 == 0.0) { // Value is 'free' delta[i] = delta[i + 1] = 1.0; } else { gamma[i + 1] = (v.doubleValue(i + 1) - beta[i] * delta[i]) / bga2; delta[i + 1] = -1.0 * beta[i + 1] / bga2; gamma[i] = -(alpha[i + 1] * gamma[i + 1] + beta[i + 1]) / beta[i]; delta[i] = beta[i + 1] * delta[i + 1] / beta[i] * gamma[i + 1]; i++; } } } double[] w = new double[n]; final double bga3 = beta[n - 2] * gamma[n - 2] + alpha[n - 1]; if (bga3 == 0.0) { w[n - 1] = 1.0; // value is 'free' } else { w[n - 1] = (v.doubleValue(n - 1) - beta[n - 2] * delta[n - 2]) / bga3; } for (int i = n - 2; i >= 0; i--) { w[i] = gamma[i] * w[i + 1] + delta[i]; } return new RealVector(w); }