001 package com.croftsoft.apps.insight;
002
003 import java.awt.Point;
004
005 public class Matrix {
006 //////////////////////////////////////////////////////////////////////
007 // Matrix.java v0.0 (C) Copyright 1996 David Wallace Croft.
008 // 1996-08-24
009 //////////////////////////////////////////////////////////////////////
010
011 int rows;
012 int columns;
013 double [ ] [ ] data;
014
015 public Matrix ( int rows, int columns ) {
016 //////////////////////////////////////////////////////////////////////
017 // Constructor method
018 //////////////////////////////////////////////////////////////////////
019 this.rows = rows;
020 this.columns = columns;
021 this.data = new double [ rows ] [ columns ];
022 }
023
024 public Matrix ( Matrix old ) {
025 //////////////////////////////////////////////////////////////////////
026 // Constructor method
027 //////////////////////////////////////////////////////////////////////
028 this ( old.rows, old.columns );
029 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
030 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
031 this.data [ index_row ] [ index_col ]
032 = old.data [ index_row ] [ index_col ];
033 }
034 }
035 }
036
037 //////////////////////////////////////////////////////////////////////
038 //////////////////////////////////////////////////////////////////////
039
040 public Matrix add ( double addend ) {
041 //////////////////////////////////////////////////////////////////////
042 Matrix new_Matrix = new Matrix ( this );
043 //////////////////////////////////////////////////////////////////////
044 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
045 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
046 new_Matrix.data [ index_row ] [ index_col ] += addend;
047 }
048 }
049 return new_Matrix;
050 }
051
052 public Matrix add ( Matrix addend ) {
053 //////////////////////////////////////////////////////////////////////
054 if ( ( this.rows != addend.rows )
055 || ( this.columns != addend.columns ) ) {
056 throw new ArrayIndexOutOfBoundsException (
057 "Matrix.add ( Matrix ): columns and rows not equal" );
058 }
059 Matrix new_Matrix = new Matrix ( this );
060 //////////////////////////////////////////////////////////////////////
061 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
062 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
063 new_Matrix.data [ index_row ] [ index_col ]
064 += addend.data [ index_row ] [ index_col ];
065 }
066 }
067 return new_Matrix;
068 }
069
070 public double [ ] array_column ( int column ) {
071 //////////////////////////////////////////////////////////////////////
072 double [ ] arr_col = new double [ this.rows ];
073 //////////////////////////////////////////////////////////////////////
074 for ( int index_row = 0; index_row < this.rows; index_row++ ) {
075 arr_col [ index_row ] = this.data [ index_row ] [ column ];
076 }
077 return arr_col;
078 }
079
080 public Matrix clip ( double min, double max ) {
081 //////////////////////////////////////////////////////////////////////
082 Matrix new_Matrix = new Matrix ( this );
083 //////////////////////////////////////////////////////////////////////
084 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
085 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
086 if ( this.data [ index_row ] [ index_col ] < min )
087 new_Matrix.data [ index_row ] [ index_col ] = min;
088 else if ( this.data [ index_row ] [ index_col ] > max )
089 new_Matrix.data [ index_row ] [ index_col ] = max;
090 }
091 }
092 return new_Matrix;
093 }
094
095 static public void demo ( ) {
096 //////////////////////////////////////////////////////////////////////
097 Matrix left = new Matrix ( 2, 3 );
098 Matrix right = new Matrix ( 3, 4 );
099 for ( int index_row = 0; index_row < left.rows; index_row++ ) {
100 for ( int index_col = 0; index_col < left.columns; index_col++ ) {
101 left.data [ index_row ] [ index_col ] = index_row + index_col;
102 }
103 }
104 for ( int index_row = 0; index_row < right.rows; index_row++ ) {
105 for ( int index_col = 0; index_col < right.columns; index_col++ ) {
106 right.data [ index_row ] [ index_col ] = index_row + index_col;
107 }
108 }
109 left.display ( );
110 System.out.println ( "" );
111 right.display ( );
112 System.out.println ( "" );
113 Matrix product = multiply ( left, right );
114 product.display ( );
115 System.out.println ( "" );
116 Matrix transposed = product.transpose ( );
117 transposed.display ( );
118 System.out.println ( "" );
119 Matrix sigmoided = transposed.sigmoid ( );
120 sigmoided.display ( );
121 }
122
123 public void display ( ) {
124 //////////////////////////////////////////////////////////////////////
125 String line_String;
126 //////////////////////////////////////////////////////////////////////
127 for ( int index_row = 0; index_row < this.rows; index_row++ ) {
128 line_String = "";
129 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
130 line_String += this.data [ index_row ] [ index_col ] + " ";
131 }
132 System.out.println ( line_String );
133 }
134 }
135
136 public Matrix divide ( double factor ) {
137 //////////////////////////////////////////////////////////////////////
138 Matrix new_Matrix = new Matrix ( this );
139 //////////////////////////////////////////////////////////////////////
140 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
141 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
142 new_Matrix.data [ index_row ] [ index_col ] /= factor;
143 }
144 }
145 return new_Matrix;
146 }
147
148 static public Matrix identity ( Matrix old ) {
149 //////////////////////////////////////////////////////////////////////
150 Matrix new_Matrix = new Matrix ( old.rows, old.columns );
151 //////////////////////////////////////////////////////////////////////
152 for ( int index_row = 0; index_row < old.rows ; index_row++ ) {
153 for ( int index_col = 0; index_col < old.columns; index_col++ ) {
154 new_Matrix.data [ index_row ] [ index_col ] = 1.0;
155 }
156 }
157 return new_Matrix;
158 }
159
160 public Point max_indices ( ) {
161 //////////////////////////////////////////////////////////////////////
162 int max_row = 0;
163 int max_col = 0;
164 //////////////////////////////////////////////////////////////////////
165 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
166 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
167 if ( this.data [ index_row ] [ index_col ]
168 > this.data [ max_row ] [ max_col ] ) {
169 max_row = index_row;
170 max_col = index_col;
171 }
172 }
173 }
174 return new Point ( max_row, max_col );
175 }
176
177 public Matrix multiply ( double factor ) {
178 //////////////////////////////////////////////////////////////////////
179 Matrix new_Matrix = new Matrix ( this );
180 //////////////////////////////////////////////////////////////////////
181 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
182 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
183 new_Matrix.data [ index_row ] [ index_col ] *= factor;
184 }
185 }
186 return new_Matrix;
187 }
188
189 public Matrix multiply ( Matrix right ) {
190 //////////////////////////////////////////////////////////////////////
191 return multiply ( this, right );
192 }
193
194 static public Matrix multiply ( Matrix left, Matrix right ) {
195 //////////////////////////////////////////////////////////////////////
196 if ( left.columns != right.rows ) {
197 throw new ArrayIndexOutOfBoundsException (
198 "Matrix.multiply: left.columns != right.rows" );
199 }
200 Matrix product = new Matrix ( left.rows, right.columns );
201 //////////////////////////////////////////////////////////////////////
202 for ( int index_row = 0; index_row < product.rows; index_row++ ) {
203 for ( int index_col = 0; index_col < product.columns; index_col++ ) {
204 product.data [ index_row ] [ index_col ] = 0.0;
205 for ( int index = 0; index < left.columns; index++ ) {
206 product.data [ index_row ] [ index_col ]
207 += left.data [ index_row ] [ index ]
208 * right.data [ index ] [ index_col ];
209 }
210 }
211 }
212 return product;
213 }
214
215 static public Matrix multiply_elements ( Matrix a, Matrix b ) {
216 //////////////////////////////////////////////////////////////////////
217 if ( ( a.rows != b.rows ) || ( a.columns != b.columns ) ) {
218 throw new ArrayIndexOutOfBoundsException (
219 "Matrix.multiply_pairwise: rows or columns not equal" );
220 }
221 Matrix product = new Matrix ( a.rows, a.columns );
222 //////////////////////////////////////////////////////////////////////
223 for ( int index_row = 0; index_row < a.rows ; index_row++ ) {
224 for ( int index_col = 0; index_col < a.columns; index_col++ ) {
225 product.data [ index_row ] [ index_col ]
226 = a.data [ index_row ] [ index_col ]
227 * b.data [ index_row ] [ index_col ];
228 }
229 }
230 return product;
231 }
232
233 public Matrix randomize_uniform ( double min, double max ) {
234 //////////////////////////////////////////////////////////////////////
235 Matrix new_Matrix = new Matrix ( this.rows, this.columns );
236 //////////////////////////////////////////////////////////////////////
237 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
238 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
239 new_Matrix.data [ index_row ] [ index_col ]
240 = Croft_Random.uniform ( min, max );
241 }
242 }
243 return new_Matrix;
244 }
245
246 public Matrix sigmoid ( ) {
247 //////////////////////////////////////////////////////////////////////
248 Matrix new_Matrix = new Matrix ( this.rows, this.columns );
249 //////////////////////////////////////////////////////////////////////
250 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
251 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
252 new_Matrix.data [ index_row ] [ index_col ]
253 = Croft_Math.sigmoid ( this.data [ index_row ] [ index_col ] );
254 }
255 }
256 return new_Matrix;
257 }
258
259 public Matrix sigmoid_derivative ( ) {
260 //////////////////////////////////////////////////////////////////////
261 Matrix new_Matrix = new Matrix ( this.rows, this.columns );
262 //////////////////////////////////////////////////////////////////////
263 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
264 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
265 new_Matrix.data [ index_row ] [ index_col ]
266 = Croft_Math.sigmoid_derivative
267 ( this.data [ index_row ] [ index_col ] );
268 }
269 }
270 return new_Matrix;
271 }
272
273 public Matrix square_elements ( ) {
274 //////////////////////////////////////////////////////////////////////
275 Matrix new_Matrix = new Matrix ( this.rows, this.columns );
276 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
277 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
278 new_Matrix.data [ index_row ] [ index_col ]
279 = this.data [ index_row ] [ index_col ]
280 * this.data [ index_row ] [ index_col ];
281 }
282 }
283 return new_Matrix;
284 }
285
286 public Matrix sub_matrix (
287 int row_start, int row_end,
288 int col_start, int col_end ) {
289 //////////////////////////////////////////////////////////////////////
290 // Note that the first row is row 0.
291 //////////////////////////////////////////////////////////////////////
292 Matrix sub
293 = new Matrix ( row_end - row_start + 1, col_end - col_start + 1 );
294 //////////////////////////////////////////////////////////////////////
295 for ( int index_row = 0; index_row < sub.rows ; index_row++ ) {
296 for ( int index_col = 0; index_col < sub.columns; index_col++ ) {
297 sub.data [ index_row ] [ index_col ]
298 = this.data [ index_row + row_start ] [ index_col + col_start ];
299 }
300 }
301 return sub;
302 }
303
304 public Matrix subtract ( Matrix subtractor ) {
305 //////////////////////////////////////////////////////////////////////
306 if ( ( this.rows != subtractor.rows )
307 || ( this.columns != subtractor.columns ) ) {
308 throw new ArrayIndexOutOfBoundsException (
309 "Matrix.subtract ( Matrix ): columns and rows not equal" );
310 }
311 Matrix new_Matrix = new Matrix ( this );
312 //////////////////////////////////////////////////////////////////////
313 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
314 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
315 new_Matrix.data [ index_row ] [ index_col ]
316 -= subtractor.data [ index_row ] [ index_col ];
317 }
318 }
319 return new_Matrix;
320 }
321
322 public double sum ( ) {
323 //////////////////////////////////////////////////////////////////////
324 double temp = 0.0;
325 //////////////////////////////////////////////////////////////////////
326 for ( int index_row = 0; index_row < this.rows ; index_row++ ) {
327 for ( int index_col = 0; index_col < this.columns; index_col++ ) {
328 temp += this.data [ index_row ] [ index_col ];
329 }
330 }
331 return temp;
332 }
333
334 public Matrix transpose ( ) {
335 //////////////////////////////////////////////////////////////////////
336 Matrix transposed = new Matrix ( this.columns, this.rows );
337 //////////////////////////////////////////////////////////////////////
338 for ( int index_row = 0;
339 index_row < transposed.rows;
340 index_row++ ) {
341 for ( int index_col = 0;
342 index_col < transposed.columns;
343 index_col++ ) {
344 transposed.data [ index_row ] [ index_col ]
345 = this.data [ index_col ] [ index_row ];
346 }
347 }
348 return transposed;
349 }
350
351 //////////////////////////////////////////////////////////////////////
352 //////////////////////////////////////////////////////////////////////
353 }