Mercurial > hg > jslab
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 } |