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 }