-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path157.java
More file actions
400 lines (344 loc) · 10.7 KB
/
Copy path157.java
File metadata and controls
400 lines (344 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
package org.hortonmachine.gears.utils.math.matrixes;
/**
* From: Java Number Cruncher
* The Java Programmer's Guide to Numerical Computation
* by Ronald Mak
*
*
* The matrix class.
*/
public class Matrix
{
/** number of rows */ protected int nRows;
/** number of columns */ protected int nCols;
/** 2-d array of values */ protected double values[][];
//--------------//
// Constructors //
//--------------//
/**
* Default constructor.
*/
protected Matrix() {}
/**
* Constructor.
* @param rowCount the number of rows
* @param colCount the number of columns
*/
public Matrix(int rowCount, int colCount)
{
nRows = (rowCount > 0) ? rowCount : 1;
nCols = (colCount > 0) ? colCount : 1;
values = new double[nRows][nCols];
}
/**
* Constructor.
* @param values the 2-d array of values
*/
public Matrix(double values[][]) { set(values); }
//---------//
// Getters //
//---------//
/**
* Get the row count.
* @return the row count
*/
public int rowCount() { return nRows; }
/**
* Get the column count.
* @return the column count
*/
public int columnCount() { return nCols; }
/**
* Get the value of element [r,c] in the matrix.
* @param r the row index
* @param c the column index
* @return the value
* @throws numbercruncher.MatrixException for an invalid index
*/
public double at(int r, int c) throws MatrixException
{
if ((r < 0) || (r >= nRows) || (c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
return values[r][c];
}
/**
* Get a row of this matrix.
* @param r the row index
* @return the row as a row vector
* @throws numbercruncher.MatrixException for an invalid index
*/
public RowVector getRow(int r) throws MatrixException
{
if ((r < 0) || (r >= nRows)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
RowVector rv = new RowVector(nCols);
for (int c = 0; c < nCols; ++c) {
rv.values[0][c] = this.values[r][c];
}
return rv;
}
/**
* Get a column of this matrix.
* @param c the column index
* @return the column as a column vector
* @throws numbercruncher.MatrixException for an invalid index
*/
public ColumnVector getColumn(int c) throws MatrixException
{
if ((c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
ColumnVector cv = new ColumnVector(nRows);
for (int r = 0; r < nRows; ++r) {
cv.values[r][0] = this.values[r][c];
}
return cv;
}
/**
* Copy the values of this matrix.
* @return the values
*/
public double[][] values() { return values; }
/**
* Copy the values of this matrix.
* @return the copied values
*/
public double[][] copyValues2D()
{
double v[][] = new double[nRows][nCols];
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
v[r][c] = values[r][c];
}
}
return v;
}
//---------//
// Setters //
//---------//
/**
* Set the value of element [r,c].
* @param r the row index
* @param c the column index
* @param value the value
* @throws numbercruncher.MatrixException for an invalid index
*/
public void set(int r, int c, double value) throws MatrixException
{
if ((r < 0) || (r >= nRows) || (c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
values[r][c] = value;
}
/**
* Set this matrix from a 2-d array of values.
* If the rows do not have the same length, then the matrix
* column count is the length of the shortest row.
* @param values the 2-d array of values
*/
protected void set(double values[][])
{
this.nRows = values.length;
this.nCols = values[0].length;
this.values = values;
for (int r = 1; r < nRows; ++r) {
nCols = Math.min(nCols, values[r].length);
}
}
/**
* Set a row of this matrix from a row vector.
* @param rv the row vector
* @param r the row index
* @throws numbercruncher.MatrixException for an invalid index or
* an invalid vector size
*/
public void setRow(RowVector rv, int r) throws MatrixException
{
if ((r < 0) || (r >= nRows)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
if (nCols != rv.nCols) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
for (int c = 0; c < nCols; ++c) {
this.values[r][c] = rv.values[0][c];
}
}
/**
* Set a column of this matrix from a column vector.
* @param cv the column vector
* @param c the column index
* @throws numbercruncher.MatrixException for an invalid index or
* an invalid vector size
*/
public void setColumn(ColumnVector cv, int c)
throws MatrixException
{
if ((c < 0) || (c >= nCols)) {
throw new MatrixException(MatrixException.INVALID_INDEX);
}
if (nRows != cv.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
for (int r = 0; r < nRows; ++r) {
this.values[r][c] = cv.values[r][0];
}
}
//-------------------//
// Matrix operations //
//-------------------//
/**
* Return the transpose of this matrix.
* @return the transposed matrix
*/
public Matrix transpose()
{
double tv[][] = new double[nCols][nRows]; // transposed values
// Set the values of the transpose.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
tv[c][r] = values[r][c];
}
}
return new Matrix(tv);
}
/**
* Add another matrix to this matrix.
* @param m the matrix addend
* @return the sum matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix add(Matrix m) throws MatrixException
{
// Validate m's size.
if ((nRows != m.nRows) && (nCols != m.nCols)) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double sv[][] = new double[nRows][nCols]; // sum values
// Compute values of the sum.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
sv[r][c] = values[r][c] + m.values[r][c];
}
}
return new Matrix(sv);
}
/**
* Subtract another matrix from this matrix.
* @param m the matrix subrrahend
* @return the difference matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix subtract(Matrix m) throws MatrixException
{
// Validate m's size.
if ((nRows != m.nRows) && (nCols != m.nCols)) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double dv[][] = new double[nRows][nCols]; // difference values
// Compute values of the difference.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
dv[r][c] = values[r][c] - m.values[r][c];
}
}
return new Matrix(dv);
}
/**
* Multiply this matrix by a constant.
* @param k the constant
* @return the product matrix
*/
public Matrix multiply(double k)
{
double pv[][] = new double[nRows][nCols]; // product values
// Compute values of the product.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < nCols; ++c) {
pv[r][c] = k*values[r][c];
}
}
return new Matrix(pv);
}
/**
* Multiply this matrix by another matrix.
* @param m the matrix multiplier
* @return the product matrix
* @throws numbercruncher.MatrixException for invalid size
*/
public Matrix multiply(Matrix m) throws MatrixException
{
// Validate m's dimensions.
if (nCols != m.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[][] = new double[nRows][m.nCols]; // product values
// Compute values of the product.
for (int r = 0; r < nRows; ++r) {
for (int c = 0; c < m.nCols; ++c) {
double dot = 0;
for (int k = 0; k < nCols; ++k) {
dot += values[r][k] * m.values[k][c];
}
pv[r][c] = dot;
}
}
return new Matrix(pv);
}
/**
* Multiply this matrix by a column vector: this*cv
* @param cv the column vector
* @return the product column vector
* @throws numbercruncher.MatrixException for invalid size
*/
public ColumnVector multiply(ColumnVector cv)
throws MatrixException
{
// Validate cv's size.
if (nRows != cv.nRows) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[] = new double[nRows]; // product values
// Compute the values of the product.
for (int r = 0; r < nRows; ++r) {
double dot = 0;
for (int c = 0; c < nCols; ++c) {
dot += values[r][c] * cv.values[c][0];
}
pv[r] = dot;
}
return new ColumnVector(pv);
}
/**
* Multiply a row vector by this matrix: rv*this
* @param rv the row vector
* @return the product row vector
* @throws numbercruncher.MatrixException for invalid size
*/
public RowVector multiply(RowVector rv) throws MatrixException
{
// Validate rv's size.
if (nCols != rv.nCols) {
throw new MatrixException(
MatrixException.INVALID_DIMENSIONS);
}
double pv[] = new double[nRows]; // product values
// Compute the values of the product.
for (int c = 0; c < nCols; ++c) {
double dot = 0;
for (int r = 0; r < nRows; ++r) {
dot += rv.values[0][r] * values[r][c];
}
pv[c] = dot;
}
return new RowVector(pv);
}
}