public static <N extends Number> SparseMatrix<N> fromFile(File file, Vectors.Factory<N> using) throws IOException, VectorFormatException { final BufferedReader in = new BufferedReader(new FileReader(file)); String s; final int m = Integer.parseInt(in.readLine()); final int n = Integer.parseInt(in.readLine()); @SuppressWarnings("unchecked") final Vector<N>[] vectors = (Vector<N>[]) new Vector<?>[m]; int idx = 0; while ((s = in.readLine()) != null) { if (idx >= m) { throw new VectorFormatException("Too many lines"); } vectors[idx++] = using.fromString(s, n); } return new SparseMatrix<N>(n, vectors, using); }
@Override public <M extends Number, O extends Number> Vector<O> mult(Vector<M> x, Vectors.Factory<O> using) { assert (x.length() == n); double[] product = new double[m]; if (x instanceof RealVector) { final double[] x2 = ((RealVector) x).data(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { product[i] += data[i][j] * x2[j]; } } } else if (x instanceof IntVector) { final int[] x2 = ((IntVector) x).data(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { product[i] += data[i][j] * x2[j]; } } } else { for (int i = 0; i < m; i++) { for (Map.Entry<Integer, M> e : x.entrySet()) { product[i] += data[i][e.getKey()] * e.getValue().doubleValue(); } } } return using.make(product); }
return new Solution(new TridiagonalMatrix(new double[0], new double[0]), new double[0][0], 0.0); } else if (n == 1) { final Vector<Double> unitVector = Vectors.AS_REALS.make(new double[]{1.0}); final double a11 = A.apply(unitVector).doubleValue(0); return new Solution(new TridiagonalMatrix(new double[]{a11}, new double[0]), new double[][]{{1}}, 0.0); } else if (n == 2) { final Vector<Double> unit1Vector = Vectors.AS_REALS.make(new double[]{1.0, 0.0}); final Vector<Double> unit2Vector = Vectors.AS_REALS.make(new double[]{0.0, 1.0}); final double[] a1 = A.apply(unit1Vector).toDoubleArray(); final double[] a2 = A.apply(unit2Vector).toDoubleArray();
@Override public <M extends Number> Vector<Integer> multTransposed(Vector<M> x) { assert (x.length() == m); double[] product = new double[n]; if (x instanceof RealVector) { final double[] x2 = ((RealVector) x).data(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { product[i] += data[j][i] * x2[j]; } } } else if (x instanceof IntVector) { final int[] x2 = ((IntVector) x).data(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { product[i] += data[j][i] * x2[j]; } } } else { for (int i = 0; i < n; i++) { for (Map.Entry<Integer, M> e : x.entrySet()) { product[i] += data[e.getKey()][i] * e.getValue().doubleValue(); } } } return Vectors.AS_INTS.make(product); }
@Override public <M extends Number, O extends Number> Vector<O> mult(Vector<M> x, Vectors.Factory<O> using) { assert (x.length() == n); double[] product = new double[m]; if (x instanceof RealVector) { final double[] x2 = ((RealVector) x).data(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { product[i] += data[i][j] * x2[j]; } } } else if (x instanceof IntVector) { final int[] x2 = ((IntVector) x).data(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { product[i] += data[i][j] * x2[j]; } } } else { for (int i = 0; i < m; i++) { for (Map.Entry<Integer, M> e : x.entrySet()) { product[i] += data[i][e.getKey()] * e.getValue().doubleValue(); } } } return using.make(product); }
@Override public <M extends Number> void sub(Matrix<M> matrix) { assert (m == matrix.rows()); assert (n == matrix.cols()); if (matrix instanceof SparseMatrix) { final Vector<M>[] arr2 = ((SparseMatrix<M>) matrix).arr; for (int i = 0; i < m; i++) { if (arr[i] != null && arr2 != null) { arr[i].sub(arr2[i]); } else if (arr2 != null) { arr[i] = using.make(n, defaultValue); arr[i].sub(arr2[i]); } } } else { for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { row(i).sub(j, matrix.doubleValue(i, j)); } } } }
/** * Generate the transpose of this matrix * * @param using {@link AS_INT_ARRAY} or {@link AS_REAL_ARRAY} as appropriate * @return The transposed matrix */ @Override public SparseMatrix<N> transpose() { final SparseMatrix<N> t = new SparseMatrix<N>(n, m, defaultValue, using); for (int i = 0; i < m; i++) { if (arr[i] != null) { for (Map.Entry<Integer, N> e : arr[i].entrySet()) { final int j = e.getKey(); if (t.arr[j] == null) { t.arr[j] = using.make(m, defaultValue); } t.arr[j].put(i, e.getValue()); } } } return t; }
public static Vector<Double> randomUnit(int n) { double[] w = new double[n]; // w is a random vector with 2-norm = 1 for (int i = 0; i < n; i++) { w[i] = random.nextDouble(); } double w2sum = 0.0; for (int i = 0; i < n; i++) { w2sum += w[i] * w[i]; } w2sum = Math.sqrt(w2sum); if (w2sum == 0.0) { return randomUnit(n); } for (int i = 0; i < n; i++) { w[i] = w[i] / w2sum; } return Vectors.AS_REALS.make(w); }
@Override public <M extends Number> void add(Matrix<M> matrix) { assert (m == matrix.rows()); assert (n == matrix.cols()); if (matrix instanceof SparseMatrix) { final Vector<M>[] arr2 = ((SparseMatrix<M>) matrix).arr; for (int i = 0; i < m; i++) { if (arr[i] != null && arr2 != null) { arr[i].add(arr2[i]); } else if (arr2 != null) { arr[i] = using.make(n, defaultValue); arr[i].add(arr2[i]); } } } else { for (int i = 0; i < m; i++) { for (int j = 0; j < m; j++) { row(i).add(j, matrix.doubleValue(i, j)); } } } }
@Override public <M extends Number> Matrix<N> product(Matrix<M> B) { if (this.cols() != B.rows()) { throw new IllegalArgumentException("Matrix dimensions not suitable for product"); } if (defaultValue != 0.0 || (B instanceof SparseMatrix && ((SparseMatrix) B).defaultValue != 0.0)) { throw new UnsupportedOperationException(); } Vector<N>[] res = new Vector[this.rows()]; for (int i = 0; i < this.rows(); i++) { res[i] = using.make(B.cols(), 0.0); for (int j : this.arr[i].keySet()) { final Vector<M> r = B.row(j); for (int k : r.keySet()) { res[i].add(k, this.arr[i].doubleValue(j) * B.doubleValue(j, k)); } } } return new SparseMatrix<N>(this.rows(), res, using); }
@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; }
public void toFile(File file) throws IOException { final PrintWriter out = new PrintWriter(file); out.println(m); out.println(n); for (int i = 0; i < m; i++) { if (arr[i] == null) { out.println(using.make(n, defaultValue).toString()); } else { out.println(arr[i].toString()); } } out.flush(); out.close(); }
@Override public void add(int i, int j, int v) { if (arr[i] == null) { arr[i] = using.make(n, defaultValue); arr[i].put(j, using.valueOf(v + defaultValue)); } else { arr[i].put(j, arr[i].value(j).intValue() + v); } }
@Override public void add(int i, int j, double v) { if (arr[i] == null) { arr[i] = using.make(n, defaultValue); arr[i].put(j, using.valueOf(v + defaultValue)); } else { arr[i].put(j, arr[i].value(j).doubleValue() + v); } }
@Override public void add(int i, int j, N v) { if (arr[i] == null) { arr[i] = using.make(n, defaultValue); arr[i].put(j, v.doubleValue() + defaultValue); } else { arr[i].put(j, arr[i].value(j).doubleValue() + v.doubleValue()); } }
@Override public void set(int i, int j, N v) { if (arr[i] == null) { arr[i] = using.make(n, defaultValue); } arr[i].put(j, v); }
@Override public void set(int i, int j, int v) { if (arr[i] == null) { arr[i] = using.make(n, defaultValue); } arr[i].put(j, using.valueOf(v)); }
/** * Get the nth row. * * @param idx The row to get */ public Vector<N> row(int idx) { if (arr[idx] != null) { return arr[idx]; } else { return arr[idx] = using.make(n, defaultValue); } }