Package cc.plural.math

Source Code of cc.plural.math.MatrixF

/**
* Copyright (C) 2012 J.W.Marsden <jmarsden@plural.cc>
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package cc.plural.math;

import cc.plural.math.linear.LUDecompositionF;

/**
* Abstract m by n Float Matrix in the following form.
*
* Provides static methods to construct various Matrix instances.
*
* @author j.w.marsden@gmail.com
*/
public abstract class MatrixF extends Matrix {

    /**
     * Constructor for MatrixF. You must promise to set m and n
     */
    public MatrixF() {
    }

    /**
     * Default constructor to specify the dimensions of the m by n MatrixF
     *
     * @param m rows in the MatrixF.
     * @param n columns in the MatrixF.
     */
    public MatrixF(int m, int n) {
        this.m = m;
        this.n = n;
    }

    /**
     * Constructor to create a MatrixF with the given data set.
     *
     * @param data datum for the matrix.
     */
    public MatrixF(Float[][] data) {
        m = data.length;
        n = data[0].length;
        this.setData(data);
    }

    /**
     * Retrieve the data from the MatrixF. This will be unsupported on some
     * implementations.
     *
     * @return Float[][] data from this MatrixF.
     */
    public abstract Float[][] getData();

    public abstract Float getData(int i, int j);

    /**
     * Sets the data into the Matrix. This will be unsupported on some
     * implementations.
     */
    public abstract void setData(Number[][] data);

    public abstract void setData(int i, int j, Number data);

    /**
     * Retrieve the data for a row from the MatrixF.
     *
     * @param i the row to retrieve (0 <= i < m)
     * @return Float[] the row data
     */
    public abstract Float[] getRow(int i);

    /**
     * Retrieve the data for a column from the MatrixF. It is worth noting that
     * this data is never mutable.
     *
     * @param i the row to retrieve (0 <= i < n)
     * @return Float[] the column data
     */
    public Float[] getColumn(int i) {
        if (i >= n) {
            throw new IndexOutOfBoundsException();
        }
        Float[] result = new Float[m];
        for (int j = 0; j < m; j++) {
            result[j] = getData(j, i);
        }
        return result;
    }

