Commit | Line | Data |
---|---|---|
7824a618 H |
1 | import java.util.Random; |
2 | import java.text.NumberFormat; | |
3 | import java.lang.Math; | |
4 | import java.io.*; | |
5 | ||
6 | /** Class representing matrix with methods for matrix algebra | |
7 | * Copylefted by: Harvie 2oo9 ( http://blog.harvie.cz/ ) | |
8 | * @author Thomas Harvie Mudrunka (mudruto1) | |
9 | * @version 1.0 | |
10 | */ | |
11 | ||
12 | class Matrix implements Serializable { | |
13 | public float[][] matrix; | |
14 | public final int x, y; | |
15 | private Random rnd = new Random(); | |
16 | ||
17 | /** Construct new zero matrix described by (rows,cols) */ | |
18 | Matrix(int i, int j) { | |
19 | x = i; | |
20 | y = j; | |
21 | matrix = new float[x][y]; | |
22 | for(i = 0;i < x;i++) for(j = 0;j < y;j++) matrix[i][j] = 0; | |
23 | } | |
24 | ||
25 | /** Construct new matrix from (2d_array) */ | |
26 | Matrix(float[][] m) { | |
27 | x = m.length; | |
28 | y = m[0].length; | |
29 | matrix = m; | |
30 | } | |
31 | ||
32 | /** Return matrix as multiline String ready to output */ | |
33 | public String toString() { | |
34 | String out = new String(""); | |
35 | for(int i = 0;i < x;i++) { | |
36 | out += "|\t"; | |
37 | for(int j = 0;j < y;j++) out += (NumberFormat.getInstance().format(matrix[i][j])+"\t"); | |
38 | out += "|\n"; | |
39 | } | |
40 | return out; | |
41 | } | |
42 | ||
43 | /** Print matrix to console */ | |
44 | public void print() { | |
45 | System.out.println(this.toString()); | |
46 | } | |
47 | ||
48 | /** Randomize matrix with numbers x, where: 0 <= x < max */ | |
49 | public void randomize(int max) { | |
50 | for(int i = 0;i < x;i++) for(int j = 0;j < y;j++) matrix[i][j] = rnd.nextInt(max); | |
51 | } | |
52 | ||
53 | /** Compare size of this and another matrix */ | |
54 | public boolean compatible(Matrix m) { | |
55 | if(m.x == this.x && m.y == this.y) return true; | |
56 | System.err.println("Cannot add/subtract/multiply two matrices with different sizes!"); | |
57 | return false; | |
58 | } | |
59 | ||
60 | /** Add another matrix to this and return result */ | |
61 | public Matrix add(Matrix m) { | |
62 | if(!compatible(m)) return null; | |
63 | Matrix o = new Matrix(x,y); | |
64 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] += this.matrix[i][j]; | |
65 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] += m.matrix[i][j]; | |
66 | return o; | |
67 | } | |
68 | ||
69 | /** Subtract another matrix from this and return result */ | |
70 | public Matrix subtract(Matrix m) { | |
71 | if(!compatible(m)) return null; | |
72 | Matrix o = new Matrix(x,y); | |
73 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] += this.matrix[i][j]; | |
74 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] -= m.matrix[i][j]; | |
75 | return o; | |
76 | } | |
77 | ||
78 | /** Scalar-multiply this matrix by another one and return result */ | |
79 | public Matrix multiply(Matrix m) { | |
80 | if(!compatible(m)) return null; | |
81 | Matrix o = new Matrix(x,y); | |
82 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] += this.matrix[i][j]; | |
83 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) o.matrix[i][j] *= m.matrix[i][j]; | |
84 | return o; | |
85 | } | |
86 | ||
87 | /** Matrix-multiply this matrix by another one and return result */ | |
88 | public Matrix mmultiply(Matrix m) { | |
89 | if(this.y != m.x) { | |
90 | System.err.println("Cannot multiply those two matrices!"); | |
91 | return null; | |
92 | } | |
93 | Matrix o = new Matrix(this.x,m.y); | |
94 | for(int i = 0;i < o.x;i++) for(int j = 0;j < o.y;j++) { | |
95 | for(int z = 0;z < this.y;z++) o.matrix[i][j] += this.matrix[i][z] * m.matrix[z][j]; | |
96 | } | |
97 | return o; | |
98 | } | |
99 | ||
100 | /** Return matrix representing this matrix with swapped rows a and b */ | |
101 | public Matrix swap_rows(int a, int b) { | |
102 | Matrix o = new Matrix(x,y); | |
103 | int i, j; | |
104 | for(i = 0;i < o.x;i++) for(j = 0;j < o.y;j++) o.matrix[i][j] += this.matrix[i][j]; | |
105 | float tmp[] = o.matrix[a]; | |
106 | o.matrix[a] = o.matrix[b]; | |
107 | o.matrix[b] = tmp; | |
108 | return o; | |
109 | } | |
110 | ||
111 | /** Return determinant of this matrix */ | |
112 | public double determinant() { | |
113 | System.err.println("TODO: Determinant!"); | |
114 | return 0; | |
115 | } | |
116 | ||
117 | /*public float SIM_MIN(float a, float b) { | |
118 | return (a < b ? a : b); | |
119 | } | |
120 | ||
121 | public double fabs(double a) { | |
122 | return Math.abs(a); | |
123 | }*/ | |
124 | ||
125 | /** Return matrix representing upper triangle format of this matrix */ | |
126 | public Matrix echelon() { | |
127 | System.err.println("Reducing to echelon row form is not working properly!"); | |
128 | //return null; | |
129 | Matrix o = new Matrix(x,y); | |
130 | int i, j; | |
131 | for(i = 0;i < o.x;i++) for(j = 0;j < o.y;j++) o.matrix[i][j] += this.matrix[i][j]; | |
132 | ||
133 | for(int row = x; row >= 0; row--) { | |
134 | //reduceRow(row); | |
135 | double multiplier; | |
136 | for(j=row+1; j < y; j++) { | |
137 | if(o.matrix[row][j] != 0) { | |
138 | multiplier = -o.matrix[row][j]; | |
139 | //addRow(j, row, multiplier); | |
140 | //(int fromRow, int toRow, double mult) | |
141 | for(i=0; i<y; i++) { | |
142 | o.matrix[row][i] += o.matrix[j][i]*multiplier; | |
143 | } | |
144 | } | |
145 | } | |
146 | } | |
147 | /*int lead = 0; | |
148 | ||
149 | for(int r = 0; r < x; r++) { | |
150 | if(x <= lead) { | |
151 | return o; | |
152 | } | |
153 | i = r; | |
154 | while(o.matrix[i][lead] == 0) { | |
155 | i++; | |
156 | if(x == i) { | |
157 | i = r; | |
158 | lead++; | |
159 | if(y == lead) { | |
160 | return o; | |
161 | } | |
162 | } | |
163 | } | |
164 | o = o.swap_rows(i, r); | |
165 | for(j = 0;j < y; j++) o.matrix[r][j] /= o.matrix[r][lead]; | |
166 | for(int row = 0; row < x; row++) | |
167 | { | |
168 | if(row != r) | |
169 | { | |
170 | for(int l = 0; l < y; l++) | |
171 | o.matrix[row][l] -= o.matrix[i][lead] * o.matrix[r][l]; | |
172 | } | |
173 | } | |
174 | lead++; | |
175 | } | |
176 | */ | |
177 | ||
178 | return o; | |
179 | } | |
180 | ||
181 | /** Serialize this object to file specified by its name (and path) */ | |
182 | public boolean save(String file) { | |
183 | try { | |
184 | ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file)); | |
185 | os.writeObject(this); | |
186 | os.close(); | |
187 | } catch (Exception e) { | |
188 | e.printStackTrace(); | |
189 | return false; | |
190 | } | |
191 | return true; | |
192 | } | |
193 | ||
194 | /** Deserialize and return Matrix object from file specified by its name (and path) */ | |
195 | public static Matrix load(String file) { | |
196 | Matrix m = null; | |
197 | try { | |
198 | ObjectInputStream is = new ObjectInputStream(new FileInputStream(file)); | |
199 | m = (Matrix) is.readObject(); | |
200 | is.close(); | |
201 | } catch (Exception e) { | |
202 | e.printStackTrace(); | |
203 | } | |
204 | return m; | |
205 | } | |
206 | ||
207 | ||
208 | } | |
209 | ||
210 | /** Class demonstrating usage of Matrix class */ | |
211 | public class matice { | |
212 | public static void main(String[] argv) { | |
213 | System.out.println("You has matrix! Follow the black habit ;o)\n"); | |
214 | ||
215 | String file = "f.matrix"; | |
216 | ||
217 | System.out.println("Created matrix F and saved to file "+file+" ="); | |
218 | Matrix f = new Matrix(3,3); f.randomize(2); f.print(); | |
219 | f.save(file); | |
220 | ||
221 | System.out.println("Loaded matrix G from file "+file+" ="); | |
222 | Matrix g = Matrix.load(file); g.print(); | |
223 | ||
224 | System.exit(0); | |
225 | ||
226 | System.out.println("Created matrix A ="); | |
227 | Matrix a = new Matrix(3,3); a.randomize(2); a.print(); | |
228 | ||
229 | System.out.println("Created matrix B ="); | |
230 | Matrix b = new Matrix(new float[][] { | |
231 | {1, 2, 3}, | |
232 | {4, 5, 6}, | |
233 | {7, 8, 9} | |
234 | }); | |
235 | b.print(); | |
236 | ||
237 | /*System.out.println("Row Echelon form of B ="); | |
238 | b.echelon().print(); | |
239 | */ | |
240 | ||
241 | System.out.println("A + B ="); | |
242 | a.add(b).print(); | |
243 | ||
244 | System.out.println("A - B ="); | |
245 | a.subtract(b).print(); | |
246 | ||
247 | System.out.println("A * B ="); | |
248 | a.multiply(b).print(); | |
249 | ||
250 | System.out.println("Swap rows 0 and 1 of matrix B ="); | |
251 | b.swap_rows(0,1).print(); | |
252 | ||
253 | System.out.println("Created matrix C ="); | |
254 | Matrix c = new Matrix(3,4); c.randomize(20); c.print(); | |
255 | ||
256 | System.out.println("Created matrix D ="); | |
257 | Matrix d = new Matrix(4,2); d.randomize(10); d.print(); | |
258 | ||
259 | System.out.println("C . D ="); | |
260 | c.mmultiply(d).print(); | |
261 | } | |
262 | } | |
263 | ||
264 | /* Echelon debug: | |
265 | ||
266 | B: matrix( | |
267 | [1,2,3], | |
268 | [4,5,6], | |
269 | [7,8,9] | |
270 | ); | |
271 | ||
272 | echelon(B) = matrix( | |
273 | [1,2,3], | |
274 | [0,1,2], | |
275 | [0,0,0] | |
276 | ) | |
277 | ||
278 | **********************************/ | |
279 | ||
280 | ||
281 | /* Example: | |
282 | ||
283 | 0 ;) harvie@harvie-ntb prg $ javac matice.java; java matice | |
284 | You has matrix! Follow the black habit ;o) | |
285 | ||
286 | Created matrix A = | |
287 | | 0 0 0 | | |
288 | | 0 0 1 | | |
289 | | 1 1 0 | | |
290 | ||
291 | Created matrix B = | |
292 | | 8 9 8 | | |
293 | | 7 9 6 | | |
294 | | 7 4 8 | | |
295 | ||
296 | A + B = | |
297 | | 8 9 8 | | |
298 | | 7 9 7 | | |
299 | | 8 5 8 | | |
300 | ||
301 | A - B = | |
302 | | -8 -9 -8 | | |
303 | | -7 -9 -5 | | |
304 | | -6 -3 -8 | | |
305 | ||
306 | A * B = | |
307 | | 0 0 0 | | |
308 | | 0 0 6 | | |
309 | | 7 4 0 | | |
310 | ||
311 | Created matrix C = | |
312 | | 19 12 2 7 | | |
313 | | 1 3 8 12 | | |
314 | | 7 5 13 4 | | |
315 | ||
316 | Created matrix D = | |
317 | | 8 2 | | |
318 | | 7 8 | | |
319 | | 8 4 | | |
320 | | 5 7 | | |
321 | ||
322 | C . D = | |
323 | | 287 191 | | |
324 | | 153 142 | | |
325 | | 215 134 | | |
326 | ||
327 | */ |