1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.linear;
23
24 import java.io.Serializable;
25
26 import org.hipparchus.exception.LocalizedCoreFormats;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.exception.NullArgumentException;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.MathUtils;
31 import org.hipparchus.util.Precision;
32
33
34
35
36
37 public class DiagonalMatrix extends AbstractRealMatrix
38 implements Serializable {
39
40 private static final long serialVersionUID = 20121229L;
41
42 private final double[] data;
43
44
45
46
47
48
49
50
51 public DiagonalMatrix(final int dimension)
52 throws MathIllegalArgumentException {
53 super(dimension, dimension);
54 data = new double[dimension];
55 }
56
57
58
59
60
61
62
63
64 public DiagonalMatrix(final double[] d) {
65 this(d, true);
66 }
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public DiagonalMatrix(final double[] d, final boolean copyArray)
83 throws NullArgumentException {
84 MathUtils.checkNotNull(d);
85 data = copyArray ? d.clone() : d;
86 }
87
88
89
90
91
92
93 @Override
94 public RealMatrix createMatrix(final int rowDimension,
95 final int columnDimension)
96 throws MathIllegalArgumentException {
97 if (rowDimension != columnDimension) {
98 throw new MathIllegalArgumentException(LocalizedCoreFormats.DIMENSIONS_MISMATCH,
99 rowDimension, columnDimension);
100 }
101
102 return new DiagonalMatrix(rowDimension);
103 }
104
105
106 @Override
107 public RealMatrix copy() {
108 return new DiagonalMatrix(data);
109 }
110
111
112
113
114
115
116
117
118
119 public DiagonalMatrix add(final DiagonalMatrix m)
120 throws MathIllegalArgumentException {
121
122 MatrixUtils.checkAdditionCompatible(this, m);
123
124 final int dim = getRowDimension();
125 final double[] outData = new double[dim];
126 for (int i = 0; i < dim; i++) {
127 outData[i] = data[i] + m.data[i];
128 }
129
130 return new DiagonalMatrix(outData, false);
131 }
132
133
134
135
136
137
138
139
140
141 public DiagonalMatrix subtract(final DiagonalMatrix m)
142 throws MathIllegalArgumentException {
143 MatrixUtils.checkSubtractionCompatible(this, m);
144
145 final int dim = getRowDimension();
146 final double[] outData = new double[dim];
147 for (int i = 0; i < dim; i++) {
148 outData[i] = data[i] - m.data[i];
149 }
150
151 return new DiagonalMatrix(outData, false);
152 }
153
154
155
156
157
158
159
160
161
162 public DiagonalMatrix multiply(final DiagonalMatrix m)
163 throws MathIllegalArgumentException {
164 MatrixUtils.checkMultiplicationCompatible(this, m);
165
166 final int dim = getRowDimension();
167 final double[] outData = new double[dim];
168 for (int i = 0; i < dim; i++) {
169 outData[i] = data[i] * m.data[i];
170 }
171
172 return new DiagonalMatrix(outData, false);
173 }
174
175
176 @Override
177 public RealMatrix multiply(final RealMatrix m)
178 throws MathIllegalArgumentException {
179 if (m instanceof DiagonalMatrix) {
180 return multiply((DiagonalMatrix) m);
181 } else {
182 MatrixUtils.checkMultiplicationCompatible(this, m);
183 final RealMatrix product = m.createMatrix(m.getRowDimension(), m.getColumnDimension());
184 product.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() {
185
186 @Override
187 public double visit(int row, int column, double value) {
188 return data[row] * m.getEntry(row, column);
189 }
190 });
191 return product;
192 }
193 }
194
195
196
197
198
199
200
201
202
203 public DiagonalMatrix multiplyTransposed(final DiagonalMatrix m)
204 throws MathIllegalArgumentException {
205
206 return multiply(m);
207 }
208
209
210 @Override
211 public RealMatrix multiplyTransposed(final RealMatrix m)
212 throws MathIllegalArgumentException {
213 if (m instanceof DiagonalMatrix) {
214 return multiplyTransposed((DiagonalMatrix) m);
215 } else {
216 MatrixUtils.checkSameColumnDimension(this, m);
217 final RealMatrix product = m.createMatrix(m.getColumnDimension(), m.getRowDimension());
218 product.walkInOptimizedOrder(new DefaultRealMatrixChangingVisitor() {
219
220 @Override
221 public double visit(int row, int column, double value) {
222 return data[row] * m.getEntry(column, row);
223 }
224 });
225 return product;
226 }
227 }
228
229
230
231
232
233
234
235
236
237 public DiagonalMatrix transposeMultiply(final DiagonalMatrix m)
238 throws MathIllegalArgumentException {
239
240 return multiply(m);
241 }
242
243
244 @Override
245 public RealMatrix transposeMultiply(final RealMatrix m) {
246 if (m instanceof DiagonalMatrix) {
247 return transposeMultiply((DiagonalMatrix) m);
248 } else {
249
250 return multiply(m);
251 }
252 }
253
254
255 @Override
256 public double[][] getData() {
257 final int dim = getRowDimension();
258 final double[][] out = new double[dim][dim];
259
260 for (int i = 0; i < dim; i++) {
261 out[i][i] = data[i];
262 }
263
264 return out;
265 }
266
267
268
269
270
271
272 public double[] getDataRef() {
273 return data;
274 }
275
276
277 @Override
278 public double getEntry(final int row, final int column)
279 throws MathIllegalArgumentException {
280 MatrixUtils.checkMatrixIndex(this, row, column);
281 return row == column ? data[row] : 0;
282 }
283
284
285
286
287 @Override
288 public void setEntry(final int row, final int column, final double value)
289 throws MathIllegalArgumentException {
290 if (row == column) {
291 MatrixUtils.checkRowIndex(this, row);
292 data[row] = value;
293 } else {
294 ensureZero(value);
295 }
296 }
297
298
299
300
301 @Override
302 public void addToEntry(final int row,
303 final int column,
304 final double increment)
305 throws MathIllegalArgumentException {
306 if (row == column) {
307 MatrixUtils.checkRowIndex(this, row);
308 data[row] += increment;
309 } else {
310 ensureZero(increment);
311 }
312 }
313
314
315 @Override
316 public void multiplyEntry(final int row,
317 final int column,
318 final double factor)
319 throws MathIllegalArgumentException {
320
321 if (row == column) {
322 MatrixUtils.checkRowIndex(this, row);
323 data[row] *= factor;
324 }
325 }
326
327
328 @Override
329 public int getRowDimension() {
330 return data.length;
331 }
332
333
334 @Override
335 public int getColumnDimension() {
336 return data.length;
337 }
338
339
340 @Override
341 public double[] operate(final double[] v)
342 throws MathIllegalArgumentException {
343 return multiply(new DiagonalMatrix(v, false)).getDataRef();
344 }
345
346
347 @Override
348 public double[] preMultiply(final double[] v)
349 throws MathIllegalArgumentException {
350 return operate(v);
351 }
352
353
354 @Override
355 public RealVector preMultiply(final RealVector v) throws MathIllegalArgumentException {
356 final double[] vectorData;
357 if (v instanceof ArrayRealVector) {
358 vectorData = ((ArrayRealVector) v).getDataRef();
359 } else {
360 vectorData = v.toArray();
361 }
362 return MatrixUtils.createRealVector(preMultiply(vectorData));
363 }
364
365
366
367
368
369 private void ensureZero(final double value) throws MathIllegalArgumentException {
370 if (!Precision.equals(0.0, value, 1)) {
371 throw new MathIllegalArgumentException(LocalizedCoreFormats.NUMBER_TOO_LARGE,
372 FastMath.abs(value), 0);
373 }
374 }
375
376
377
378
379
380
381
382
383
384
385 public DiagonalMatrix inverse() throws MathIllegalArgumentException {
386 return inverse(0);
387 }
388
389
390
391
392
393
394
395
396 public DiagonalMatrix inverse(double threshold) throws MathIllegalArgumentException {
397 if (isSingular(threshold)) {
398 throw new MathIllegalArgumentException(LocalizedCoreFormats.SINGULAR_MATRIX);
399 }
400
401 final double[] result = new double[data.length];
402 for (int i = 0; i < data.length; i++) {
403 result[i] = 1.0 / data[i];
404 }
405 return new DiagonalMatrix(result, false);
406 }
407
408
409
410
411
412
413
414 public boolean isSingular(double threshold) {
415 for (int i = 0; i < data.length; i++) {
416 if (Precision.equals(data[i], 0.0, threshold)) {
417 return true;
418 }
419 }
420 return false;
421 }
422 }