comparison src/samer/maths/Matrix.java @ 0:bf79fb79ee13

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