    /**
     * Adds a Matrix to this instance. Matrix A + Matrix B = Matrix C.
     *
     * @param b Matrix B.
     * @return Matrix Matrix C.
     */
    public MatrixF add(Matrix b) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                setData(i, j, getData(i, j).floatValue() + b.getData(i, j).floatValue());
            }
        }
        return this;
    }

    public MatrixF add(Matrix b, Matrix c) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                c.setData(i, j, getData(i, j).floatValue() + b.getData(i, j).floatValue());
            }
        }
        return this;
    }

    /**
     * Subtracts a Matrix from this instance. Matrix A - Matrix B = Matrix C.
     *
     * @param b Matrix B.
     * @return Matrix Matrix C.
     */
    public MatrixF subtract(Matrix b) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                setData(i, j, getData(i, j).floatValue() - b.getData(i, j).floatValue());
            }
        }
        return this;
    }

    public MatrixF subtract(Matrix b, Matrix c) {
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                c.setData(i, j, getData(i, j).floatValue() - b.getData(i, j).floatValue());
            }
        }
        return this;
    }

    /**
     * Multiplies a Matrix to this instance. Matrix A * Matrix B = Matrix C.
     *
     * @param b Matrix B.
     * @return Matrix Matrix C.
     */
    public MatrixF multiply(Matrix b) {
        throw new UnsupportedOperationException();
    }

    public MatrixF multiply(Matrix b, Matrix c) {
        throw new UnsupportedOperationException();
    }

    /**
     * Returns the transpose of this instance. Matrix A' = transpose(Matrix A)
     *
     * @return Matrix A' which is a transpose of this instance.
     */
    public abstract MatrixF transpose();

    /**
     * Adds a scalar value to this Matrix instance. Matrix C = C(c[i,j]) =
     * a[i,j]+v
     *
     * @param v Value to add
     * @return Matrix Matrix C
     */
    public abstract MatrixF addScalar(Number v);

    public abstract MatrixF addScalar(Number v, Matrix c);

    /**
     * Adds a scalar value to this Matrix instance. Matrix C = C(c[i,j]) =
     * a[i,j]-v
     *
     * @param v Value to subtract
     * @return Matrix Matrix C
     */
    public abstract MatrixF subtractScalar(Number v);

    public abstract MatrixF subtractScalar(Number v, Matrix c);

    /**
     * Adds a scalar value to this Matrix instance. Matrix C = C(c[i,j]) =
     * a[i,j]*v
     *
     * @param v Value to multiply
     * @return Matrix Matrix C
     */
    public abstract MatrixF multiplyScalar(Number v);

    public abstract MatrixF multiplyScalar(Number v, Matrix c);

    /**
     * Adds a scalar value to this Matrix instance. Matrix C = C(c[i,j]) =
     * a[i,j]/v
     *
     * @param v Value to divide
     * @return Matrix Matrix C
     */
    public abstract MatrixF divideScalar(Number v);

    public abstract MatrixF divideScalar(Number v, Matrix c);

    public abstract VectorF transformVector(VectorF v);

    /**
     * Return the invert of the Matrix A.
     *
     * @return Matrix A^-1
     */
    public abstract MatrixF invert();

    /**
     * Matrix Solver in the form A*X=B where A is this Matrix and X is the
     * solutions.
     *
     * @param b Matrix B
     * @return Solution Matrix X
     */
    public MatrixF solve(Matrix b) {
        if (m != n || b.getM() != n || b.getN() != 1) {
            throw new RuntimeException("Incorrect matrix dimensions.");
        }
        for (int i = 0; i < n; i++) {
            int max = i;
            for (int j = i + 1; j < n; j++) {
                if (Math.abs(getData(j, i)) > Math.abs(getData(max, i))) {
                    max = j;
                }
            }
            /**
             * Swap i and max
             */
            float tmp;
            for (int j = 0; j < n; j++) {
                tmp = getData(i, j).floatValue();
                setData(i, j, getData(max, j));
                setData(max, j, tmp);
            }
            for (int j = 0; j < b.getN(); j++) {
                tmp = b.getData(i, j).floatValue();
                b.setData(i, j, b.getData(max, j));
                b.setData(max, j, tmp);
            }
            /**
             * Check Singular
             */
            if (getData(i, i) == 0) {
                throw new RuntimeException("Matrix is singular.");
            }
            /**
             * Pivot B
             */
            for (int j = i + 1; j < n; j++) {
                b.setData(j, 0, (b.getData(j, 0).floatValue() - (b.getData(i, 0).floatValue() * getData(j, i).floatValue() / getData(i, i).floatValue())));
            }
            /**
             * Pivot A
             */
            for (int j = i + 1; j < n; j++) {
                float f = getData(j, i) / getData(i, i);
                for (int k = i + 1; k < n; k++) {
                    setData(j, k, (getData(j, k) - getData(i, k) * f));
                }
                setData(j, i, 0);
            }
        }
        MatrixF x = MatrixF.empty(n, 1);
        for (int j = n - 1; j >= 0; j--) {
            double v = 0;
            for (int k = j + 1; k < n; k++) {
                v += getData(j, k).floatValue() * x.getData(k, 0).floatValue();
            }
            x.setData(j, 0, ((b.getData(j, 0).floatValue() - v) / getData(j, j).floatValue()));
        }
        return x;
    }

    @Override
    public Matrix solve(Matrix b, Matrix c) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * Calculates the determinant of the MatrixF if it is square (n=m).
     * Currently this handles cases where n < 3 internally and uses
     * LUDecompositionF for larger instances. @return double detminant of the
     * MatrixF.
     */
    public Float determinant() {
        if (n != m) {
            throw new RuntimeException("Not a square matrix.");
        }
        Float[][] data = getData();
        if (n == 1) {
            return data[0][0];
        } else if (n == 2) {
            return data[0][0] * data[1][1]
                    - data[0][1] * data[1][0];
        } else if (n == 3) {
            return data[0][0] * data[1][1] * data[2][2]
                    + data[0][1] * data[1][2] * data[2][0]
                    + data[0][2] * data[1][0] * data[2][1]
                    - data[0][0] * data[1][2] * data[2][1]
                    - data[0][1] * data[1][0] * data[2][2]
                    - data[0][2] * data[1][1] * data[2][0];
        } else {
            return (new LUDecompositionF(this)).determinant();
        }
    }

    @Override
    public Number determinant(Number r) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Matrix getSubMatrix(int mi, int mj, int ni, int nj) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Matrix getSubMatrix(int mi, int mj, int ni, int nj, Matrix r) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    /**
     * Convert the MatrixF to a String
     *
     * @return String MatrixF as String
     */
    @Override
    public String toString() {
        String dataString = "{";
        for (int i = 0; i < m; i++) {
            dataString += "{";
            for (int j = 0; j < n; j++) {
                dataString += getData(i, j) + ((j < n - 1) ? "F," : "F");
            }
            dataString += "}" + ((i < m - 1) ? "," : "");
        }
        dataString += "}";
        return String.format("%s %s", super.toString(), dataString);
    }

    public static MatrixF empty(int n, int i) {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
TOP

Related Classes of cc.plural.math.MatrixF

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.