Mercurial > hg > jslab
view src/samer/maths/Matrix.java @ 8:5e3cbbf173aa tip
Reorganise some more
author | samer |
---|---|
date | Fri, 05 Apr 2019 22:41:58 +0100 |
parents | bf79fb79ee13 |
children |
line wrap: on
line source
/* * Matrix.java * * Copyright (c) 2000, Samer Abdallah, King's College London. * All rights reserved. * * This software is provided AS iS and WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. */ package samer.maths; import samer.core.*; import samer.core.util.*; import java.util.*; import java.io.*; /** Represents a bundling of a Jama.Matrix with Viewable bits. Create one of these and you can either keep it invisible, expose its UI yourself, or let the Viewable framework expose a default viewer automatically */ public class Matrix extends Jama.Matrix implements Mat, Saveable { Viewable viewable; // ............... Viewable bits ................. private class Vbl extends Viewable { Vbl(String nm) { super(nm); } Vbl() { super("matrix"); } /** returns current Agent if there is one, creates a MatrixAgent if not */ public Agent getAgent() { if (super.getAgent()==null) setAgent(new MatrixAgent(Matrix.this)); return super.getAgent(); } public Matrix getMatrix() { return Matrix.this; } public Viewer getViewer() { BaseViewer vwr = new BaseViewer(this); StringBuffer buf = new StringBuffer(); buf.append(getLabel()) .append(" (").append(getRowDimension()) .append(" by ").append(getColumnDimension()) .append(")"); vwr.setText(buf.toString()); return vwr; } } public Observable observable() { return viewable; } public Viewable viewable() { return viewable; } public boolean equals(Observable o) { return viewable==o; } public Node getNode() { return viewable.getNode(); } public final void changed(Object o) { viewable.changed(o); } public final void changed() { viewable.changed(); } public void addObserver(Observer o) { viewable.addObserver(o); } public void deleteObserver(Observer o) { viewable.deleteObserver(o); } public void dispose() { viewable.dispose(); } public void copyFrom(double[][] src) { double[][] dest=getArray(); for (int i=0; i<src.length; i++) { Mathx.copy(src[i],dest[i]); changed(); } } // ................................................ public Matrix( String name, int m, int n) { this(name,m,n,1); } public Matrix( String name, int m, int n, int flags) { super(m,n); viewable=new Vbl(name); if (flags==1) Shell.registerViewable(viewable); } public Matrix( int m, int n) { super(m,n); viewable=new Vbl(); Shell.registerViewable(viewable); } public Matrix( double array[][]) { super(array); viewable=new Vbl(); Shell.registerViewable(viewable); } public String toString() { StringBuffer buf = new StringBuffer(); buf.append(viewable.getLabel()) .append(" (").append(getRowDimension()) .append(" by ").append(getColumnDimension()) .append(")"); return buf.toString(); } // implement Mat interface public int width() { return getColumnDimension(); } public int height() { return getRowDimension(); } public Agent getAgent() { return viewable.getAgent(); } // ................................................ // some useful additions to Matrix functionality public void set( Generator g) { for (int i=0; i<m; i++) g.next(A[i]); } public void apply( Function f) { for (int i=0; i<m; i++) f.apply(A[i]); } public void add( Generator g) { for (int i=0; i<m; i++) { for (int j=0; j<n; j++) { A[i][j]+=g.next(); } } } /** Set to identity matrix */ public void identity() { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { A[i][j] = (i == j ? 1.0 : 0.0); } } } public static Jama.Matrix identity(Jama.Matrix a) { double [][] A=a.getArray(); int m=a.getRowDimension(); int n=a.getColumnDimension(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { A[i][j] = (i == j ? 1.0 : 0.0); } } return a; } /** Set to zero matrix */ public void zero() { for (int i = 0; i < m; i++) { Mathx.zero(A[i]); } } /** Set to given matrix * (need to make sure both matrices are the same size) @param b the matrix to be copied */ public void assign( Jama.Matrix b) { double[][] B=b.getArray(); int mmax = B.length>m ? m : B.length; int nmax = B[0].length>n ? n : B[0].length; for (int i = 0; i < mmax; i++) { System.arraycopy(B[i],0,A[i],0,nmax); } } // Saveable implementation public void load(InputStream in) throws Exception { ObjectInputStream o=new ObjectInputStream(in); assign((Jama.Matrix)o.readObject()); changed(); } public void save(OutputStream out) throws Exception { ObjectOutputStream o=new ObjectOutputStream(out); o.writeObject(new Jama.Matrix(getArray())); } public void write(Writer wr) throws Exception { print(new PrintWriter(wr,true), new DoubleFormat(16),4); } public void read(Reader rdr) throws Exception { Jama.Matrix A=Jama.Matrix.read(new BufferedReader(rdr)); assign(A); changed(); } /** Symmetrise in place preserving trace. Will fail if matrix is not square. */ public void symmetrise() { double a, _G[][]=getArray(); for (int i=0; i<n; i++) { for (int j=i+1; j<n; j++) { a=(_G[i][j]+_G[j][i])/2; _G[i][j]=_G[j][i]=a; } } } /** Antisymmetrise in place. Will fail if matrix is not square. */ public void antisymmetrise() { double a, _G[][]=getArray(); for (int i=0; i<n; i++) { for (int j=i+1; j<n; j++) { a=(_G[i][j]-_G[j][i])/2; _G[i][j]=a; _G[j][i]=-a; } _G[i][i]=0; } } /** return log(abs(det(this))) (must be square matrix) */ public double logdet() { int n=getRowDimension(); double [][] x=lu().getU().getArray(); double L=0; for (int i=0; i<n; i++) L+= Math.log(Math.abs(x[i][i])); return L; } // ................................................ public Vec getRow(int k) { return new Row(k); } public Vec getColumn(int k) { return new Column(k); } public static Vec getDiagonal(final Jama.Matrix A) { return new Vec() { double[][] x=A.getArray(); public int size() { return x.length; } public double[] array() { return null; } public Mat mat() { return new Mat() { // Mat implementation public int width() { return x.length; } public int height() { return 1; } public double get( int i, int j) { return x[j][j]; } public void set( int i, int j, double t) { x[j][j]=t; } }; } public Iterator iterator() { return new Iterator() { int i=0, n=x.length; public void rewind() { i=0; } public boolean more() { return i<n; } public double next() { double y=x[i][i]; i++; return y; } }; } }; } private abstract class Slice implements Vec, Vec.Iterator { protected int i, j, n; Slice(int n, int j) { this.n=n; this.j=j; i=0; } // Vec implementation public final Vec.Iterator iterator() { i=0; return this; } public final int size() { return n; } public final void rewind() { i=0; } public final boolean more() { return i<n; } } private class Row extends Slice { double [] x; public Row(int rownum) { super(Matrix.this.getColumnDimension(),rownum); x=getArray()[rownum]; } public final double next() { return x[i++]; } public final double[] array() { return x; } public final Mat mat() { return new Mat() { // Mat implementation public int width() { return Row.this.n; } public int height() { return 1; } public double get( int i, int j) { return x[j]; } public void set( int i, int j, double t) { x[j]=t; } }; } } private class Column extends Slice { double [][] x; int j; public Column(int colnum) { super(Matrix.this.getRowDimension(),colnum); x=getArray(); j=colnum; } public final double next() { return x[i++][j]; } public final double[] array() { return null; } public final Mat mat() { return new Mat() { public final int width() { return Column.this.n; } public final int height() { return 1; } public final double get( int i, int k) { return x[k][j]; } public final void set( int i, int k, double t) { x[k][j]=t; } }; } } }