annotate 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
rev   line source
samer@0 1 /*
samer@0 2 * Matrix.java
samer@0 3 *
samer@0 4 * Copyright (c) 2000, Samer Abdallah, King's College London.
samer@0 5 * All rights reserved.
samer@0 6 *
samer@0 7 * This software is provided AS iS and WITHOUT ANY WARRANTY;
samer@0 8 * without even the implied warranty of MERCHANTABILITY or
samer@0 9 * FITNESS FOR A PARTICULAR PURPOSE.
samer@0 10 */
samer@0 11
samer@0 12 package samer.maths;
samer@0 13 import samer.core.*;
samer@0 14 import samer.core.util.*;
samer@0 15 import java.util.*;
samer@0 16 import java.io.*;
samer@0 17
samer@0 18 /**
samer@0 19 Represents a bundling of a Jama.Matrix with Viewable bits.
samer@0 20 Create one of these and you can either keep it invisible,
samer@0 21 expose its UI yourself, or let the Viewable framework
samer@0 22 expose a default viewer automatically
samer@0 23 */
samer@0 24
samer@0 25 public class Matrix extends Jama.Matrix implements Mat, Saveable
samer@0 26 {
samer@0 27 Viewable viewable;
samer@0 28
samer@0 29 // ............... Viewable bits .................
samer@0 30
samer@0 31 private class Vbl extends Viewable {
samer@0 32 Vbl(String nm) { super(nm); }
samer@0 33 Vbl() { super("matrix"); }
samer@0 34
samer@0 35 /** returns current Agent if there is one, creates a MatrixAgent if not */
samer@0 36 public Agent getAgent() {
samer@0 37 if (super.getAgent()==null) setAgent(new MatrixAgent(Matrix.this));
samer@0 38 return super.getAgent();
samer@0 39 }
samer@0 40
samer@0 41 public Matrix getMatrix() { return Matrix.this; }
samer@0 42 public Viewer getViewer()
samer@0 43 {
samer@0 44 BaseViewer vwr = new BaseViewer(this);
samer@0 45 StringBuffer buf = new StringBuffer();
samer@0 46
samer@0 47 buf.append(getLabel())
samer@0 48 .append(" (").append(getRowDimension())
samer@0 49 .append(" by ").append(getColumnDimension())
samer@0 50 .append(")");
samer@0 51 vwr.setText(buf.toString());
samer@0 52
samer@0 53 return vwr;
samer@0 54 }
samer@0 55 }
samer@0 56
samer@0 57 public Observable observable() { return viewable; }
samer@0 58 public Viewable viewable() { return viewable; }
samer@0 59 public boolean equals(Observable o) { return viewable==o; }
samer@0 60 public Node getNode() { return viewable.getNode(); }
samer@0 61
samer@0 62 public final void changed(Object o) { viewable.changed(o); }
samer@0 63 public final void changed() { viewable.changed(); }
samer@0 64 public void addObserver(Observer o) { viewable.addObserver(o); }
samer@0 65 public void deleteObserver(Observer o) { viewable.deleteObserver(o); }
samer@0 66 public void dispose() { viewable.dispose(); }
samer@0 67
samer@0 68 public void copyFrom(double[][] src) {
samer@0 69 double[][] dest=getArray();
samer@0 70 for (int i=0; i<src.length; i++) {
samer@0 71 Mathx.copy(src[i],dest[i]);
samer@0 72 changed();
samer@0 73 }
samer@0 74 }
samer@0 75
samer@0 76 // ................................................
samer@0 77
samer@0 78 public Matrix( String name, int m, int n) { this(name,m,n,1); }
samer@0 79 public Matrix( String name, int m, int n, int flags) {
samer@0 80 super(m,n); viewable=new Vbl(name);
samer@0 81 if (flags==1) Shell.registerViewable(viewable);
samer@0 82 }
samer@0 83
samer@0 84
samer@0 85 public Matrix( int m, int n) { super(m,n); viewable=new Vbl(); Shell.registerViewable(viewable); }
samer@0 86 public Matrix( double array[][]) { super(array); viewable=new Vbl(); Shell.registerViewable(viewable); }
samer@0 87
samer@0 88 public String toString() {
samer@0 89 StringBuffer buf = new StringBuffer();
samer@0 90
samer@0 91 buf.append(viewable.getLabel())
samer@0 92 .append(" (").append(getRowDimension())
samer@0 93 .append(" by ").append(getColumnDimension())
samer@0 94 .append(")");
samer@0 95 return buf.toString();
samer@0 96 }
samer@0 97
samer@0 98 // implement Mat interface
samer@0 99 public int width() { return getColumnDimension(); }
samer@0 100 public int height() { return getRowDimension(); }
samer@0 101
samer@0 102 public Agent getAgent() { return viewable.getAgent(); }
samer@0 103
samer@0 104
samer@0 105 // ................................................
samer@0 106 // some useful additions to Matrix functionality
samer@0 107
samer@0 108 public void set( Generator g) {
samer@0 109 for (int i=0; i<m; i++) g.next(A[i]);
samer@0 110 }
samer@0 111
samer@0 112 public void apply( Function f) {
samer@0 113 for (int i=0; i<m; i++) f.apply(A[i]);
samer@0 114 }
samer@0 115
samer@0 116 public void add( Generator g)
samer@0 117 {
samer@0 118 for (int i=0; i<m; i++) {
samer@0 119 for (int j=0; j<n; j++) {
samer@0 120 A[i][j]+=g.next();
samer@0 121 }
samer@0 122 }
samer@0 123 }
samer@0 124
samer@0 125
samer@0 126 /** Set to identity matrix */
samer@0 127
samer@0 128 public void identity()
samer@0 129 {
samer@0 130 for (int i = 0; i < m; i++) {
samer@0 131 for (int j = 0; j < n; j++) {
samer@0 132 A[i][j] = (i == j ? 1.0 : 0.0);
samer@0 133 }
samer@0 134 }
samer@0 135 }
samer@0 136
samer@0 137 public static Jama.Matrix identity(Jama.Matrix a)
samer@0 138 {
samer@0 139 double [][] A=a.getArray();
samer@0 140 int m=a.getRowDimension();
samer@0 141 int n=a.getColumnDimension();
samer@0 142 for (int i = 0; i < m; i++) {
samer@0 143 for (int j = 0; j < n; j++) {
samer@0 144 A[i][j] = (i == j ? 1.0 : 0.0);
samer@0 145 }
samer@0 146 }
samer@0 147 return a;
samer@0 148 }
samer@0 149
samer@0 150 /** Set to zero matrix */
samer@0 151
samer@0 152 public void zero() {
samer@0 153 for (int i = 0; i < m; i++) { Mathx.zero(A[i]); }
samer@0 154 }
samer@0 155
samer@0 156 /** Set to given matrix
samer@0 157 * (need to make sure both matrices are the same size)
samer@0 158 @param b the matrix to be copied
samer@0 159 */
samer@0 160
samer@0 161 public void assign( Jama.Matrix b)
samer@0 162 {
samer@0 163 double[][] B=b.getArray();
samer@0 164 int mmax = B.length>m ? m : B.length;
samer@0 165 int nmax = B[0].length>n ? n : B[0].length;
samer@0 166
samer@0 167 for (int i = 0; i < mmax; i++) {
samer@0 168 System.arraycopy(B[i],0,A[i],0,nmax);
samer@0 169 }
samer@0 170 }
samer@0 171
samer@0 172 // Saveable implementation
samer@0 173
samer@0 174 public void load(InputStream in) throws Exception {
samer@0 175 ObjectInputStream o=new ObjectInputStream(in);
samer@0 176 assign((Jama.Matrix)o.readObject());
samer@0 177 changed();
samer@0 178 }
samer@0 179
samer@0 180 public void save(OutputStream out) throws Exception {
samer@0 181 ObjectOutputStream o=new ObjectOutputStream(out);
samer@0 182 o.writeObject(new Jama.Matrix(getArray()));
samer@0 183 }
samer@0 184
samer@0 185 public void write(Writer wr) throws Exception {
samer@0 186 print(new PrintWriter(wr,true), new DoubleFormat(16),4);
samer@0 187 }
samer@0 188
samer@0 189 public void read(Reader rdr) throws Exception {
samer@0 190 Jama.Matrix A=Jama.Matrix.read(new BufferedReader(rdr));
samer@0 191 assign(A); changed();
samer@0 192 }
samer@0 193
samer@0 194 /** Symmetrise in place preserving trace.
samer@0 195 Will fail if matrix is not square. */
samer@0 196 public void symmetrise()
samer@0 197 {
samer@0 198 double a, _G[][]=getArray();
samer@0 199 for (int i=0; i<n; i++) {
samer@0 200 for (int j=i+1; j<n; j++) {
samer@0 201 a=(_G[i][j]+_G[j][i])/2;
samer@0 202 _G[i][j]=_G[j][i]=a;
samer@0 203 }
samer@0 204 }
samer@0 205 }
samer@0 206
samer@0 207 /** Antisymmetrise in place.
samer@0 208 Will fail if matrix is not square. */
samer@0 209 public void antisymmetrise()
samer@0 210 {
samer@0 211 double a, _G[][]=getArray();
samer@0 212 for (int i=0; i<n; i++) {
samer@0 213 for (int j=i+1; j<n; j++) {
samer@0 214 a=(_G[i][j]-_G[j][i])/2;
samer@0 215 _G[i][j]=a; _G[j][i]=-a;
samer@0 216 }
samer@0 217 _G[i][i]=0;
samer@0 218 }
samer@0 219 }
samer@0 220
samer@0 221 /** return log(abs(det(this))) (must be square matrix) */
samer@0 222
samer@0 223 public double logdet() {
samer@0 224 int n=getRowDimension();
samer@0 225 double [][] x=lu().getU().getArray();
samer@0 226 double L=0;
samer@0 227 for (int i=0; i<n; i++) L+= Math.log(Math.abs(x[i][i]));
samer@0 228 return L;
samer@0 229 }
samer@0 230 // ................................................
samer@0 231
samer@0 232 public Vec getRow(int k) { return new Row(k); }
samer@0 233 public Vec getColumn(int k) { return new Column(k); }
samer@0 234
samer@0 235 public static Vec getDiagonal(final Jama.Matrix A) {
samer@0 236 return new Vec() {
samer@0 237 double[][] x=A.getArray();
samer@0 238
samer@0 239 public int size() { return x.length; }
samer@0 240 public double[] array() { return null; }
samer@0 241 public Mat mat() {
samer@0 242 return new Mat() {
samer@0 243 // Mat implementation
samer@0 244 public int width() { return x.length; }
samer@0 245 public int height() { return 1; }
samer@0 246 public double get( int i, int j) { return x[j][j]; }
samer@0 247 public void set( int i, int j, double t) { x[j][j]=t; }
samer@0 248 };
samer@0 249 }
samer@0 250 public Iterator iterator() {
samer@0 251 return new Iterator() {
samer@0 252 int i=0, n=x.length;
samer@0 253 public void rewind() { i=0; }
samer@0 254 public boolean more() { return i<n; }
samer@0 255 public double next() {
samer@0 256 double y=x[i][i]; i++; return y;
samer@0 257 }
samer@0 258 };
samer@0 259 }
samer@0 260 };
samer@0 261 }
samer@0 262
samer@0 263 private abstract class Slice implements Vec, Vec.Iterator
samer@0 264 {
samer@0 265 protected int i, j, n;
samer@0 266
samer@0 267 Slice(int n, int j) { this.n=n; this.j=j; i=0; }
samer@0 268
samer@0 269 // Vec implementation
samer@0 270 public final Vec.Iterator iterator() { i=0; return this; }
samer@0 271 public final int size() { return n; }
samer@0 272 public final void rewind() { i=0; }
samer@0 273 public final boolean more() { return i<n; }
samer@0 274 }
samer@0 275
samer@0 276 private class Row extends Slice {
samer@0 277 double [] x;
samer@0 278
samer@0 279 public Row(int rownum) {
samer@0 280 super(Matrix.this.getColumnDimension(),rownum);
samer@0 281 x=getArray()[rownum];
samer@0 282 }
samer@0 283
samer@0 284 public final double next() { return x[i++]; }
samer@0 285 public final double[] array() { return x; }
samer@0 286 public final Mat mat() {
samer@0 287 return new Mat() {
samer@0 288 // Mat implementation
samer@0 289 public int width() { return Row.this.n; }
samer@0 290 public int height() { return 1; }
samer@0 291 public double get( int i, int j) { return x[j]; }
samer@0 292 public void set( int i, int j, double t) { x[j]=t; }
samer@0 293 };
samer@0 294 }
samer@0 295 }
samer@0 296
samer@0 297 private class Column extends Slice {
samer@0 298 double [][] x;
samer@0 299 int j;
samer@0 300
samer@0 301 public Column(int colnum) {
samer@0 302 super(Matrix.this.getRowDimension(),colnum);
samer@0 303 x=getArray();
samer@0 304 j=colnum;
samer@0 305 }
samer@0 306
samer@0 307 public final double next() { return x[i++][j]; }
samer@0 308 public final double[] array() { return null; }
samer@0 309 public final Mat mat() {
samer@0 310 return new Mat() {
samer@0 311 public final int width() { return Column.this.n; }
samer@0 312 public final int height() { return 1; }
samer@0 313 public final double get( int i, int k) { return x[k][j]; }
samer@0 314 public final void set( int i, int k, double t) { x[k][j]=t; }
samer@0 315 };
samer@0 316 }
samer@0 317 }
samer@0 318 }