/* * WrappedMatrix.java * * Copyright (c) 2002-2017 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.math.matrixAlgebra; import java.util.Arrays; /** * Created by msuchard on 1/27/17. */ public interface WrappedMatrix { double get(final int i); void set(final int i, final double x); double get(final int i, final int j); void set(final int i, final int j, final double x); int getMajorDim(); int getMinorDim(); double[] getBuffer(); int getOffset(); double[] data = null; abstract class Abstract implements WrappedMatrix { final protected double[] buffer; final protected int offset; final protected int dimMajor; final protected int dimMinor; public Abstract(final double[] buffer, final int offset, final int dimMajor, final int dimMinor) { this.buffer = buffer; this.offset = offset; this.dimMajor = dimMajor; this.dimMinor = dimMinor; } final public double[] getBuffer() { return buffer; } final public int getOffset() { return offset; } final public int getMajorDim() { return dimMajor; } final public int getMinorDim() { return dimMinor; } final public String toString() { StringBuilder sb = new StringBuilder("[ "); // TODO // if (dim > 0) { // sb.append(get(0)); // } // for (int i = 1; i < dim; ++i) { // sb.append(", ").append(get(i)); // } // sb.append(" ]"); return sb.toString(); } } final class Raw extends Abstract { public Raw(double[] buffer, int offset, int dimMajor, int dimMinor) { super(buffer, offset, dimMajor, dimMinor); } @Override final public double get(final int i) { return buffer[offset + i]; } @Override final public void set(final int i, final double x) { buffer[offset + i] = x; } @Override final public double get(final int i, final int j) { return buffer[offset + i * dimMajor + j]; } @Override final public void set(final int i, final int j, final double x) { buffer[offset + i * dimMajor + j] = x; } } final class Indexed extends Abstract { final private int[] indicesMajor; final private int[] indicesMinor; public Indexed(double[] buffer, int offset, int[] indicesMajor, int[] indicesMinor, int dimMajor, int dimMinor) { super(buffer, offset, dimMajor, dimMinor); this.indicesMajor = indicesMajor; this.indicesMinor = indicesMinor; } @Override final public double get(int i, int j) { return buffer[getIndex(i, j)]; } @Override final public void set(int i, int j, double x) { buffer[getIndex(i, j)] = x; } @Override final public double get(int i) { throw new RuntimeException("Not yet implemented"); } @Override final public void set(int i, double x) { throw new RuntimeException("Not yet implemented"); } private final int getIndex(final int i, final int j) { return offset + indicesMajor[i] * dimMajor + indicesMinor[j]; } } final class Utils { public static void gatherRowsAndColumns(final WrappedMatrix source, final WrappedMatrix destination, final int[] rowIndices, final int[] colIndices) { final int rowLength = rowIndices.length; final int colLength = colIndices.length; for (int i = 0; i < rowLength; ++i) { final int rowIndex = rowIndices[i]; for (int j = 0; j < colLength; ++j) { destination.set(i, j, source.get(rowIndex, colIndices[j]) ); } } } public static void scatterRowsAndColumns(final WrappedMatrix source, final WrappedMatrix destination, final int[] rowIndices, final int[] colIndices) { scatterRowsAndColumns(source, destination, rowIndices, colIndices, true); } public static void scatterRowsAndColumns(final WrappedMatrix source, final WrappedMatrix destination, final int[] rowIndices, final int[] colIndices, final boolean clear) { if (clear) { double[] data = destination.getBuffer(); final int start = destination.getOffset(); final int end = start + destination.getMajorDim() * destination.getMinorDim(); Arrays.fill(data, start, end, 0.0); } final int rowLength = rowIndices.length; final int colLength = colIndices.length; for (int i = 0; i < rowLength; ++i) { final int rowIndex = rowIndices[i]; for (int j = 0; j < colLength; ++j) { destination.set(rowIndex, colIndices[i], source.get(i, j)); } } } } }