001 // --- BEGIN LICENSE BLOCK ---
002 /*
003 * Copyright (c) 2009, Mikio L. Braun
004 * Copyright (c) 2008, Johannes Schaback
005 * Copyright (c) 2009, Jan Saputra M??ller
006 * All rights reserved.
007 *
008 * Redistribution and use in source and binary forms, with or without
009 * modification, are permitted provided that the following conditions are
010 * met:
011 *
012 * * Redistributions of source code must retain the above copyright
013 * notice, this list of conditions and the following disclaimer.
014 *
015 * * Redistributions in binary form must reproduce the above
016 * copyright notice, this list of conditions and the following
017 * disclaimer in the documentation and/or other materials provided
018 * with the distribution.
019 *
020 * * Neither the name of the Technische Universit??t Berlin nor the
021 * names of its contributors may be used to endorse or promote
022 * products derived from this software without specific prior
023 * written permission.
024 *
025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
026 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
027 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
028 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
029 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
030 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
031 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
032 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
033 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
034 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
035 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
036 */
037 // --- END LICENSE BLOCK ---
038 package org.jblas;
039
040 import org.jblas.exceptions.SizeException;
041 import org.jblas.ranges.Range;
042 import java.io.BufferedReader;
043 import java.io.DataInputStream;
044 import java.io.DataOutputStream;
045 import java.io.FileInputStream;
046 import java.io.FileOutputStream;
047 import java.io.IOException;
048 import java.io.InputStreamReader;
049
050 import java.io.ObjectInputStream;
051 import java.io.ObjectOutputStream;
052 import java.io.PrintWriter;
053 import java.io.Serializable;
054 import java.io.StringWriter;
055 import java.util.AbstractList;
056 import java.util.Arrays;
057 import java.util.Comparator;
058 import java.util.Iterator;
059 import java.util.LinkedList;
060 import java.util.List;
061
062 /**
063 * A general matrix class for <tt>double</tt> typed values.
064 *
065 * Don't be intimidated by the large number of methods this function defines. Most
066 * are overloads provided for ease of use. For example, for each arithmetic operation,
067 * up to six overloaded versions exist to handle in-place computations, and
068 * scalar arguments.
069 *
070 * <h3>Construction</h3>
071 *
072 * <p>To construct a two-dimensional matrices, you can use the following constructors
073 * and static methods.</p>
074 *
075 * <table class="my">
076 * <tr><th>Method<th>Description
077 * <tr><td>DoubleMatrix(m,n, [value1, value2, value3...])<td>Values are filled in row by row.
078 * <tr><td>DoubleMatrix(new double[][] {{value1, value2, ...}, ...}<td>Inner arrays are columns.
079 * <tr><td>DoubleMatrix.zeros(m,n) <td>Initial values set to 0.0.
080 * <tr><td>DoubleMatrix.ones(m,n) <td>Initial values set to 1.0.
081 * <tr><td>DoubleMatrix.rand(m,n) <td>Values drawn at random between 0.0 and 1.0.
082 * <tr><td>DoubleMatrix.randn(m,n) <td>Values drawn from normal distribution.
083 * <tr><td>DoubleMatrix.eye(n) <td>Unit matrix (values 0.0 except for 1.0 on the diagonal).
084 * <tr><td>DoubleMatrix.diag(array) <td>Diagonal matrix with given diagonal elements.
085 * </table>
086 *
087 * <p>Alternatively, you can construct (column) vectors, if you just supply the length
088 * using the following constructors and static methods.</p>
089 *
090 * <table class="my">
091 * <tr><th>Method<th>Description
092 * <tr><td>DoubleMatrix(m)<td>Constructs a column vector.
093 * <tr><td>DoubleMatrix(new double[] {value1, value2, ...})<td>Constructs a column vector.
094 * <tr><td>DoubleMatrix.zeros(m) <td>Initial values set to 1.0.
095 * <tr><td>DoubleMatrix.ones(m) <td>Initial values set to 0.0.
096 * <tr><td>DoubleMatrix.rand(m) <td>Values drawn at random between 0.0 and 1.0.
097 * <tr><td>DoubleMatrix.randn(m) <td>Values drawn from normal distribution.
098 * </table>
099 *
100 * <p>You can also construct new matrices by concatenating matrices either horziontally
101 * or vertically:</p>
102 *
103 * <table class="my">
104 * <tr><th>Method<th>Description
105 * <tr><td>x.concatHorizontally(y)<td>New matrix will be x next to y.
106 * <tr><td>x.concatVertically(y)<td>New matrix will be x atop y.
107 * </table>
108 *
109 * <h3>Element Access, Copying and Duplication</h3>
110 *
111 * <p>To access individual elements, or whole rows and columns, use the following
112 * methods:<p>
113 *
114 * <table class="my">
115 * <tr><th>x.Method<th>Description
116 * <tr><td>x.get(i,j)<td>Get element in row i and column j.
117 * <tr><td>x.put(i, j, v)<td>Set element in row i and column j to value v
118 * <tr><td>x.get(i)<td>Get the ith element of the matrix (traversing rows first).
119 * <tr><td>x.put(i, v)<td>Set the ith element of the matrix (traversing rows first).
120 * <tr><td>x.getColumn(i)<td>Get a copy of column i.
121 * <tr><td>x.putColumn(i, c)<td>Put matrix c into column i.
122 * <tr><td>x.getRow(i)<td>Get a copy of row i.
123 * <tr><td>x.putRow(i, c)<td>Put matrix c into row i.
124 * <tr><td>x.swapColumns(i, j)<td>Swap the contents of columns i and j.
125 * <tr><td>x.swapRows(i, j)<td>Swap the contents of columns i and j.
126 * </table>
127 *
128 * <p>For <tt>get</tt> and <tt>put</tt>, you can also pass integer arrays,
129 * DoubleMatrix objects, or Range objects, which then specify the indices used
130 * as follows:
131 *
132 * <ul>
133 * <li><em>integer array:</em> the elements will be used as indices.
134 * <li><em>DoubleMatrix object:</em> non-zero entries specify the indices.
135 * <li><em>Range object:</em> see below.
136 * </ul>
137 *
138 * <p>When using <tt>put</tt> with multiple indices, the assigned object must
139 * have the correct size or be a scalar.</p>
140 *
141 * <p>There exist the following Range objects. The Class <tt>RangeUtils</tt> also
142 * contains the a number of handy helper methods for constructing these ranges.</p>
143 * <table class="my">
144 * <tr><th>Class <th>RangeUtils method <th>Indices
145 * <tr><td>AllRange <td>all() <td>All legal indices.
146 * <tr><td>PointRange <td>point(i) <td> A single point.
147 * <tr><td>IntervalRange <td>interval(a, b)<td> All indices from a to b (inclusive)
148 * <tr><td rowspan=3>IndicesRange <td>indices(int[])<td> The specified indices.
149 * <tr><td>indices(DoubleMatrix)<td>The specified indices.
150 * <tr><td>find(DoubleMatrix)<td>The non-zero entries of the matrix.
151 * </table>
152 *
153 * <p>The following methods can be used for duplicating and copying matrices.</p>
154 *
155 * <table class="my">
156 * <tr><th>Method<th>Description
157 * <tr><td>x.dup()<td>Get a copy of x.
158 * <tr><td>x.copy(y)<td>Copy the contents of y to x (possible resizing x).
159 * </table>
160 *
161 * <h3>Size and Shape</h3>
162 *
163 * <p>The following methods permit to acces the size of a matrix and change its size or shape.</p>
164 *
165 * <table class="my">
166 * <tr><th>x.Method<th>Description
167 * <tr><td>x.rows<td>Number of rows.
168 * <tr><td>x.columns<td>Number of columns.
169 * <tr><td>x.length<td>Total number of elements.
170 * <tr><td>x.isEmpty()<td>Checks whether rows == 0 and columns == 0.
171 * <tr><td>x.isRowVector()<td>Checks whether rows == 1.
172 * <tr><td>x.isColumnVector()<td>Checks whether columns == 1.
173 * <tr><td>x.isVector()<td>Checks whether rows == 1 or columns == 1.
174 * <tr><td>x.isSquare()<td>Checks whether rows == columns.
175 * <tr><td>x.isScalar()<td>Checks whether length == 1.
176 * <tr><td>x.resize(r, c)<td>Resize the matrix to r rows and c columns, discarding the content.
177 * <tr><td>x.reshape(r, c)<td>Resize the matrix to r rows and c columns.<br> Number of elements must not change.
178 * </table>
179 *
180 * <p>The size is stored in the <tt>rows</tt> and <tt>columns</tt> member variables.
181 * The total number of elements is stored in <tt>length</tt>. Do not change these
182 * values unless you know what you're doing!</p>
183 *
184 * <h3>Arithmetics</h3>
185 *
186 * <p>The usual arithmetic operations are implemented. Each operation exists in a
187 * in-place version, recognizable by the suffix <tt>"i"</tt>, to which you can supply
188 * the result matrix (or <tt>this</tt> is used, if missing). Using in-place operations
189 * can also lead to a smaller memory footprint, as the number of temporary objects
190 * which are directly garbage collected again is reduced.</p>
191 *
192 * <p>Whenever you specify a result vector, the result vector must already have the
193 * correct dimensions.</p>
194 *
195 * <p>For example, you can add two matrices using the <tt>add</tt> method. If you want
196 * to store the result in of <tt>x + y</tt> in <tt>z</tt>, type
197 * <span class=code>
198 * x.addi(y, z) // computes x = y + z.
199 * </span>
200 * Even in-place methods return the result, such that you can easily chain in-place methods,
201 * for example:
202 * <span class=code>
203 * x.addi(y).addi(z) // computes x += y; x += z
204 * </span></p>
205 *
206 * <p>Methods which operate element-wise only make sure that the length of the matrices
207 * is correct. Therefore, you can add a 3 * 3 matrix to a 1 * 9 matrix, for example.</p>
208 *
209 * <p>Finally, there exist versions which take doubles instead of DoubleMatrix Objects
210 * as arguments. These then compute the operation with the same value as the
211 * right-hand-side. The same effect can be achieved by passing a DoubleMatrix with
212 * exactly one element.</p>
213 *
214 * <table class="my">
215 * <tr><th>Operation <th>Method <th>Comment
216 * <tr><td>x + y <td>x.add(y) <td>
217 * <tr><td>x - y <td>x.sub(y), y.rsub(x) <td>rsub subtracts left from right hand side
218 * <tr><td rowspan=3>x * y <td>x.mul(y) <td>element-wise multiplication
219 * <tr> <td>x.mmul(y)<td>matrix-matrix multiplication
220 * <tr> <td>x.dot(y) <td>scalar-product
221 * <tr><td>x / y <td>x.div(y), y.rdiv(x) <td>rdiv divides right hand side by left hand side.
222 * <tr><td>- x <td>x.neg() <td>
223 * </table>
224 *
225 * <p>There also exist operations which work on whole columns or rows.</p>
226 *
227 * <table class="my">
228 * <tr><th>Method <th>Description
229 * <tr><td>x.addRowVector<td>adds a vector to each row (addiRowVector works in-place)
230 * <tr><td>x.addColumnVector<td>adds a vector to each column
231 * <tr><td>x.subRowVector<td>subtracts a vector from each row
232 * <tr><td>x.subColumnVector<td>subtracts a vector from each column
233 * <tr><td>x.mulRow<td>Multiplies a row by a scalar
234 * <tr><td>x.mulColumn<td>multiplies a row by a column
235 * </table>
236 *
237 * <p>In principle, you could achieve the same result by first calling getColumn(),
238 * adding, and then calling putColumn, but these methods are much faster.</p>
239 *
240 * <p>The following comparison operations are available</p>
241 *
242 * <table class="my">
243 * <tr><th>Operation <th>Method
244 * <tr><td>x < y <td>x.lt(y)
245 * <tr><td>x <= y <td>x.le(y)
246 * <tr><td>x > y <td>x.gt(y)
247 * <tr><td>x >= y <td>x.ge(y)
248 * <tr><td>x == y <td>x.eq(y)
249 * <tr><td>x != y <td>x.ne(y)
250 * </table>
251 *
252 * <p> Logical operations are also supported. For these operations, a value different from
253 * zero is treated as "true" and zero is treated as "false". All operations are carried
254 * out elementwise.</p>
255 *
256 * <table class="my">
257 * <tr><th>Operation <th>Method
258 * <tr><td>x & y <td>x.and(y)
259 * <tr><td>x | y <td>x.or(y)
260 * <tr><td>x ^ y <td>x.xor(y)
261 * <tr><td>! x <td>x.not()
262 * </table>
263 *
264 * <p>Finally, there are a few more methods to compute various things:</p>
265 *
266 * <table class="my">
267 * <tr><th>Method <th>Description
268 * <tr><td>x.max() <td>Return maximal element
269 * <tr><td>x.argmax() <td>Return index of largest element
270 * <tr><td>x.min() <td>Return minimal element
271 * <tr><td>x.argmin() <td>Return index of largest element
272 * <tr><td>x.columnMins() <td>Return column-wise minima
273 * <tr><td>x.columnArgmins() <td>Return column-wise index of minima
274 * <tr><td>x.columnMaxs() <td>Return column-wise maxima
275 * <tr><td>x.columnArgmaxs() <td>Return column-wise index of maxima
276 * </table>
277 *
278 * @author Mikio Braun, Johannes Schaback
279 */
280 public class DoubleMatrix implements Serializable {
281
282 /** Number of rows. */
283 public int rows;
284 /** Number of columns. */
285 public int columns;
286 /** Total number of elements (for convenience). */
287 public int length;
288 /** The actual data stored by rows (that is, row 0, row 1...). */
289 public double[] data = null; // rows are contiguous
290 public static final DoubleMatrix EMPTY = new DoubleMatrix();
291
292 static final long serialVersionUID = -1249281332731183060L;
293
294 /**************************************************************************
295 *
296 * Constructors and factory functions
297 *
298 **************************************************************************/
299 /** Create a new matrix with <i>newRows</i> rows, <i>newColumns</i> columns
300 * using <i>newData></i> as the data. The length of the data is not checked!
301 */
302 public DoubleMatrix(int newRows, int newColumns, double... newData) {
303 rows = newRows;
304 columns = newColumns;
305 length = rows * columns;
306
307 if (newData != null && newData.length != newRows * newColumns) {
308 throw new IllegalArgumentException(
309 "Passed data must match matrix dimensions.");
310 }
311
312 data = newData;
313 //System.err.printf("%d * %d matrix created\n", rows, columns);
314 }
315
316 /**
317 * Creates a new <i>n</i> times <i>m</i> <tt>DoubleMatrix</tt>.
318 * @param newRows the number of rows (<i>n</i>) of the new matrix.
319 * @param newColumns the number of columns (<i>m</i>) of the new matrix.
320 */
321 public DoubleMatrix(int newRows, int newColumns) {
322 this(newRows, newColumns, new double[newRows * newColumns]);
323 }
324
325 /**
326 * Creates a new <tt>DoubleMatrix</tt> of size 0 times 0.
327 */
328 public DoubleMatrix() {
329 this(0, 0, (double[]) null);
330 }
331
332 /**
333 * Create a Matrix of length <tt>len</tt>. By default, this creates a row vector.
334 * @param len
335 */
336 public DoubleMatrix(int len) {
337 this(len, 1, new double[len]);
338 }
339
340 public DoubleMatrix(double[] newData) {
341 this(newData.length);
342 data = newData;
343 }
344
345 /**
346 * Creates a new matrix by reading it from a file.
347 * @param filename the path and name of the file to read the matrix from
348 * @throws IOException
349 */
350 public DoubleMatrix(String filename) throws IOException {
351 load(filename);
352 }
353
354 /**
355 * Creates a new <i>n</i> times <i>m</i> <tt>DoubleMatrix</tt> from
356 * the given <i>n</i> times <i>m</i> 2D data array. The first dimension of the array makes the
357 * rows (<i>n</i>) and the second dimension the columns (<i>m</i>). For example, the
358 * given code <br/><br/>
359 * <code>new DoubleMatrix(new double[][]{{1d, 2d, 3d}, {4d, 5d, 6d}, {7d, 8d, 9d}}).print();</code><br/><br/>
360 * will constructs the following matrix:
361 * <pre>
362 * 1.0 2.0 3.0
363 * 4.0 5.0 6.0
364 * 7.0 8.0 9.0
365 * </pre>.
366 * @param data <i>n</i> times <i>m</i> data array
367 */
368 public DoubleMatrix(double[][] data) {
369 this(data.length, data[0].length);
370
371 for (int r = 0; r < rows; r++) {
372 assert (data[r].length == columns);
373 }
374
375 for (int r = 0; r < rows; r++) {
376 for (int c = 0; c < columns; c++) {
377 put(r, c, data[r][c]);
378 }
379 }
380 }
381
382 public DoubleMatrix(List<Double> data) {
383 this(data.size());
384
385 int c = 0;
386 for (java.lang.Double d : data) {
387 put(c++, d);
388 }
389 }
390
391 /**
392 * Construct DoubleMatrix from ASCII representation.
393 *
394 * This is not very fast, but can be quiet useful when
395 * you want to "just" construct a matrix, for example
396 * when testing.
397 *
398 * The format is semicolon separated rows of space separated values,
399 * for example "1 2 3; 4 5 6; 7 8 9".
400 */
401 public static DoubleMatrix valueOf(String text) {
402 String[] rowValues = text.split(";");
403
404 // process first line
405 String[] columnValues = rowValues[0].trim().split("\\s+");
406
407 DoubleMatrix result = null;
408
409 // process rest
410 for (int r = 0; r < rowValues.length; r++) {
411 columnValues = rowValues[r].trim().split("\\s+");
412
413 if (r == 0) {
414 result = new DoubleMatrix(rowValues.length, columnValues.length);
415 }
416
417 for (int c = 0; c < columnValues.length; c++) {
418 result.put(r, c, Double.valueOf(columnValues[c]));
419 }
420 }
421
422 return result;
423 }
424
425 /**
426 * Serialization
427 */
428 private void writeObject(ObjectOutputStream s) throws IOException {
429 s.defaultWriteObject();
430 }
431
432 private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
433 s.defaultReadObject();
434 }
435
436 /** Create matrix with random values uniformly in 0..1. */
437 public static DoubleMatrix rand(int rows, int columns) {
438 DoubleMatrix m = new DoubleMatrix(rows, columns);
439
440 java.util.Random r = new java.util.Random();
441 for (int i = 0; i < rows * columns; i++) {
442 m.data[i] = r.nextDouble();
443 }
444
445 return m;
446 }
447
448 /** Creates a row vector with random values uniformly in 0..1. */
449 public static DoubleMatrix rand(int len) {
450 return rand(len, 1);
451 }
452
453 /** Create matrix with normally distributed random values. */
454 public static DoubleMatrix randn(int rows, int columns) {
455 DoubleMatrix m = new DoubleMatrix(rows, columns);
456
457 java.util.Random r = new java.util.Random();
458 for (int i = 0; i < rows * columns; i++) {
459 m.data[i] = (double) r.nextGaussian();
460 }
461
462 return m;
463 }
464
465 /** Create row vector with normally distributed random values. */
466 public static DoubleMatrix randn(int len) {
467 return randn(len, 1);
468 }
469
470 /** Creates a new matrix in which all values are equal 0. */
471 public static DoubleMatrix zeros(int rows, int columns) {
472 return new DoubleMatrix(rows, columns);
473 }
474
475 /** Creates a row vector of given length. */
476 public static DoubleMatrix zeros(int length) {
477 return zeros(length, 1);
478 }
479
480 /** Creates a new matrix in which all values are equal 1. */
481 public static DoubleMatrix ones(int rows, int columns) {
482 DoubleMatrix m = new DoubleMatrix(rows, columns);
483
484 for (int i = 0; i < rows * columns; i++) {
485 m.put(i, 1.0);
486 }
487
488 return m;
489 }
490
491 /** Creates a row vector with all elements equal to 1. */
492 public static DoubleMatrix ones(int length) {
493 return ones(length, 1);
494 }
495
496 /** Construct a new n-by-n identity matrix. */
497 public static DoubleMatrix eye(int n) {
498 DoubleMatrix m = new DoubleMatrix(n, n);
499
500 for (int i = 0; i < n; i++) {
501 m.put(i, i, 1.0);
502 }
503
504 return m;
505 }
506
507 /**
508 * Creates a new matrix where the values of the given vector are the diagonal values of
509 * the matrix.
510 */
511 public static DoubleMatrix diag(DoubleMatrix x) {
512 DoubleMatrix m = new DoubleMatrix(x.length, x.length);
513
514 for (int i = 0; i < x.length; i++) {
515 m.put(i, i, x.get(i));
516 }
517
518 return m;
519 }
520
521 /**
522 * Create a 1-by-1 matrix. For many operations, this matrix functions like a
523 * normal double.
524 */
525 public static DoubleMatrix scalar(double s) {
526 DoubleMatrix m = new DoubleMatrix(1, 1);
527 m.put(0, 0, s);
528 return m;
529 }
530
531 /** Test whether a matrix is scalar. */
532 public boolean isScalar() {
533 return length == 1;
534 }
535
536 /** Return the first element of the matrix. */
537 public double scalar() {
538 return get(0);
539 }
540
541 public static DoubleMatrix logspace(double lower, double upper, int size) {
542 DoubleMatrix result = new DoubleMatrix(size);
543 for (int i = 0; i < size; i++) {
544 double t = (double) i / (size - 1);
545 double e = lower * (1 - t) + t * upper;
546 result.put(i, (double) Math.pow(10.0, e));
547 }
548 return result;
549 }
550
551 public static DoubleMatrix linspace(int lower, int upper, int size) {
552 DoubleMatrix result = new DoubleMatrix(size);
553 for (int i = 0; i < size; i++) {
554 double t = (double) i / (size - 1);
555 result.put(i, lower * (1 - t) + t * upper);
556 }
557 return result;
558 }
559
560 /**
561 * Concatenates two matrices horizontally. Matrices must have identical
562 * numbers of rows.
563 */
564 public static DoubleMatrix concatHorizontally(DoubleMatrix A, DoubleMatrix B) {
565 if (A.rows != B.rows) {
566 throw new SizeException("Matrices don't have same number of rows.");
567 }
568
569 DoubleMatrix result = new DoubleMatrix(A.rows, A.columns + B.columns);
570 SimpleBlas.copy(A, result);
571 JavaBlas.rcopy(B.length, B.data, 0, 1, result.data, A.length, 1);
572 return result;
573 }
574
575 /**
576 * Concatenates two matrices vertically. Matrices must have identical
577 * numbers of columns.
578 */
579 public static DoubleMatrix concatVertically(DoubleMatrix A, DoubleMatrix B) {
580 if (A.columns != B.columns) {
581 throw new SizeException("Matrices don't have same number of columns (" + A.columns + " != " + B.columns + ".");
582 }
583
584 DoubleMatrix result = new DoubleMatrix(A.rows + B.rows, A.columns);
585
586 for (int i = 0; i < A.columns; i++) {
587 JavaBlas.rcopy(A.rows, A.data, A.index(0, i), 1, result.data, result.index(0, i), 1);
588 JavaBlas.rcopy(B.rows, B.data, B.index(0, i), 1, result.data, result.index(A.rows, i), 1);
589 }
590
591 return result;
592 }
593
594 /**************************************************************************
595 * Working with slices (Man! 30+ methods just to make this a bit flexible...)
596 */
597 /** Get all elements specified by the linear indices. */
598 public DoubleMatrix get(int[] indices) {
599 DoubleMatrix result = new DoubleMatrix(indices.length);
600
601 for (int i = 0; i < indices.length; i++) {
602 result.put(i, get(indices[i]));
603 }
604
605 return result;
606 }
607
608 /** Get all elements for a given row and the specified columns. */
609 public DoubleMatrix get(int r, int[] indices) {
610 DoubleMatrix result = new DoubleMatrix(1, indices.length);
611
612 for (int i = 0; i < indices.length; i++) {
613 result.put(i, get(r, indices[i]));
614 }
615
616 return result;
617 }
618
619 /** Get all elements for a given column and the specified rows. */
620 public DoubleMatrix get(int[] indices, int c) {
621 DoubleMatrix result = new DoubleMatrix(indices.length, c);
622
623 for (int i = 0; i < indices.length; i++) {
624 result.put(i, get(indices[i], c));
625 }
626
627 return result;
628 }
629
630 /** Get all elements from the specified rows and columns. */
631 public DoubleMatrix get(int[] rindices, int[] cindices) {
632 DoubleMatrix result = new DoubleMatrix(rindices.length, cindices.length);
633
634 for (int i = 0; i < rindices.length; i++) {
635 for (int j = 0; j < cindices.length; j++) {
636 result.put(i, j, get(rindices[i], cindices[j]));
637 }
638 }
639
640 return result;
641 }
642
643 /** Get elements from specified rows and columns. */
644 public DoubleMatrix get(Range rs, Range cs) {
645 rs.init(0, rows);
646 cs.init(0, columns);
647 DoubleMatrix result = new DoubleMatrix(rs.length(), cs.length());
648
649 for (; !rs.hasMore(); rs.next()) {
650 for (; !cs.hasMore(); cs.next()) {
651 result.put(rs.index(), cs.index(), get(rs.value(), cs.value()));
652 }
653 }
654
655 return result;
656 }
657
658 /** Get elements specified by the non-zero entries of the passed matrix. */
659 public DoubleMatrix get(DoubleMatrix indices) {
660 return get(indices.findIndices());
661 }
662
663 /**
664 * Get elements from a row and columns as specified by the non-zero entries of
665 * a matrix.
666 */
667 public DoubleMatrix get(int r, DoubleMatrix indices) {
668 return get(r, indices.findIndices());
669 }
670
671 /**
672 * Get elements from a column and rows as specified by the non-zero entries of
673 * a matrix.
674 */
675 public DoubleMatrix get(DoubleMatrix indices, int c) {
676 return get(indices.findIndices(), c);
677 }
678
679 /**
680 * Get elements from columns and rows as specified by the non-zero entries of
681 * the passed matrices.
682 */
683 public DoubleMatrix get(DoubleMatrix rindices, DoubleMatrix cindices) {
684 return get(rindices.findIndices(), cindices.findIndices());
685 }
686
687 /** Return all elements with linear index a, a + 1, ..., b - 1.*/
688 public DoubleMatrix getRange(int a, int b) {
689 DoubleMatrix result = new DoubleMatrix(b - a);
690
691 for (int k = 0; k < b - a; k++) {
692 result.put(k, get(a + k));
693 }
694
695 return result;
696 }
697
698 /** Get elements from a row and columns <tt>a</tt> to <tt>b</tt>. */
699 public DoubleMatrix getColumnRange(int r, int a, int b) {
700 DoubleMatrix result = new DoubleMatrix(1, b - a);
701
702 for (int k = 0; k < b - a; k++) {
703 result.put(k, get(r, a + k));
704 }
705
706 return result;
707 }
708
709 /** Get elements from a column and rows <tt>a/tt> to <tt>b</tt>. */
710 public DoubleMatrix getRowRange(int a, int b, int c) {
711 DoubleMatrix result = new DoubleMatrix(b - a);
712
713 for (int k = 0; k < b - a; k++) {
714 result.put(k, get(a + k, c));
715 }
716
717 return result;
718 }
719
720 /**
721 * Get elements from rows <tt>ra</tt> to <tt>rb</tt> and
722 * columns <tt>ca</tt> to <tt>cb</tt>.
723 */
724 public DoubleMatrix getRange(int ra, int rb, int ca, int cb) {
725 DoubleMatrix result = new DoubleMatrix(rb - ra, cb - ca);
726
727 for (int i = 0; i < rb - ra; i++) {
728 for (int j = 0; j < cb - ca; j++) {
729 result.put(i, j, get(ra + i, ca + j));
730 }
731 }
732
733 return result;
734 }
735
736 /** Get whole rows from the passed indices. */
737 public DoubleMatrix getRows(int[] rindices) {
738 DoubleMatrix result = new DoubleMatrix(rindices.length, columns);
739 for (int i = 0; i < rindices.length; i++) {
740 JavaBlas.rcopy(columns, data, index(rindices[i], 0), rows, result.data, result.index(i, 0), result.rows);
741 }
742 return result;
743 }
744
745 /** Get whole rows as specified by the non-zero entries of a matrix. */
746 public DoubleMatrix getRows(DoubleMatrix rindices) {
747 return getRows(rindices.findIndices());
748 }
749
750 public DoubleMatrix getRows(Range indices, DoubleMatrix result) {
751 indices.init(0, rows);
752 if (result.rows < indices.length()) {
753 throw new SizeException("Result matrix does not have enough rows (" + result.rows + " < " + indices.length() + ")");
754 }
755 result.checkColumns(columns);
756
757 for (int c = 0; c < columns; c++) {
758 indices.init(0, rows);
759 for (int r = 0; indices.hasMore(); indices.next(), r++) {
760 result.put(r, c, get(indices.index(), c));
761 }
762 }
763 return result;
764 }
765
766 public DoubleMatrix getRows(Range indices) {
767 indices.init(0, rows);
768 DoubleMatrix result = new DoubleMatrix(indices.length(), columns);
769 return getRows(indices, result);
770 }
771
772 /** Get whole columns from the passed indices. */
773 public DoubleMatrix getColumns(int[] cindices) {
774 DoubleMatrix result = new DoubleMatrix(rows, cindices.length);
775 for (int i = 0; i < cindices.length; i++) {
776 JavaBlas.rcopy(rows, data, index(0, cindices[i]), 1, result.data, result.index(0, i), 1);
777 }
778 return result;
779 }
780
781 /** Get whole columns as specified by the non-zero entries of a matrix. */
782 public DoubleMatrix getColumns(DoubleMatrix cindices) {
783 return getColumns(cindices.findIndices());
784 }
785
786 /**
787 * Assert that the matrix has a certain length.
788 * @throws SizeException
789 */
790 public void checkLength(int l) {
791 if (length != l) {
792 throw new SizeException("Matrix does not have the necessary length (" + length + " != " + l + ").");
793 }
794 }
795
796 /**
797 * Asserts that the matrix has a certain number of rows.
798 * @throws SizeException
799 */
800 public void checkRows(int r) {
801 if (rows != r) {
802 throw new SizeException("Matrix does not have the necessary number of rows (" + rows + " != " + r + ").");
803 }
804 }
805
806 /**
807 * Asserts that the amtrix has a certain number of columns.
808 * @throws SizeException
809 */
810 public void checkColumns(int c) {
811 if (columns != c) {
812 throw new SizeException("Matrix does not have the necessary number of columns (" + columns + " != " + c + ").");
813 }
814 }
815
816 /** Set elements in linear ordering in the specified indices. */
817 public DoubleMatrix put(int[] indices, DoubleMatrix x) {
818 if (x.isScalar()) {
819 return put(indices, x.scalar());
820 }
821 x.checkLength(indices.length);
822
823 for (int i = 0; i < indices.length; i++) {
824 put(indices[i], x.get(i));
825 }
826
827 return this;
828 }
829
830 /** Set multiple elements in a row. */
831 public DoubleMatrix put(int r, int[] indices, DoubleMatrix x) {
832 if (x.isScalar()) {
833 return put(r, indices, x.scalar());
834 }
835 x.checkColumns(indices.length);
836
837 for (int i = 0; i < indices.length; i++) {
838 put(r, indices[i], x.get(i));
839 }
840
841 return this;
842 }
843
844 /** Set multiple elements in a row. */
845 public DoubleMatrix put(int[] indices, int c, DoubleMatrix x) {
846 if (x.isScalar()) {
847 return put(indices, c, x.scalar());
848 }
849 x.checkRows(indices.length);
850
851 for (int i = 0; i < indices.length; i++) {
852 put(indices[i], c, x.get(i));
853 }
854
855 return this;
856 }
857
858 /** Put a sub-matrix as specified by the indices. */
859 public DoubleMatrix put(int[] rindices, int[] cindices, DoubleMatrix x) {
860 if (x.isScalar()) {
861 return put(rindices, cindices, x.scalar());
862 }
863 x.checkRows(rindices.length);
864 x.checkColumns(cindices.length);
865
866 for (int i = 0; i < rindices.length; i++) {
867 for (int j = 0; j < cindices.length; j++) {
868 put(rindices[i], cindices[j], x.get(i, j));
869 }
870 }
871
872 return this;
873 }
874
875 /** Put a matrix into specified indices. */
876 public DoubleMatrix put(Range rs, Range cs, DoubleMatrix x) {
877 rs.init(0, rows);
878 cs.init(0, columns);
879
880 x.checkRows(rs.length());
881 x.checkColumns(cs.length());
882
883 for (; rs.hasMore(); rs.next()) {
884 for (; cs.hasMore(); cs.next()) {
885 put(rs.value(), cs.value(), x.get(rs.index(), cs.index()));
886 }
887 }
888
889 return this;
890 }
891
892 /** Put a single value into the specified indices (linear adressing). */
893 public DoubleMatrix put(int[] indices, double v) {
894 for (int i = 0; i < indices.length; i++) {
895 put(indices[i], v);
896 }
897
898 return this;
899 }
900
901 /** Put a single value into a row and the specified columns. */
902 public DoubleMatrix put(int r, int[] indices, double v) {
903 for (int i = 0; i < indices.length; i++) {
904 put(r, indices[i], v);
905 }
906
907 return this;
908 }
909
910 /** Put a single value into the specified rows of a column. */
911 public DoubleMatrix put(int[] indices, int c, double v) {
912 for (int i = 0; i < indices.length; i++) {
913 put(indices[i], c, v);
914 }
915
916 return this;
917 }
918
919 /** Put a single value into the specified rows and columns. */
920 public DoubleMatrix put(int[] rindices, int[] cindices, double v) {
921 for (int i = 0; i < rindices.length; i++) {
922 for (int j = 0; j < cindices.length; j++) {
923 put(rindices[i], cindices[j], v);
924 }
925 }
926
927 return this;
928 }
929
930 /**
931 * Put a sub-matrix into the indices specified by the non-zero entries
932 * of <tt>indices</tt> (linear adressing).
933 */
934 public DoubleMatrix put(DoubleMatrix indices, DoubleMatrix v) {
935 return put(indices.findIndices(), v);
936 }
937
938 /** Put a sub-vector into the specified columns (non-zero entries of <tt>indices</tt>) of a row. */
939 public DoubleMatrix put(int r, DoubleMatrix indices, DoubleMatrix v) {
940 return put(r, indices.findIndices(), v);
941 }
942
943 /** Put a sub-vector into the specified rows (non-zero entries of <tt>indices</tt>) of a column. */
944 public DoubleMatrix put(DoubleMatrix indices, int c, DoubleMatrix v) {
945 return put(indices.findIndices(), c, v);
946 }
947
948 /**
949 * Put a sub-matrix into the specified rows and columns (non-zero entries of
950 * <tt>rindices</tt> and <tt>cindices</tt>.
951 */
952 public DoubleMatrix put(DoubleMatrix rindices, DoubleMatrix cindices, DoubleMatrix v) {
953 return put(rindices.findIndices(), cindices.findIndices(), v);
954 }
955
956 /**
957 * Put a single value into the elements specified by the non-zero
958 * entries of <tt>indices</tt> (linear adressing).
959 */
960 public DoubleMatrix put(DoubleMatrix indices, double v) {
961 return put(indices.findIndices(), v);
962 }
963
964 /**
965 * Put a single value into the specified columns (non-zero entries of
966 * <tt>indices</tt>) of a row.
967 */
968 public DoubleMatrix put(int r, DoubleMatrix indices, double v) {
969 return put(r, indices.findIndices(), v);
970 }
971
972 /**
973 * Put a single value into the specified rows (non-zero entries of
974 * <tt>indices</tt>) of a column.
975 */
976 public DoubleMatrix put(DoubleMatrix indices, int c, double v) {
977 return put(indices.findIndices(), c, v);
978 }
979
980 /**
981 * Put a single value in the specified rows and columns (non-zero entries
982 * of <tt>rindices</tt> and <tt>cindices</tt>.
983 */
984 public DoubleMatrix put(DoubleMatrix rindices, DoubleMatrix cindices, double v) {
985 return put(rindices.findIndices(), cindices.findIndices(), v);
986 }
987
988 /** Find the linear indices of all non-zero elements. */
989 public int[] findIndices() {
990 int len = 0;
991 for (int i = 0; i < length; i++) {
992 if (get(i) != 0.0) {
993 len++;
994 }
995 }
996
997 int[] indices = new int[len];
998 int c = 0;
999
1000 for (int i = 0; i < length; i++) {
1001 if (get(i) != 0.0) {
1002 indices[c++] = i;
1003 }
1004 }
1005
1006 return indices;
1007 }
1008
1009 /**************************************************************************
1010 * Basic operations (copying, resizing, element access)
1011 */
1012 /** Return transposed copy of this matrix. */
1013 public DoubleMatrix transpose() {
1014 DoubleMatrix result = new DoubleMatrix(columns, rows);
1015
1016 for (int i = 0; i < rows; i++) {
1017 for (int j = 0; j < columns; j++) {
1018 result.put(j, i, get(i, j));
1019 }
1020 }
1021
1022 return result;
1023 }
1024
1025 /**
1026 * Compare two matrices. Returns true if and only if other is also a
1027 * DoubleMatrix which has the same size and the maximal absolute
1028 * difference in matrix elements is smaller thatn 1e-6.
1029 */
1030 public boolean equals(Object o) {
1031 if (!(o instanceof DoubleMatrix)) {
1032 return false;
1033 }
1034
1035 DoubleMatrix other = (DoubleMatrix) o;
1036
1037 if (!sameSize(other)) {
1038 return false;
1039 }
1040
1041 DoubleMatrix diff = MatrixFunctions.absi(sub(other));
1042
1043 return diff.max() / (rows * columns) < 1e-6;
1044 }
1045
1046 /** Resize the matrix. All elements will be set to zero. */
1047 public void resize(int newRows, int newColumns) {
1048 rows = newRows;
1049 columns = newColumns;
1050 length = newRows * newColumns;
1051 data = new double[rows * columns];
1052 }
1053
1054 /** Reshape the matrix. Number of elements must not change. */
1055 public DoubleMatrix reshape(int newRows, int newColumns) {
1056 if (length != newRows * newColumns) {
1057 throw new IllegalArgumentException(
1058 "Number of elements must not change.");
1059 }
1060
1061 rows = newRows;
1062 columns = newColumns;
1063
1064 return this;
1065 }
1066
1067 /** Generate a new matrix which has the given number of replications of this. */
1068 public DoubleMatrix repmat(int rowMult, int columnMult) {
1069 DoubleMatrix result = new DoubleMatrix(rows * rowMult, columns * columnMult);
1070
1071 for (int c = 0; c < columnMult; c++) {
1072 for (int r = 0; r < rowMult; r++) {
1073 for (int i = 0; i < rows; i++) {
1074 for (int j = 0; j < columns; j++) {
1075 result.put(r * rows + i, c * columns + j, get(i, j));
1076 }
1077 }
1078 }
1079 }
1080 return result;
1081 }
1082
1083 /** Checks whether two matrices have the same size. */
1084 public boolean sameSize(DoubleMatrix a) {
1085 return rows == a.rows && columns == a.columns;
1086 }
1087
1088 /** Throws SizeException unless two matrices have the same size. */
1089 public void assertSameSize(DoubleMatrix a) {
1090 if (!sameSize(a)) {
1091 throw new SizeException("Matrices must have the same size.");
1092 }
1093 }
1094
1095 /** Checks whether two matrices can be multiplied (that is, number of columns of
1096 * this must equal number of rows of a. */
1097 public boolean multipliesWith(DoubleMatrix a) {
1098 return columns == a.rows;
1099 }
1100
1101 /** Throws SizeException unless matrices can be multiplied with one another. */
1102 public void assertMultipliesWith(DoubleMatrix a) {
1103 if (!multipliesWith(a)) {
1104 throw new SizeException("Number of columns of left matrix must be equal to number of rows of right matrix.");
1105 }
1106 }
1107
1108 /** Checks whether two matrices have the same length. */
1109 public boolean sameLength(DoubleMatrix a) {
1110 return length == a.length;
1111 }
1112
1113 /** Throws SizeException unless matrices have the same length. */
1114 public void assertSameLength(DoubleMatrix a) {
1115 if (!sameLength(a)) {
1116 throw new SizeException("Matrices must have same length (is: " + length + " and " + a.length + ")");
1117 }
1118 }
1119
1120 /** Copy DoubleMatrix a to this. this a is resized if necessary. */
1121 public DoubleMatrix copy(DoubleMatrix a) {
1122 if (!sameSize(a)) {
1123 resize(a.rows, a.columns);
1124 }
1125
1126 System.arraycopy(a.data, 0, data, 0, length);
1127 return a;
1128 }
1129
1130 /**
1131 * Returns a duplicate of this matrix. Geometry is the same (including offsets, transpose, etc.),
1132 * but the buffer is not shared.
1133 */
1134 public DoubleMatrix dup() {
1135 DoubleMatrix out = new DoubleMatrix(rows, columns);
1136
1137 JavaBlas.rcopy(length, data, 0, 1, out.data, 0, 1);
1138
1139 return out;
1140 }
1141
1142 /** Swap two columns of a matrix. */
1143 public DoubleMatrix swapColumns(int i, int j) {
1144 NativeBlas.dswap(rows, data, index(0, i), 1, data, index(0, j), 1);
1145 return this;
1146 }
1147
1148 /** Swap two rows of a matrix. */
1149 public DoubleMatrix swapRows(int i, int j) {
1150 NativeBlas.dswap(columns, data, index(i, 0), rows, data, index(j, 0), rows);
1151 return this;
1152 }
1153
1154 /** Set matrix element */
1155 public DoubleMatrix put(int rowIndex, int columnIndex, double value) {
1156 data[index(rowIndex, columnIndex)] = value;
1157 return this;
1158 }
1159
1160 /** Retrieve matrix element */
1161 public double get(int rowIndex, int columnIndex) {
1162 return data[index(rowIndex, columnIndex)];
1163 }
1164
1165 /** Get index of an element */
1166 public int index(int rowIndex, int columnIndex) {
1167 return rowIndex + rows * columnIndex;
1168 }
1169
1170 /** Compute the row index of a linear index. */
1171 public int indexRows(int i) {
1172 return i / rows;
1173 }
1174
1175 /** Compute the column index of a linear index. */
1176 public int indexColumns(int i) {
1177 return i - indexRows(i) * rows;
1178 }
1179
1180 /** Get a matrix element (linear indexing). */
1181 public double get(int i) {
1182 return data[i];
1183 }
1184
1185 /** Set a matrix element (linear indexing). */
1186 public DoubleMatrix put(int i, double v) {
1187 data[i] = v;
1188 return this;
1189 }
1190
1191 /** Set all elements to a value. */
1192 public DoubleMatrix fill(double value) {
1193 for (int i = 0; i < length; i++) {
1194 put(i, value);
1195 }
1196 return this;
1197 }
1198
1199 /** Get number of rows. */
1200 public int getRows() {
1201 return rows;
1202 }
1203
1204 /** Get number of columns. */
1205 public int getColumns() {
1206 return columns;
1207 }
1208
1209 /** Get total number of elements. */
1210 public int getLength() {
1211 return length;
1212 }
1213
1214 /** Checks whether the matrix is empty. */
1215 public boolean isEmpty() {
1216 return columns == 0 || rows == 0;
1217 }
1218
1219 /** Checks whether the matrix is square. */
1220 public boolean isSquare() {
1221 return columns == rows;
1222 }
1223
1224 /** Throw SizeException unless matrix is square. */
1225 public void assertSquare() {
1226 if (!isSquare()) {
1227 throw new SizeException("Matrix must be square!");
1228 }
1229 }
1230
1231 /** Checks whether the matrix is a vector. */
1232 public boolean isVector() {
1233 return columns == 1 || rows == 1;
1234 }
1235
1236 /** Checks whether the matrix is a row vector. */
1237 public boolean isRowVector() {
1238 return rows == 1;
1239 }
1240
1241 /** Checks whether the matrix is a column vector. */
1242 public boolean isColumnVector() {
1243 return columns == 1;
1244 }
1245
1246 /** Returns the diagonal of the matrix. */
1247 public DoubleMatrix diag() {
1248 assertSquare();
1249 DoubleMatrix d = new DoubleMatrix(rows);
1250 JavaBlas.rcopy(rows, data, 0, rows + 1, d.data, 0, 1);
1251 return d;
1252 }
1253
1254 /** Pretty-print this matrix to <tt>System.out</tt>. */
1255 public void print() {
1256 System.out.println(toString());
1257 }
1258
1259 /** Generate string representation of the matrix. */
1260 @Override
1261 public String toString() {
1262 StringBuilder s = new StringBuilder();
1263
1264 s.append("[");
1265
1266 for (int i = 0; i < rows; i++) {
1267 for (int j = 0; j < columns; j++) {
1268 s.append(get(i, j));
1269 if (j < columns - 1) {
1270 s.append(", ");
1271 }
1272 }
1273 if (i < rows - 1) {
1274 s.append("; ");
1275 }
1276 }
1277
1278 s.append("]");
1279
1280 return s.toString();
1281 }
1282
1283 /**
1284 * Generate string representation of the matrix, with specified
1285 * format for the entries. For example, <code>x.toString("%.1f")</code>
1286 * generates a string representations having only one position after the
1287 * decimal point.
1288 */
1289 public String toString(String fmt) {
1290 StringWriter s = new StringWriter();
1291 PrintWriter p = new PrintWriter(s);
1292
1293 p.print("[");
1294
1295 for (int r = 0; r < rows; r++) {
1296 for (int c = 0; c < columns; c++) {
1297 p.printf(fmt, get(r, c));
1298 if (c < columns - 1) {
1299 p.print(", ");
1300 }
1301 }
1302 if (r < rows - 1) {
1303 p.print("; ");
1304 }
1305 }
1306
1307 p.print("]");
1308
1309 return s.toString();
1310 }
1311
1312 /** Converts the matrix to a one-dimensional array of doubles. */
1313 public double[] toArray() {
1314 double[] array = new double[length];
1315
1316 System.arraycopy(data, 0, array, 0, length);
1317
1318 return array;
1319 }
1320
1321 /** Converts the matrix to a two-dimensional array of doubles. */
1322 public double[][] toArray2() {
1323 double[][] array = new double[rows][columns];
1324
1325 for (int r = 0; r < rows; r++) {
1326 for (int c = 0; c < columns; c++) {
1327 array[r][c] = get(r, c);
1328 }
1329 }
1330
1331 return array;
1332 }
1333
1334 /** Converts the matrix to a one-dimensional array of integers. */
1335 public int[] toIntArray() {
1336 int[] array = new int[length];
1337
1338 for (int i = 0; i < length; i++) {
1339 array[i] = (int) Math.rint(get(i));
1340 }
1341
1342 return array;
1343 }
1344
1345 /** Convert the matrix to a two-dimensional array of integers. */
1346 public int[][] toIntArray2() {
1347 int[][] array = new int[rows][columns];
1348
1349 for (int r = 0; r < rows; r++) {
1350 for (int c = 0; c < columns; c++) {
1351 array[r][c] = (int) Math.rint(get(r, c));
1352 }
1353 }
1354
1355 return array;
1356 }
1357
1358 /** Convert the matrix to a one-dimensional array of boolean values. */
1359 public boolean[] toBooleanArray() {
1360 boolean[] array = new boolean[length];
1361
1362 for (int i = 0; i < length; i++) {
1363 array[i] = get(i) != 0.0 ? true : false;
1364 }
1365
1366 return array;
1367 }
1368
1369 /** Convert the matrix to a two-dimensional array of boolean values. */
1370 public boolean[][] toBooleanArray2() {
1371 boolean[][] array = new boolean[rows][columns];
1372
1373 for (int r = 0; r < rows; r++) {
1374 for (int c = 0; c < columns; c++) {
1375 array[r][c] = get(r, c) != 0.0 ? true : false;
1376 }
1377 }
1378
1379 return array;
1380 }
1381
1382 /** Convert matrix to FloatMatrix. */
1383 public FloatMatrix toFloatMatrix() {
1384 FloatMatrix result = new FloatMatrix(rows, columns);
1385
1386 for (int c = 0; c < columns; c++) {
1387 for (int r = 0; r < rows; r++) {
1388 result.put(r, c, (float) get(r, c));
1389 }
1390 }
1391
1392 return result;
1393 }
1394
1395 /**
1396 * A wrapper which allows to view a matrix as a List of Doubles (read-only!).
1397 * Also implements the {@link ConvertsToDoubleMatrix} interface.
1398 */
1399 public class ElementsAsListView extends AbstractList<Double> implements ConvertsToDoubleMatrix {
1400
1401 private DoubleMatrix me;
1402
1403 public ElementsAsListView(DoubleMatrix me) {
1404 this.me = me;
1405 }
1406
1407 @Override
1408 public Double get(int index) {
1409 return me.get(index);
1410 }
1411
1412 @Override
1413 public int size() {
1414 return me.length;
1415 }
1416
1417 public DoubleMatrix convertToDoubleMatrix() {
1418 return me;
1419 }
1420 }
1421
1422 public class RowsAsListView extends AbstractList<DoubleMatrix> implements ConvertsToDoubleMatrix {
1423
1424 private DoubleMatrix me;
1425
1426 public RowsAsListView(DoubleMatrix me) {
1427 this.me = me;
1428 }
1429
1430 @Override
1431 public DoubleMatrix get(int index) {
1432 return getRow(index);
1433 }
1434
1435 @Override
1436 public int size() {
1437 return rows;
1438 }
1439
1440 public DoubleMatrix convertToDoubleMatrix() {
1441 return me;
1442 }
1443 }
1444
1445 public class ColumnsAsListView extends AbstractList<DoubleMatrix> implements ConvertsToDoubleMatrix {
1446
1447 private DoubleMatrix me;
1448
1449 public ColumnsAsListView(DoubleMatrix me) {
1450 this.me = me;
1451 }
1452
1453 @Override
1454 public DoubleMatrix get(int index) {
1455 return getColumn(index);
1456 }
1457
1458 @Override
1459 public int size() {
1460 return columns;
1461 }
1462
1463 public DoubleMatrix convertToDoubleMatrix() {
1464 return me;
1465 }
1466 }
1467
1468 public List<Double> elementsAsList() {
1469 return new ElementsAsListView(this);
1470 }
1471
1472 public List<DoubleMatrix> rowsAsList() {
1473 return new RowsAsListView(this);
1474 }
1475
1476 public List<DoubleMatrix> columnsAsList() {
1477 return new ColumnsAsListView(this);
1478 }
1479
1480 /**************************************************************************
1481 * Arithmetic Operations
1482 */
1483 /**
1484 * Ensures that the result vector has the same length as this. If not,
1485 * resizing result is tried, which fails if result == this or result == other.
1486 */
1487 private void ensureResultLength(DoubleMatrix other, DoubleMatrix result) {
1488 if (!sameLength(result)) {
1489 if (result == this || result == other) {
1490 throw new SizeException("Cannot resize result matrix because it is used in-place.");
1491 }
1492 result.resize(rows, columns);
1493 }
1494 }
1495
1496 /** Add two matrices (in-place). */
1497 public DoubleMatrix addi(DoubleMatrix other, DoubleMatrix result) {
1498 if (other.isScalar()) {
1499 return addi(other.scalar(), result);
1500 }
1501 if (isScalar()) {
1502 return other.addi(scalar(), result);
1503 }
1504
1505 assertSameLength(other);
1506 ensureResultLength(other, result);
1507
1508 if (result == this) {
1509 SimpleBlas.axpy(1.0, other, result);
1510 } else if (result == other) {
1511 SimpleBlas.axpy(1.0, this, result);
1512 } else {
1513 /*SimpleBlas.copy(this, result);
1514 SimpleBlas.axpy(1.0, other, result);*/
1515 JavaBlas.rzgxpy(length, result.data, data, other.data);
1516 }
1517
1518 return result;
1519 }
1520
1521 /** Add a scalar to a matrix (in-place). */
1522 public DoubleMatrix addi(double v, DoubleMatrix result) {
1523 ensureResultLength(null, result);
1524
1525 for (int i = 0; i < length; i++) {
1526 result.put(i, get(i) + v);
1527 }
1528 return result;
1529 }
1530
1531 /** Subtract two matrices (in-place). */
1532 public DoubleMatrix subi(DoubleMatrix other, DoubleMatrix result) {
1533 if (other.isScalar()) {
1534 return subi(other.scalar(), result);
1535 }
1536 if (isScalar()) {
1537 return other.rsubi(scalar(), result);
1538 }
1539
1540 assertSameLength(other);
1541 ensureResultLength(other, result);
1542
1543 if (result == this) {
1544 SimpleBlas.axpy(-1.0, other, result);
1545 } else if (result == other) {
1546 SimpleBlas.scal(-1.0, result);
1547 SimpleBlas.axpy(1.0, this, result);
1548 } else {
1549 SimpleBlas.copy(this, result);
1550 SimpleBlas.axpy(-1.0, other, result);
1551 }
1552 return result;
1553 }
1554
1555 /** Subtract a scalar from a matrix (in-place). */
1556 public DoubleMatrix subi(double v, DoubleMatrix result) {
1557 ensureResultLength(null, result);
1558
1559 for (int i = 0; i < length; i++) {
1560 result.put(i, get(i) - v);
1561 }
1562 return result;
1563 }
1564
1565 /**
1566 * Subtract two matrices, but subtract first from second matrix, that is,
1567 * compute <em>result = other - this</em> (in-place).
1568 * */
1569 public DoubleMatrix rsubi(DoubleMatrix other, DoubleMatrix result) {
1570 return other.subi(this, result);
1571 }
1572
1573 /** Subtract a matrix from a scalar (in-place). */
1574 public DoubleMatrix rsubi(double a, DoubleMatrix result) {
1575 ensureResultLength(null, result);
1576
1577 for (int i = 0; i < length; i++) {
1578 result.put(i, a - get(i));
1579 }
1580 return result;
1581 }
1582
1583 /** Elementwise multiplication (in-place). */
1584 public DoubleMatrix muli(DoubleMatrix other, DoubleMatrix result) {
1585 if (other.isScalar()) {
1586 return muli(other.scalar(), result);
1587 }
1588 if (isScalar()) {
1589 return other.muli(scalar(), result);
1590 }
1591
1592 assertSameLength(other);
1593 ensureResultLength(other, result);
1594
1595 for (int i = 0; i < length; i++) {
1596 result.put(i, get(i) * other.get(i));
1597 }
1598 return result;
1599 }
1600
1601 /** Elementwise multiplication with a scalar (in-place). */
1602 public DoubleMatrix muli(double v, DoubleMatrix result) {
1603 ensureResultLength(null, result);
1604
1605 for (int i = 0; i < length; i++) {
1606 result.put(i, get(i) * v);
1607 }
1608 return result;
1609 }
1610
1611 /** Matrix-matrix multiplication (in-place). */
1612 public DoubleMatrix mmuli(DoubleMatrix other, DoubleMatrix result) {
1613 if (other.isScalar()) {
1614 return muli(other.scalar(), result);
1615 }
1616 if (isScalar()) {
1617 return other.muli(scalar(), result);
1618 }
1619
1620 /* check sizes and resize if necessary */
1621 assertMultipliesWith(other);
1622 if (result.rows != rows || result.columns != other.columns) {
1623 if (result != this && result != other) {
1624 result.resize(rows, other.columns);
1625 } else {
1626 throw new SizeException("Cannot resize result matrix because it is used in-place.");
1627 }
1628 }
1629
1630 if (result == this || result == other) {
1631 /* actually, blas cannot do multiplications in-place. Therefore, we will fake by
1632 * allocating a temporary object on the side and copy the result later.
1633 */
1634 DoubleMatrix temp = new DoubleMatrix(result.rows, result.columns);
1635 if (other.columns == 1) {
1636 SimpleBlas.gemv(1.0, this, other, 0.0, temp);
1637 } else {
1638 SimpleBlas.gemm(1.0, this, other, 0.0, temp);
1639 }
1640 SimpleBlas.copy(temp, result);
1641 } else {
1642 if (other.columns == 1) {
1643 SimpleBlas.gemv(1.0, this, other, 0.0, result);
1644 } else {
1645 SimpleBlas.gemm(1.0, this, other, 0.0, result);
1646 }
1647 }
1648 return result;
1649 }
1650
1651 /** Matrix-matrix multiplication with a scalar (for symmetry, does the
1652 * same as <code>muli(scalar)</code> (in-place).
1653 */
1654 public DoubleMatrix mmuli(double v, DoubleMatrix result) {
1655 return muli(v, result);
1656 }
1657
1658 /** Elementwise division (in-place). */
1659 public DoubleMatrix divi(DoubleMatrix other, DoubleMatrix result) {
1660 if (other.isScalar()) {
1661 return divi(other.scalar(), result);
1662 }
1663 if (isScalar()) {
1664 return other.rdivi(scalar(), result);
1665 }
1666
1667 assertSameLength(other);
1668 ensureResultLength(other, result);
1669
1670 for (int i = 0; i < length; i++) {
1671 result.put(i, get(i) / other.get(i));
1672 }
1673 return result;
1674 }
1675
1676 /** Elementwise division with a scalar (in-place). */
1677 public DoubleMatrix divi(double a, DoubleMatrix result) {
1678 ensureResultLength(null, result);
1679
1680 for (int i = 0; i < length; i++) {
1681 result.put(i, get(i) / a);
1682 }
1683 return result;
1684 }
1685
1686 /**
1687 * Elementwise division, with operands switched. Computes
1688 * <code>result = other / this</code> (in-place). */
1689 public DoubleMatrix rdivi(DoubleMatrix other, DoubleMatrix result) {
1690 return other.divi(this, result);
1691 }
1692
1693 /** (Elementwise) division with a scalar, with operands switched. Computes
1694 * <code>result = a / this</code> (in-place). */
1695 public DoubleMatrix rdivi(double a, DoubleMatrix result) {
1696 ensureResultLength(null, result);
1697
1698 for (int i = 0; i < length; i++) {
1699 result.put(i, a / get(i));
1700 }
1701 return result;
1702 }
1703
1704 /** Negate each element (in-place). */
1705 public DoubleMatrix negi() {
1706 for (int i = 0; i < length; i++) {
1707 put(i, -get(i));
1708 }
1709 return this;
1710 }
1711
1712 /** Negate each element. */
1713 public DoubleMatrix neg() {
1714 return dup().negi();
1715 }
1716
1717 /** Maps zero to 1.0 and all non-zero values to 0.0 (in-place). */
1718 public DoubleMatrix noti() {
1719 for (int i = 0; i < length; i++) {
1720 put(i, get(i) == 0.0 ? 1.0 : 0.0);
1721 }
1722 return this;
1723 }
1724
1725 /** Maps zero to 1.0 and all non-zero values to 0.0. */
1726 public DoubleMatrix not() {
1727 return dup().noti();
1728 }
1729
1730 /** Maps zero to 0.0 and all non-zero values to 1.0 (in-place). */
1731 public DoubleMatrix truthi() {
1732 for (int i = 0; i < length; i++) {
1733 put(i, get(i) == 0.0 ? 0.0 : 1.0);
1734 }
1735 return this;
1736 }
1737
1738 /** Maps zero to 0.0 and all non-zero values to 1.0. */
1739 public DoubleMatrix truth() {
1740 return dup().truthi();
1741 }
1742
1743 public DoubleMatrix isNaNi() {
1744 for (int i = 0; i < length; i++) {
1745 put(i, Double.isNaN(get(i)) ? 1.0 : 0.0);
1746 }
1747 return this;
1748 }
1749
1750 public DoubleMatrix isNaN() {
1751 return dup().isNaNi();
1752 }
1753
1754 public DoubleMatrix isInfinitei() {
1755 for (int i = 0; i < length; i++) {
1756 put(i, Double.isInfinite(get(i)) ? 1.0 : 0.0);
1757 }
1758 return this;
1759 }
1760
1761 public DoubleMatrix isInfinite() {
1762 return dup().isInfinitei();
1763 }
1764
1765 public DoubleMatrix selecti(DoubleMatrix where) {
1766 checkLength(where.length);
1767 for (int i = 0; i < length; i++) {
1768 if (where.get(i) == 0.0) {
1769 put(i, 0.0);
1770 }
1771 }
1772 return this;
1773 }
1774
1775 public DoubleMatrix select(DoubleMatrix where) {
1776 return dup().selecti(where);
1777 }
1778
1779 /****************************************************************
1780 * Rank one-updates
1781 */
1782 /** Computes a rank-1-update A = A + alpha * x * y'. */
1783 public DoubleMatrix rankOneUpdate(double alpha, DoubleMatrix x, DoubleMatrix y) {
1784 if (rows != x.length) {
1785 throw new SizeException("Vector x has wrong length (" + x.length + " != " + rows + ").");
1786 }
1787 if (columns != y.length) {
1788 throw new SizeException("Vector y has wrong length (" + x.length + " != " + columns + ").");
1789 }
1790
1791 SimpleBlas.ger(alpha, x, y, this);
1792 return this;
1793 }
1794
1795 /** Computes a rank-1-update A = A + alpha * x * x'. */
1796 public DoubleMatrix rankOneUpdate(double alpha, DoubleMatrix x) {
1797 return rankOneUpdate(alpha, x, x);
1798 }
1799
1800 /** Computes a rank-1-update A = A + x * x'. */
1801 public DoubleMatrix rankOneUpdate(DoubleMatrix x) {
1802 return rankOneUpdate(1.0, x, x);
1803 }
1804
1805 /** Computes a rank-1-update A = A + x * y'. */
1806 public DoubleMatrix rankOneUpdate(DoubleMatrix x, DoubleMatrix y) {
1807 return rankOneUpdate(1.0, x, y);
1808 }
1809
1810 /****************************************************************
1811 * Logical operations
1812 */
1813 /** Returns the minimal element of the matrix. */
1814 public double min() {
1815 if (isEmpty()) {
1816 return Double.POSITIVE_INFINITY;
1817 }
1818 double v = Double.POSITIVE_INFINITY;
1819 for (int i = 0; i < length; i++) {
1820 if (!Double.isNaN(get(i)) && get(i) < v) {
1821 v = get(i);
1822 }
1823 }
1824
1825 return v;
1826 }
1827
1828 /**
1829 * Returns the linear index of the minimal element. If there are
1830 * more than one elements with this value, the first one is returned.
1831 */
1832 public int argmin() {
1833 if (isEmpty()) {
1834 return -1;
1835 }
1836 double v = Double.POSITIVE_INFINITY;
1837 int a = -1;
1838 for (int i = 0; i < length; i++) {
1839 if (!Double.isNaN(get(i)) && get(i) < v) {
1840 v = get(i);
1841 a = i;
1842 }
1843 }
1844
1845 return a;
1846 }
1847
1848 /**
1849 * Computes the minimum between two matrices. Returns the smaller of the
1850 * corresponding elements in the matrix (in-place).
1851 */
1852 public DoubleMatrix mini(DoubleMatrix other, DoubleMatrix result) {
1853 if (result == this) {
1854 for (int i = 0; i < length; i++) {
1855 if (get(i) > other.get(i)) {
1856 put(i, other.get(i));
1857 }
1858 }
1859 } else {
1860 for (int i = 0; i < length; i++) {
1861 if (get(i) > other.get(i)) {
1862 result.put(i, other.get(i));
1863 } else {
1864 result.put(i, get(i));
1865 }
1866 }
1867 }
1868 return this;
1869 }
1870
1871 /**
1872 * Computes the minimum between two matrices. Returns the smaller of the
1873 * corresponding elements in the matrix (in-place on this).
1874 */
1875 public DoubleMatrix mini(DoubleMatrix other) {
1876 return mini(other, this);
1877 }
1878
1879 /**
1880 * Computes the minimum between two matrices. Returns the smaller of the
1881 * corresponding elements in the matrix (in-place on this).
1882 */
1883 public DoubleMatrix min(DoubleMatrix other) {
1884 return mini(other, new DoubleMatrix(rows, columns));
1885 }
1886
1887 public DoubleMatrix mini(double v, DoubleMatrix result) {
1888 if (result == this) {
1889 for (int i = 0; i < length; i++) {
1890 if (get(i) > v) {
1891 result.put(i, v);
1892 }
1893 }
1894 } else {
1895 for (int i = 0; i < length; i++) {
1896 if (get(i) > v) {
1897 result.put(i, v);
1898 } else {
1899 result.put(i, get(i));
1900 }
1901 }
1902
1903 }
1904 return this;
1905 }
1906
1907 public DoubleMatrix mini(double v) {
1908 return mini(v, this);
1909 }
1910
1911 public DoubleMatrix min(double v) {
1912 return mini(v, new DoubleMatrix(rows, columns));
1913 }
1914
1915 /** Returns the maximal element of the matrix. */
1916 public double max() {
1917 if (isEmpty()) {
1918 return Double.NEGATIVE_INFINITY;
1919 }
1920 double v = Double.NEGATIVE_INFINITY;
1921 for (int i = 0; i < length; i++) {
1922 if (!Double.isNaN(get(i)) && get(i) > v) {
1923 v = get(i);
1924 }
1925 }
1926 return v;
1927 }
1928
1929 /**
1930 * Returns the linear index of the maximal element of the matrix. If
1931 * there are more than one elements with this value, the first one
1932 * is returned.
1933 */
1934 public int argmax() {
1935 if (isEmpty()) {
1936 return -1;
1937 }
1938 double v = Double.NEGATIVE_INFINITY;
1939 int a = -1;
1940 for (int i = 0; i < length; i++) {
1941 if (!Double.isNaN(get(i)) && get(i) > v) {
1942 v = get(i);
1943 a = i;
1944 }
1945 }
1946
1947 return a;
1948 }
1949
1950 /**
1951 * Computes the maximum between two matrices. Returns the larger of the
1952 * corresponding elements in the matrix (in-place).
1953 */
1954 public DoubleMatrix maxi(DoubleMatrix other, DoubleMatrix result) {
1955 if (result == this) {
1956 for (int i = 0; i < length; i++) {
1957 if (get(i) < other.get(i)) {
1958 put(i, other.get(i));
1959 }
1960 }
1961 } else {
1962 for (int i = 0; i < length; i++) {
1963 if (get(i) < other.get(i)) {
1964 result.put(i, other.get(i));
1965 } else {
1966 result.put(i, get(i));
1967 }
1968 }
1969 }
1970 return this;
1971 }
1972
1973 /**
1974 * Computes the maximum between two matrices. Returns the smaller of the
1975 * corresponding elements in the matrix (in-place on this).
1976 */
1977 public DoubleMatrix maxi(DoubleMatrix other) {
1978 return maxi(other, this);
1979 }
1980
1981 /**
1982 * Computes the maximum between two matrices. Returns the larger of the
1983 * corresponding elements in the matrix (in-place on this).
1984 */
1985 public DoubleMatrix max(DoubleMatrix other) {
1986 return maxi(other, new DoubleMatrix(rows, columns));
1987 }
1988
1989 public DoubleMatrix maxi(double v, DoubleMatrix result) {
1990 if (result == this) {
1991 for (int i = 0; i < length; i++) {
1992 if (get(i) < v) {
1993 result.put(i, v);
1994 }
1995 }
1996 } else {
1997 for (int i = 0; i < length; i++) {
1998 if (get(i) < v) {
1999 result.put(i, v);
2000 } else {
2001 result.put(i, get(i));
2002 }
2003 }
2004
2005 }
2006 return this;
2007 }
2008
2009 public DoubleMatrix maxi(double v) {
2010 return maxi(v, this);
2011 }
2012
2013 public DoubleMatrix max(double v) {
2014 return maxi(v, new DoubleMatrix(rows, columns));
2015 }
2016
2017 /** Computes the sum of all elements of the matrix. */
2018 public double sum() {
2019 double s = 0.0;
2020 for (int i = 0; i < length; i++) {
2021 s += get(i);
2022 }
2023 return s;
2024 }
2025
2026 /** Computes the product of all elements of the matrix */
2027 public double prod() {
2028 double p = 1.0;
2029 for (int i = 0; i < length; i++) {
2030 p *= get(i);
2031 }
2032 return p;
2033 }
2034
2035 /**
2036 * Computes the mean value of all elements in the matrix,
2037 * that is, <code>x.sum() / x.length</code>.
2038 */
2039 public double mean() {
2040 return sum() / length;
2041 }
2042
2043 /**
2044 * Computes the cumulative sum, that is, the sum of all elements
2045 * of the matrix up to a given index in linear addressing (in-place).
2046 */
2047 public DoubleMatrix cumulativeSumi() {
2048 double s = 0.0;
2049 for (int i = 0; i < length; i++) {
2050 s += get(i);
2051 put(i, s);
2052 }
2053 return this;
2054 }
2055
2056 /**
2057 * Computes the cumulative sum, that is, the sum of all elements
2058 * of the matrix up to a given index in linear addressing.
2059 */
2060 public DoubleMatrix cumulativeSum() {
2061 return dup().cumulativeSumi();
2062 }
2063
2064 /** The scalar product of this with other. */
2065 public double dot(DoubleMatrix other) {
2066 return SimpleBlas.dot(this, other);
2067 }
2068
2069 /**
2070 * Computes the projection coefficient of other on this.
2071 *
2072 * The returned scalar times <tt>this</tt> is the orthogonal projection
2073 * of <tt>other</tt> on <tt>this</tt>.
2074 */
2075 public double project(DoubleMatrix other) {
2076 other.checkLength(length);
2077 double norm = 0, dot = 0;
2078 for (int i = 0; i < this.length; i++) {
2079 double x = get(i);
2080 norm += x * x;
2081 dot += x * other.get(i);
2082 }
2083 return dot / norm;
2084 }
2085
2086 /**
2087 * The Euclidean norm of the matrix as vector, also the Frobenius
2088 * norm of the matrix.
2089 */
2090 public double norm2() {
2091 double norm = 0.0;
2092 for (int i = 0; i < length; i++) {
2093 norm += get(i) * get(i);
2094 }
2095 return (double) Math.sqrt(norm);
2096 }
2097
2098 /**
2099 * The maximum norm of the matrix (maximal absolute value of the elements).
2100 */
2101 public double normmax() {
2102 double max = 0.0;
2103 for (int i = 0; i < length; i++) {
2104 double a = Math.abs(get(i));
2105 if (a > max) {
2106 max = a;
2107 }
2108 }
2109 return max;
2110 }
2111
2112 /**
2113 * The 1-norm of the matrix as vector (sum of absolute values of elements).
2114 */
2115 public double norm1() {
2116 double norm = 0.0;
2117 for (int i = 0; i < length; i++) {
2118 norm += Math.abs(get(i));
2119 }
2120 return norm;
2121 }
2122
2123 /**
2124 * Returns the squared (Euclidean) distance.
2125 */
2126 public double squaredDistance(DoubleMatrix other) {
2127 other.checkLength(length);
2128 double sd = 0.0;
2129 for (int i = 0; i < length; i++) {
2130 double d = get(i) - other.get(i);
2131 sd += d * d;
2132 }
2133 return sd;
2134 }
2135
2136 /**
2137 * Returns the (euclidean) distance.
2138 */
2139 public double distance2(DoubleMatrix other) {
2140 return (double) Math.sqrt(squaredDistance(other));
2141 }
2142
2143 /**
2144 * Returns the (1-norm) distance.
2145 */
2146 public double distance1(DoubleMatrix other) {
2147 other.checkLength(length);
2148 double d = 0.0;
2149 for (int i = 0; i < length; i++) {
2150 d += Math.abs(get(i) - other.get(i));
2151 }
2152 return d;
2153 }
2154
2155 /**
2156 * Return a new matrix with all elements sorted.
2157 */
2158 public DoubleMatrix sort() {
2159 double array[] = toArray();
2160 java.util.Arrays.sort(array);
2161 return new DoubleMatrix(rows, columns, array);
2162 }
2163
2164 /**
2165 * Sort elements in-place.
2166 */
2167 public DoubleMatrix sorti() {
2168 Arrays.sort(data);
2169 return this;
2170 }
2171
2172 /**
2173 * Get the sorting permutation.
2174 *
2175 * @return an int[] array such that which indexes the elements in sorted
2176 * order.
2177 */
2178 public int[] sortingPermutation() {
2179 Integer[] indices = new Integer[length];
2180
2181 for (int i = 0; i < length; i++) {
2182 indices[i] = i;
2183 }
2184
2185 final double[] array = data;
2186
2187 Arrays.sort(indices, new Comparator() {
2188
2189 public int compare(Object o1, Object o2) {
2190 int i = (Integer) o1;
2191 int j = (Integer) o2;
2192 if (array[i] < array[j]) {
2193 return -1;
2194 } else if (array[i] == array[j]) {
2195 return 0;
2196 } else {
2197 return 1;
2198 }
2199 }
2200 });
2201
2202 int[] result = new int[length];
2203
2204 for (int i = 0; i < length; i++) {
2205 result[i] = indices[i];
2206 }
2207
2208 return result;
2209 }
2210
2211 /**
2212 * Sort columns (in-place).
2213 */
2214 public DoubleMatrix sortColumnsi() {
2215 for (int i = 0; i < length; i += rows) {
2216 Arrays.sort(data, i, i + rows);
2217 }
2218 return this;
2219 }
2220
2221 /** Sort columns. */
2222 public DoubleMatrix sortColumns() {
2223 return dup().sortColumnsi();
2224 }
2225
2226 /** Return matrix of indices which sort all columns. */
2227 public int[][] columnSortingPermutations() {
2228 int[][] result = new int[columns][];
2229
2230 DoubleMatrix temp = new DoubleMatrix(rows);
2231 for (int c = 0; c < columns; c++) {
2232 result[c] = getColumn(c, temp).sortingPermutation();
2233 }
2234
2235 return result;
2236 }
2237
2238 /** Sort rows (in-place). */
2239 public DoubleMatrix sortRowsi() {
2240 // actually, this is much harder because the data is not consecutive
2241 // in memory...
2242 DoubleMatrix temp = new DoubleMatrix(columns);
2243 for (int r = 0; r < rows; r++) {
2244 putRow(r, getRow(r, temp).sorti());
2245 }
2246 return this;
2247 }
2248
2249 /** Sort rows. */
2250 public DoubleMatrix sortRows() {
2251 return dup().sortRowsi();
2252 }
2253
2254 /** Return matrix of indices which sort all columns. */
2255 public int[][] rowSortingPermutations() {
2256 int[][] result = new int[rows][];
2257
2258 DoubleMatrix temp = new DoubleMatrix(columns);
2259 for (int r = 0; r < rows; r++) {
2260 result[r] = getRow(r, temp).sortingPermutation();
2261 }
2262
2263 return result;
2264 }
2265
2266 /** Return a vector containing the sums of the columns (having number of columns many entries) */
2267 public DoubleMatrix columnSums() {
2268 if (rows == 1) {
2269 return dup();
2270 } else {
2271 DoubleMatrix v = new DoubleMatrix(1, columns);
2272
2273 for (int c = 0; c < columns; c++) {
2274 for (int r = 0; r < rows; r++) {
2275 v.put(c, v.get(c) + get(r, c));
2276 }
2277 }
2278
2279 return v;
2280 }
2281 }
2282
2283 /** Return a vector containing the means of all columns. */
2284 public DoubleMatrix columnMeans() {
2285 return columnSums().divi(rows);
2286 }
2287
2288 /** Return a vector containing the sum of the rows. */
2289 public DoubleMatrix rowSums() {
2290 if (columns == 1) {
2291 return dup();
2292 } else {
2293 DoubleMatrix v = new DoubleMatrix(rows);
2294
2295 for (int c = 0; c < columns; c++) {
2296 for (int r = 0; r < rows; r++) {
2297 v.put(r, v.get(r) + get(r, c));
2298 }
2299 }
2300
2301 return v;
2302 }
2303 }
2304
2305 /** Return a vector containing the means of the rows. */
2306 public DoubleMatrix rowMeans() {
2307 return rowSums().divi(columns);
2308 }
2309
2310 /** Get a copy of a column. */
2311 public DoubleMatrix getColumn(int c) {
2312 return getColumn(c, new DoubleMatrix(rows, 1));
2313 }
2314
2315 /** Copy a column to the given vector. */
2316 public DoubleMatrix getColumn(int c, DoubleMatrix result) {
2317 result.checkLength(rows);
2318 JavaBlas.rcopy(rows, data, index(0, c), 1, result.data, 0, 1);
2319 return result;
2320 }
2321
2322 /** Copy a column back into the matrix. */
2323 public void putColumn(int c, DoubleMatrix v) {
2324 JavaBlas.rcopy(rows, v.data, 0, 1, data, index(0, c), 1);
2325 }
2326
2327 /** Get a copy of a row. */
2328 public DoubleMatrix getRow(int r) {
2329 return getRow(r, new DoubleMatrix(1, columns));
2330 }
2331
2332 /** Copy a row to a given vector. */
2333 public DoubleMatrix getRow(int r, DoubleMatrix result) {
2334 result.checkLength(columns);
2335 JavaBlas.rcopy(columns, data, index(r, 0), rows, result.data, 0, 1);
2336 return result;
2337 }
2338
2339 /** Copy a row back into the matrix. */
2340 public void putRow(int r, DoubleMatrix v) {
2341 JavaBlas.rcopy(columns, v.data, 0, 1, data, index(r, 0), rows);
2342 }
2343
2344 /** Return column-wise minimums. */
2345 public DoubleMatrix columnMins() {
2346 DoubleMatrix mins = new DoubleMatrix(1, columns);
2347 for (int c = 0; c < columns; c++) {
2348 mins.put(c, getColumn(c).min());
2349 }
2350 return mins;
2351 }
2352
2353 /** Return index of minimal element per column. */
2354 public int[] columnArgmins() {
2355 int[] argmins = new int[columns];
2356 for (int c = 0; c < columns; c++) {
2357 argmins[c] = getColumn(c).argmin();
2358 }
2359 return argmins;
2360 }
2361
2362 /** Return column-wise maximums. */
2363 public DoubleMatrix columnMaxs() {
2364 DoubleMatrix maxs = new DoubleMatrix(1, columns);
2365 for (int c = 0; c < columns; c++) {
2366 maxs.put(c, getColumn(c).max());
2367 }
2368 return maxs;
2369 }
2370
2371 /** Return index of minimal element per column. */
2372 public int[] columnArgmaxs() {
2373 int[] argmaxs = new int[columns];
2374 for (int c = 0; c < columns; c++) {
2375 argmaxs[c] = getColumn(c).argmax();
2376 }
2377 return argmaxs;
2378 }
2379
2380 /** Return row-wise minimums. */
2381 public DoubleMatrix rowMins() {
2382 DoubleMatrix mins = new DoubleMatrix(rows);
2383 for (int c = 0; c < rows; c++) {
2384 mins.put(c, getRow(c).min());
2385 }
2386 return mins;
2387 }
2388
2389 /** Return index of minimal element per row. */
2390 public int[] rowArgmins() {
2391 int[] argmins = new int[rows];
2392 for (int c = 0; c < rows; c++) {
2393 argmins[c] = getRow(c).argmin();
2394 }
2395 return argmins;
2396 }
2397
2398 /** Return row-wise maximums. */
2399 public DoubleMatrix rowMaxs() {
2400 DoubleMatrix maxs = new DoubleMatrix(rows);
2401 for (int c = 0; c < rows; c++) {
2402 maxs.put(c, getRow(c).max());
2403 }
2404 return maxs;
2405 }
2406
2407 /** Return index of minimal element per row. */
2408 public int[] rowArgmaxs() {
2409 int[] argmaxs = new int[rows];
2410 for (int c = 0; c < rows; c++) {
2411 argmaxs[c] = getRow(c).argmax();
2412 }
2413 return argmaxs;
2414 }
2415
2416 /**************************************************************************
2417 * Elementwise Functions
2418 */
2419 /** Add a row vector to all rows of the matrix (in place). */
2420 public DoubleMatrix addiRowVector(DoubleMatrix x) {
2421 x.checkLength(columns);
2422 for (int c = 0; c < columns; c++) {
2423 for (int r = 0; r < rows; r++) {
2424 put(r, c, get(r, c) + x.get(c));
2425 }
2426 }
2427 return this;
2428 }
2429
2430 /** Add a row to all rows of the matrix. */
2431 public DoubleMatrix addRowVector(DoubleMatrix x) {
2432 return dup().addiRowVector(x);
2433 }
2434
2435 /** Add a vector to all columns of the matrix (in-place). */
2436 public DoubleMatrix addiColumnVector(DoubleMatrix x) {
2437 x.checkLength(rows);
2438 for (int c = 0; c < columns; c++) {
2439 for (int r = 0; r < rows; r++) {
2440 put(r, c, get(r, c) + x.get(r));
2441 }
2442 }
2443 return this;
2444 }
2445
2446 /** Add a vector to all columns of the matrix. */
2447 public DoubleMatrix addColumnVector(DoubleMatrix x) {
2448 return dup().addiColumnVector(x);
2449 }
2450
2451 /** Subtract a row vector from all rows of the matrix (in-place). */
2452 public DoubleMatrix subiRowVector(DoubleMatrix x) {
2453 // This is a bit crazy, but a row vector must have as length as the columns of the matrix.
2454 x.checkLength(columns);
2455 for (int c = 0; c < columns; c++) {
2456 for (int r = 0; r < rows; r++) {
2457 put(r, c, get(r, c) - x.get(c));
2458 }
2459 }
2460 return this;
2461 }
2462
2463 /** Subtract a row vector from all rows of the matrix. */
2464 public DoubleMatrix subRowVector(DoubleMatrix x) {
2465 return dup().subiRowVector(x);
2466 }
2467
2468 /** Subtract a column vector from all columns of the matrix (in-place). */
2469 public DoubleMatrix subiColumnVector(DoubleMatrix x) {
2470 x.checkLength(rows);
2471 for (int c = 0; c < columns; c++) {
2472 for (int r = 0; r < rows; r++) {
2473 put(r, c, get(r, c) - x.get(r));
2474 }
2475 }
2476 return this;
2477 }
2478
2479 /** Subtract a vector from all columns of the matrix. */
2480 public DoubleMatrix subColumnVector(DoubleMatrix x) {
2481 return dup().subiColumnVector(x);
2482 }
2483
2484 /** Multiply a row by a scalar. */
2485 public DoubleMatrix mulRow(int r, double scale) {
2486 NativeBlas.dscal(columns, scale, data, index(r, 0), rows);
2487 return this;
2488 }
2489
2490 /** Multiply a column by a scalar. */
2491 public DoubleMatrix mulColumn(int c, double scale) {
2492 NativeBlas.dscal(rows, scale, data, index(0, c), 1);
2493 return this;
2494 }
2495
2496 /** Multiply all columns with a column vector (in-place). */
2497 public DoubleMatrix muliColumnVector(DoubleMatrix x) {
2498 x.checkLength(rows);
2499 for (int c = 0; c < columns; c++) {
2500 for (int r = 0; r < rows; r++) {
2501 put(r, c, get(r, c) * x.get(r));
2502 }
2503 }
2504 return this;
2505 }
2506
2507 /** Multiply all columns with a column vector. */
2508 public DoubleMatrix mulColumnVector(DoubleMatrix x) {
2509 return dup().muliColumnVector(x);
2510 }
2511
2512 /** Multiply all rows with a row vector (in-place). */
2513 public DoubleMatrix muliRowVector(DoubleMatrix x) {
2514 x.checkLength(columns);
2515 for (int c = 0; c < columns; c++) {
2516 for (int r = 0; r < rows; r++) {
2517 put(r, c, get(r, c) * x.get(c));
2518 }
2519 }
2520 return this;
2521 }
2522
2523 /** Multiply all rows with a row vector. */
2524 public DoubleMatrix mulRowVector(DoubleMatrix x) {
2525 return dup().muliRowVector(x);
2526 }
2527
2528 public DoubleMatrix diviRowVector(DoubleMatrix x) {
2529 x.checkLength(columns);
2530 for (int c = 0; c < columns; c++) {
2531 for (int r = 0; r < rows; r++) {
2532 put(r, c, get(r, c) / x.get(c));
2533 }
2534 }
2535 return this;
2536 }
2537
2538 public DoubleMatrix divRowVector(DoubleMatrix x) {
2539 return dup().diviRowVector(x);
2540 }
2541
2542 public DoubleMatrix diviColumnVector(DoubleMatrix x) {
2543 x.checkLength(rows);
2544 for (int c = 0; c < columns; c++) {
2545 for (int r = 0; r < rows; r++) {
2546 put(r, c, get(r, c) / x.get(r));
2547 }
2548 }
2549 return this;
2550 }
2551
2552 public DoubleMatrix divColumnVector(DoubleMatrix x) {
2553 return dup().diviColumnVector(x);
2554 }
2555
2556 /**
2557 * Writes out this matrix to the given data stream.
2558 * @param dos the data output stream to write to.
2559 * @throws IOException
2560 */
2561 public void out(DataOutputStream dos) throws IOException {
2562 dos.writeUTF("double");
2563 dos.writeInt(columns);
2564 dos.writeInt(rows);
2565
2566 dos.writeInt(data.length);
2567 for (int i = 0; i < data.length; i++) {
2568 dos.writeDouble(data[i]);
2569 }
2570 }
2571
2572 /**
2573 * Reads in a matrix from the given data stream. Note
2574 * that the old data of this matrix will be discarded.
2575 * @param dis the data input stream to read from.
2576 * @throws IOException
2577 */
2578 public void in(DataInputStream dis) throws IOException {
2579 if (!dis.readUTF().equals("double")) {
2580 throw new IllegalStateException("The matrix in the specified file is not of the correct type!");
2581 }
2582
2583 this.columns = dis.readInt();
2584 this.rows = dis.readInt();
2585
2586 final int MAX = dis.readInt();
2587 data = new double[MAX];
2588 for (int i = 0; i < MAX; i++) {
2589 data[i] = dis.readDouble();
2590 }
2591 }
2592
2593 /**
2594 * Saves this matrix to the specified file.
2595 * @param filename the file to write the matrix in.
2596 * @throws IOException thrown on errors while writing the matrix to the file
2597 */
2598 public void save(String filename) throws IOException {
2599 DataOutputStream dos = new DataOutputStream(new FileOutputStream(filename, false));
2600 this.out(dos);
2601 }
2602
2603 /**
2604 * Loads a matrix from a file into this matrix. Note that the old data
2605 * of this matrix will be discarded.
2606 * @param filename the file to read the matrix from
2607 * @throws IOException thrown on errors while reading the matrix
2608 */
2609 public void load(String filename) throws IOException {
2610 DataInputStream dis = new DataInputStream(new FileInputStream(filename));
2611 this.in(dis);
2612 }
2613
2614 public static DoubleMatrix loadAsciiFile(String filename) throws IOException {
2615 BufferedReader is = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
2616
2617 // Go through file and count columns and rows. What makes this endeavour a bit difficult is
2618 // that files can have leading or trailing spaces leading to spurious fields
2619 // after String.split().
2620 String line;
2621 int rows = 0;
2622 int columns = -1;
2623 while ((line = is.readLine()) != null) {
2624 String[] elements = line.split("\\s+");
2625 int numElements = elements.length;
2626 if (elements[0].length() == 0) {
2627 numElements--;
2628 }
2629 if (elements[elements.length - 1].length() == 0) {
2630 numElements--;
2631 }
2632
2633 if (columns == -1) {
2634 columns = numElements;
2635 } else {
2636 if (columns != numElements) {
2637 throw new IOException("Number of elements changes in line " + line + ".");
2638 }
2639 }
2640
2641 rows++;
2642 }
2643 is.close();
2644
2645 // Go through file a second time process the actual data.
2646 is = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
2647 DoubleMatrix result = new DoubleMatrix(rows, columns);
2648 int r = 0;
2649 while ((line = is.readLine()) != null) {
2650 String[] elements = line.split("\\s+");
2651 int firstElement = (elements[0].length() == 0) ? 1 : 0;
2652 for (int c = 0, cc = firstElement; c < columns; c++, cc++) {
2653 result.put(r, c, Double.valueOf(elements[cc]));
2654 }
2655 r++;
2656 }
2657 return result;
2658 }
2659
2660 public static DoubleMatrix loadCSVFile(String filename) throws IOException {
2661 BufferedReader is = new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
2662
2663 List<DoubleMatrix> rows = new LinkedList<DoubleMatrix>();
2664 String line;
2665 int columns = -1;
2666 while ((line = is.readLine()) != null) {
2667 String[] elements = line.split(",");
2668 int numElements = elements.length;
2669 if (elements[0].length() == 0) {
2670 numElements--;
2671 }
2672 if (elements[elements.length - 1].length() == 0) {
2673 numElements--;
2674 }
2675
2676 if (columns == -1) {
2677 columns = numElements;
2678 } else {
2679 if (columns != numElements) {
2680 throw new IOException("Number of elements changes in line " + line + ".");
2681 }
2682 }
2683
2684 DoubleMatrix row = new DoubleMatrix(columns);
2685 for (int c = 0; c < columns; c++) {
2686 row.put(c, Double.valueOf(elements[c]));
2687 }
2688 rows.add(row);
2689 }
2690 is.close();
2691
2692 System.out.println("Done reading file");
2693
2694 DoubleMatrix result = new DoubleMatrix(rows.size(), columns);
2695 int r = 0;
2696 Iterator<DoubleMatrix> ri = rows.iterator();
2697 while (ri.hasNext()) {
2698 result.putRow(r, ri.next());
2699 r++;
2700 }
2701 return result;
2702 }
2703
2704 /****************************************************************
2705 * Autogenerated code
2706 */
2707 /***** Code for operators ***************************************/
2708
2709 /* Overloads for the usual arithmetic operations */
2710 /*#
2711 def gen_overloads(base, result_rows, result_cols, verb=''); <<-EOS
2712 #{doc verb.capitalize + " a matrix (in place)."}
2713 public DoubleMatrix #{base}i(DoubleMatrix other) {
2714 return #{base}i(other, this);
2715 }
2716
2717 #{doc verb.capitalize + " a matrix (in place)."}
2718 public DoubleMatrix #{base}(DoubleMatrix other) {
2719 return #{base}i(other, new DoubleMatrix(#{result_rows}, #{result_cols}));
2720 }
2721
2722 #{doc verb.capitalize + " a scalar (in place)."}
2723 public DoubleMatrix #{base}i(double v) {
2724 return #{base}i(v, this);
2725 }
2726
2727 #{doc verb.capitalize + " a scalar."}
2728 public DoubleMatrix #{base}(double v) {
2729 return #{base}i(v, new DoubleMatrix(rows, columns));
2730 }
2731 EOS
2732 end
2733 #*/
2734
2735 /* Generating code for logical operators. This not only generates the stubs
2736 * but really all of the code.
2737 */
2738 /*#
2739 def gen_compare(name, op, cmp); <<-EOS
2740 #{doc 'Test for ' + cmp + ' (in-place).'}
2741 public DoubleMatrix #{name}i(DoubleMatrix other, DoubleMatrix result) {
2742 if (other.isScalar())
2743 return #{name}i(other.scalar(), result);
2744
2745 assertSameLength(other);
2746 ensureResultLength(other, result);
2747
2748 for (int i = 0; i < length; i++)
2749 result.put(i, get(i) #{op} other.get(i) ? 1.0 : 0.0);
2750 return result;
2751 }
2752
2753 #{doc 'Test for ' + cmp + ' (in-place).'}
2754 public DoubleMatrix #{name}i(DoubleMatrix other) {
2755 return #{name}i(other, this);
2756 }
2757
2758 #{doc 'Test for ' + cmp + '.'}
2759 public DoubleMatrix #{name}(DoubleMatrix other) {
2760 return #{name}i(other, new DoubleMatrix(rows, columns));
2761 }
2762
2763 #{doc 'Test for ' + cmp + ' against a scalar (in-place).'}
2764 public DoubleMatrix #{name}i(double value, DoubleMatrix result) {
2765 ensureResultLength(null, result);
2766 for (int i = 0; i < length; i++)
2767 result.put(i, get(i) #{op} value ? 1.0 : 0.0);
2768 return result;
2769 }
2770
2771 #{doc 'Test for ' + cmp + ' against a scalar (in-place).'}
2772 public DoubleMatrix #{name}i(double value) {
2773 return #{name}i(value, this);
2774 }
2775
2776 #{doc 'test for ' + cmp + ' against a scalar.'}
2777 public DoubleMatrix #{name}(double value) {
2778 return #{name}i(value, new DoubleMatrix(rows, columns));
2779 }
2780 EOS
2781 end
2782 #*/
2783 /*#
2784 def gen_logical(name, op, cmp); <<-EOS
2785 #{doc 'Compute elementwise ' + cmp + ' (in-place).'}
2786 public DoubleMatrix #{name}i(DoubleMatrix other, DoubleMatrix result) {
2787 assertSameLength(other);
2788 ensureResultLength(other, result);
2789
2790 for (int i = 0; i < length; i++)
2791 result.put(i, (get(i) != 0.0) #{op} (other.get(i) != 0.0) ? 1.0 : 0.0);
2792 return result;
2793 }
2794
2795 #{doc 'Compute elementwise ' + cmp + ' (in-place).'}
2796 public DoubleMatrix #{name}i(DoubleMatrix other) {
2797 return #{name}i(other, this);
2798 }
2799
2800 #{doc 'Compute elementwise ' + cmp + '.'}
2801 public DoubleMatrix #{name}(DoubleMatrix other) {
2802 return #{name}i(other, new DoubleMatrix(rows, columns));
2803 }
2804
2805 #{doc 'Compute elementwise ' + cmp + ' against a scalar (in-place).'}
2806 public DoubleMatrix #{name}i(double value, DoubleMatrix result) {
2807 ensureResultLength(null, result);
2808 boolean val = (value != 0.0);
2809 for (int i = 0; i < length; i++)
2810 result.put(i, (get(i) != 0.0) #{op} val ? 1.0 : 0.0);
2811 return result;
2812 }
2813
2814 #{doc 'Compute elementwise ' + cmp + ' against a scalar (in-place).'}
2815 public DoubleMatrix #{name}i(double value) {
2816 return #{name}i(value, this);
2817 }
2818
2819 #{doc 'Compute elementwise ' + cmp + ' against a scalar.'}
2820 public DoubleMatrix #{name}(double value) {
2821 return #{name}i(value, new DoubleMatrix(rows, columns));
2822 }
2823 EOS
2824 end
2825 #*/
2826
2827 /*# collect(gen_overloads('add', 'rows', 'columns', 'add'),
2828 gen_overloads('sub', 'rows', 'columns', 'subtract'),
2829 gen_overloads('rsub', 'rows', 'columns', '(right-)subtract'),
2830 gen_overloads('div', 'rows', 'columns', 'elementwise divide by'),
2831 gen_overloads('rdiv', 'rows', 'columns', '(right-)elementwise divide by'),
2832 gen_overloads('mul', 'rows', 'columns', 'elementwise multiply by'),
2833 gen_overloads('mmul', 'rows', 'other.columns', 'matrix-multiply by'),
2834 gen_compare('lt', '<', '"less than"'),
2835 gen_compare('gt', '>', '"greater than"'),
2836 gen_compare('le', '<=', '"less than or equal"'),
2837 gen_compare('ge', '>=', '"greater than or equal"'),
2838 gen_compare('eq', '==', 'equality'),
2839 gen_compare('ne', '!=', 'inequality'),
2840 gen_logical('and', '&', 'logical and'),
2841 gen_logical('or', '|', 'logical or'),
2842 gen_logical('xor', '^', 'logical xor'))
2843 #*/
2844 //RJPP-BEGIN------------------------------------------------------------
2845 /** Add a matrix (in place). */
2846 public DoubleMatrix addi(DoubleMatrix other) {
2847 return addi(other, this);
2848 }
2849
2850 /** Add a matrix (in place). */
2851 public DoubleMatrix add(DoubleMatrix other) {
2852 return addi(other, new DoubleMatrix(rows, columns));
2853 }
2854
2855 /** Add a scalar (in place). */
2856 public DoubleMatrix addi(double v) {
2857 return addi(v, this);
2858 }
2859
2860 /** Add a scalar. */
2861 public DoubleMatrix add(double v) {
2862 return addi(v, new DoubleMatrix(rows, columns));
2863 }
2864
2865 /** Subtract a matrix (in place). */
2866 public DoubleMatrix subi(DoubleMatrix other) {
2867 return subi(other, this);
2868 }
2869
2870 /** Subtract a matrix (in place). */
2871 public DoubleMatrix sub(DoubleMatrix other) {
2872 return subi(other, new DoubleMatrix(rows, columns));
2873 }
2874
2875 /** Subtract a scalar (in place). */
2876 public DoubleMatrix subi(double v) {
2877 return subi(v, this);
2878 }
2879
2880 /** Subtract a scalar. */
2881 public DoubleMatrix sub(double v) {
2882 return subi(v, new DoubleMatrix(rows, columns));
2883 }
2884
2885 /** (right-)subtract a matrix (in place). */
2886 public DoubleMatrix rsubi(DoubleMatrix other) {
2887 return rsubi(other, this);
2888 }
2889
2890 /** (right-)subtract a matrix (in place). */
2891 public DoubleMatrix rsub(DoubleMatrix other) {
2892 return rsubi(other, new DoubleMatrix(rows, columns));
2893 }
2894
2895 /** (right-)subtract a scalar (in place). */
2896 public DoubleMatrix rsubi(double v) {
2897 return rsubi(v, this);
2898 }
2899
2900 /** (right-)subtract a scalar. */
2901 public DoubleMatrix rsub(double v) {
2902 return rsubi(v, new DoubleMatrix(rows, columns));
2903 }
2904
2905 /** Elementwise divide by a matrix (in place). */
2906 public DoubleMatrix divi(DoubleMatrix other) {
2907 return divi(other, this);
2908 }
2909
2910 /** Elementwise divide by a matrix (in place). */
2911 public DoubleMatrix div(DoubleMatrix other) {
2912 return divi(other, new DoubleMatrix(rows, columns));
2913 }
2914
2915 /** Elementwise divide by a scalar (in place). */
2916 public DoubleMatrix divi(double v) {
2917 return divi(v, this);
2918 }
2919
2920 /** Elementwise divide by a scalar. */
2921 public DoubleMatrix div(double v) {
2922 return divi(v, new DoubleMatrix(rows, columns));
2923 }
2924
2925 /** (right-)elementwise divide by a matrix (in place). */
2926 public DoubleMatrix rdivi(DoubleMatrix other) {
2927 return rdivi(other, this);
2928 }
2929
2930 /** (right-)elementwise divide by a matrix (in place). */
2931 public DoubleMatrix rdiv(DoubleMatrix other) {
2932 return rdivi(other, new DoubleMatrix(rows, columns));
2933 }
2934
2935 /** (right-)elementwise divide by a scalar (in place). */
2936 public DoubleMatrix rdivi(double v) {
2937 return rdivi(v, this);
2938 }
2939
2940 /** (right-)elementwise divide by a scalar. */
2941 public DoubleMatrix rdiv(double v) {
2942 return rdivi(v, new DoubleMatrix(rows, columns));
2943 }
2944
2945 /** Elementwise multiply by a matrix (in place). */
2946 public DoubleMatrix muli(DoubleMatrix other) {
2947 return muli(other, this);
2948 }
2949
2950 /** Elementwise multiply by a matrix (in place). */
2951 public DoubleMatrix mul(DoubleMatrix other) {
2952 return muli(other, new DoubleMatrix(rows, columns));
2953 }
2954
2955 /** Elementwise multiply by a scalar (in place). */
2956 public DoubleMatrix muli(double v) {
2957 return muli(v, this);
2958 }
2959
2960 /** Elementwise multiply by a scalar. */
2961 public DoubleMatrix mul(double v) {
2962 return muli(v, new DoubleMatrix(rows, columns));
2963 }
2964
2965 /** Matrix-multiply by a matrix (in place). */
2966 public DoubleMatrix mmuli(DoubleMatrix other) {
2967 return mmuli(other, this);
2968 }
2969
2970 /** Matrix-multiply by a matrix (in place). */
2971 public DoubleMatrix mmul(DoubleMatrix other) {
2972 return mmuli(other, new DoubleMatrix(rows, other.columns));
2973 }
2974
2975 /** Matrix-multiply by a scalar (in place). */
2976 public DoubleMatrix mmuli(double v) {
2977 return mmuli(v, this);
2978 }
2979
2980 /** Matrix-multiply by a scalar. */
2981 public DoubleMatrix mmul(double v) {
2982 return mmuli(v, new DoubleMatrix(rows, columns));
2983 }
2984
2985 /** Test for "less than" (in-place). */
2986 public DoubleMatrix lti(DoubleMatrix other, DoubleMatrix result) {
2987 if (other.isScalar())
2988 return lti(other.scalar(), result);
2989
2990 assertSameLength(other);
2991 ensureResultLength(other, result);
2992
2993 for (int i = 0; i < length; i++)
2994 result.put(i, get(i) < other.get(i) ? 1.0 : 0.0);
2995 return result;
2996 }
2997
2998 /** Test for "less than" (in-place). */
2999 public DoubleMatrix lti(DoubleMatrix other) {
3000 return lti(other, this);
3001 }
3002
3003 /** Test for "less than". */
3004 public DoubleMatrix lt(DoubleMatrix other) {
3005 return lti(other, new DoubleMatrix(rows, columns));
3006 }
3007
3008 /** Test for "less than" against a scalar (in-place). */
3009 public DoubleMatrix lti(double value, DoubleMatrix result) {
3010 ensureResultLength(null, result);
3011 for (int i = 0; i < length; i++)
3012 result.put(i, get(i) < value ? 1.0 : 0.0);
3013 return result;
3014 }
3015
3016 /** Test for "less than" against a scalar (in-place). */
3017 public DoubleMatrix lti(double value) {
3018 return lti(value, this);
3019 }
3020
3021 /** test for "less than" against a scalar. */
3022 public DoubleMatrix lt(double value) {
3023 return lti(value, new DoubleMatrix(rows, columns));
3024 }
3025
3026 /** Test for "greater than" (in-place). */
3027 public DoubleMatrix gti(DoubleMatrix other, DoubleMatrix result) {
3028 if (other.isScalar())
3029 return gti(other.scalar(), result);
3030
3031 assertSameLength(other);
3032 ensureResultLength(other, result);
3033
3034 for (int i = 0; i < length; i++)
3035 result.put(i, get(i) > other.get(i) ? 1.0 : 0.0);
3036 return result;
3037 }
3038
3039 /** Test for "greater than" (in-place). */
3040 public DoubleMatrix gti(DoubleMatrix other) {
3041 return gti(other, this);
3042 }
3043
3044 /** Test for "greater than". */
3045 public DoubleMatrix gt(DoubleMatrix other) {
3046 return gti(other, new DoubleMatrix(rows, columns));
3047 }
3048
3049 /** Test for "greater than" against a scalar (in-place). */
3050 public DoubleMatrix gti(double value, DoubleMatrix result) {
3051 ensureResultLength(null, result);
3052 for (int i = 0; i < length; i++)
3053 result.put(i, get(i) > value ? 1.0 : 0.0);
3054 return result;
3055 }
3056
3057 /** Test for "greater than" against a scalar (in-place). */
3058 public DoubleMatrix gti(double value) {
3059 return gti(value, this);
3060 }
3061
3062 /** test for "greater than" against a scalar. */
3063 public DoubleMatrix gt(double value) {
3064 return gti(value, new DoubleMatrix(rows, columns));
3065 }
3066
3067 /** Test for "less than or equal" (in-place). */
3068 public DoubleMatrix lei(DoubleMatrix other, DoubleMatrix result) {
3069 if (other.isScalar())
3070 return lei(other.scalar(), result);
3071
3072 assertSameLength(other);
3073 ensureResultLength(other, result);
3074
3075 for (int i = 0; i < length; i++)
3076 result.put(i, get(i) <= other.get(i) ? 1.0 : 0.0);
3077 return result;
3078 }
3079
3080 /** Test for "less than or equal" (in-place). */
3081 public DoubleMatrix lei(DoubleMatrix other) {
3082 return lei(other, this);
3083 }
3084
3085 /** Test for "less than or equal". */
3086 public DoubleMatrix le(DoubleMatrix other) {
3087 return lei(other, new DoubleMatrix(rows, columns));
3088 }
3089
3090 /** Test for "less than or equal" against a scalar (in-place). */
3091 public DoubleMatrix lei(double value, DoubleMatrix result) {
3092 ensureResultLength(null, result);
3093 for (int i = 0; i < length; i++)
3094 result.put(i, get(i) <= value ? 1.0 : 0.0);
3095 return result;
3096 }
3097
3098 /** Test for "less than or equal" against a scalar (in-place). */
3099 public DoubleMatrix lei(double value) {
3100 return lei(value, this);
3101 }
3102
3103 /** test for "less than or equal" against a scalar. */
3104 public DoubleMatrix le(double value) {
3105 return lei(value, new DoubleMatrix(rows, columns));
3106 }
3107
3108 /** Test for "greater than or equal" (in-place). */
3109 public DoubleMatrix gei(DoubleMatrix other, DoubleMatrix result) {
3110 if (other.isScalar())
3111 return gei(other.scalar(), result);
3112
3113 assertSameLength(other);
3114 ensureResultLength(other, result);
3115
3116 for (int i = 0; i < length; i++)
3117 result.put(i, get(i) >= other.get(i) ? 1.0 : 0.0);
3118 return result;
3119 }
3120
3121 /** Test for "greater than or equal" (in-place). */
3122 public DoubleMatrix gei(DoubleMatrix other) {
3123 return gei(other, this);
3124 }
3125
3126 /** Test for "greater than or equal". */
3127 public DoubleMatrix ge(DoubleMatrix other) {
3128 return gei(other, new DoubleMatrix(rows, columns));
3129 }
3130
3131 /** Test for "greater than or equal" against a scalar (in-place). */
3132 public DoubleMatrix gei(double value, DoubleMatrix result) {
3133 ensureResultLength(null, result);
3134 for (int i = 0; i < length; i++)
3135 result.put(i, get(i) >= value ? 1.0 : 0.0);
3136 return result;
3137 }
3138
3139 /** Test for "greater than or equal" against a scalar (in-place). */
3140 public DoubleMatrix gei(double value) {
3141 return gei(value, this);
3142 }
3143
3144 /** test for "greater than or equal" against a scalar. */
3145 public DoubleMatrix ge(double value) {
3146 return gei(value, new DoubleMatrix(rows, columns));
3147 }
3148
3149 /** Test for equality (in-place). */
3150 public DoubleMatrix eqi(DoubleMatrix other, DoubleMatrix result) {
3151 if (other.isScalar())
3152 return eqi(other.scalar(), result);
3153
3154 assertSameLength(other);
3155 ensureResultLength(other, result);
3156
3157 for (int i = 0; i < length; i++)
3158 result.put(i, get(i) == other.get(i) ? 1.0 : 0.0);
3159 return result;
3160 }
3161
3162 /** Test for equality (in-place). */
3163 public DoubleMatrix eqi(DoubleMatrix other) {
3164 return eqi(other, this);
3165 }
3166
3167 /** Test for equality. */
3168 public DoubleMatrix eq(DoubleMatrix other) {
3169 return eqi(other, new DoubleMatrix(rows, columns));
3170 }
3171
3172 /** Test for equality against a scalar (in-place). */
3173 public DoubleMatrix eqi(double value, DoubleMatrix result) {
3174 ensureResultLength(null, result);
3175 for (int i = 0; i < length; i++)
3176 result.put(i, get(i) == value ? 1.0 : 0.0);
3177 return result;
3178 }
3179
3180 /** Test for equality against a scalar (in-place). */
3181 public DoubleMatrix eqi(double value) {
3182 return eqi(value, this);
3183 }
3184
3185 /** test for equality against a scalar. */
3186 public DoubleMatrix eq(double value) {
3187 return eqi(value, new DoubleMatrix(rows, columns));
3188 }
3189
3190 /** Test for inequality (in-place). */
3191 public DoubleMatrix nei(DoubleMatrix other, DoubleMatrix result) {
3192 if (other.isScalar())
3193 return nei(other.scalar(), result);
3194
3195 assertSameLength(other);
3196 ensureResultLength(other, result);
3197
3198 for (int i = 0; i < length; i++)
3199 result.put(i, get(i) != other.get(i) ? 1.0 : 0.0);
3200 return result;
3201 }
3202
3203 /** Test for inequality (in-place). */
3204 public DoubleMatrix nei(DoubleMatrix other) {
3205 return nei(other, this);
3206 }
3207
3208 /** Test for inequality. */
3209 public DoubleMatrix ne(DoubleMatrix other) {
3210 return nei(other, new DoubleMatrix(rows, columns));
3211 }
3212
3213 /** Test for inequality against a scalar (in-place). */
3214 public DoubleMatrix nei(double value, DoubleMatrix result) {
3215 ensureResultLength(null, result);
3216 for (int i = 0; i < length; i++)
3217 result.put(i, get(i) != value ? 1.0 : 0.0);
3218 return result;
3219 }
3220
3221 /** Test for inequality against a scalar (in-place). */
3222 public DoubleMatrix nei(double value) {
3223 return nei(value, this);
3224 }
3225
3226 /** test for inequality against a scalar. */
3227 public DoubleMatrix ne(double value) {
3228 return nei(value, new DoubleMatrix(rows, columns));
3229 }
3230
3231 /** Compute elementwise logical and (in-place). */
3232 public DoubleMatrix andi(DoubleMatrix other, DoubleMatrix result) {
3233 assertSameLength(other);
3234 ensureResultLength(other, result);
3235
3236 for (int i = 0; i < length; i++)
3237 result.put(i, (get(i) != 0.0) & (other.get(i) != 0.0) ? 1.0 : 0.0);
3238 return result;
3239 }
3240
3241 /** Compute elementwise logical and (in-place). */
3242 public DoubleMatrix andi(DoubleMatrix other) {
3243 return andi(other, this);
3244 }
3245
3246 /** Compute elementwise logical and. */
3247 public DoubleMatrix and(DoubleMatrix other) {
3248 return andi(other, new DoubleMatrix(rows, columns));
3249 }
3250
3251 /** Compute elementwise logical and against a scalar (in-place). */
3252 public DoubleMatrix andi(double value, DoubleMatrix result) {
3253 ensureResultLength(null, result);
3254 boolean val = (value != 0.0);
3255 for (int i = 0; i < length; i++)
3256 result.put(i, (get(i) != 0.0) & val ? 1.0 : 0.0);
3257 return result;
3258 }
3259
3260 /** Compute elementwise logical and against a scalar (in-place). */
3261 public DoubleMatrix andi(double value) {
3262 return andi(value, this);
3263 }
3264
3265 /** Compute elementwise logical and against a scalar. */
3266 public DoubleMatrix and(double value) {
3267 return andi(value, new DoubleMatrix(rows, columns));
3268 }
3269
3270 /** Compute elementwise logical or (in-place). */
3271 public DoubleMatrix ori(DoubleMatrix other, DoubleMatrix result) {
3272 assertSameLength(other);
3273 ensureResultLength(other, result);
3274
3275 for (int i = 0; i < length; i++)
3276 result.put(i, (get(i) != 0.0) | (other.get(i) != 0.0) ? 1.0 : 0.0);
3277 return result;
3278 }
3279
3280 /** Compute elementwise logical or (in-place). */
3281 public DoubleMatrix ori(DoubleMatrix other) {
3282 return ori(other, this);
3283 }
3284
3285 /** Compute elementwise logical or. */
3286 public DoubleMatrix or(DoubleMatrix other) {
3287 return ori(other, new DoubleMatrix(rows, columns));
3288 }
3289
3290 /** Compute elementwise logical or against a scalar (in-place). */
3291 public DoubleMatrix ori(double value, DoubleMatrix result) {
3292 ensureResultLength(null, result);
3293 boolean val = (value != 0.0);
3294 for (int i = 0; i < length; i++)
3295 result.put(i, (get(i) != 0.0) | val ? 1.0 : 0.0);
3296 return result;
3297 }
3298
3299 /** Compute elementwise logical or against a scalar (in-place). */
3300 public DoubleMatrix ori(double value) {
3301 return ori(value, this);
3302 }
3303
3304 /** Compute elementwise logical or against a scalar. */
3305 public DoubleMatrix or(double value) {
3306 return ori(value, new DoubleMatrix(rows, columns));
3307 }
3308
3309 /** Compute elementwise logical xor (in-place). */
3310 public DoubleMatrix xori(DoubleMatrix other, DoubleMatrix result) {
3311 assertSameLength(other);
3312 ensureResultLength(other, result);
3313
3314 for (int i = 0; i < length; i++)
3315 result.put(i, (get(i) != 0.0) ^ (other.get(i) != 0.0) ? 1.0 : 0.0);
3316 return result;
3317 }
3318
3319 /** Compute elementwise logical xor (in-place). */
3320 public DoubleMatrix xori(DoubleMatrix other) {
3321 return xori(other, this);
3322 }
3323
3324 /** Compute elementwise logical xor. */
3325 public DoubleMatrix xor(DoubleMatrix other) {
3326 return xori(other, new DoubleMatrix(rows, columns));
3327 }
3328
3329 /** Compute elementwise logical xor against a scalar (in-place). */
3330 public DoubleMatrix xori(double value, DoubleMatrix result) {
3331 ensureResultLength(null, result);
3332 boolean val = (value != 0.0);
3333 for (int i = 0; i < length; i++)
3334 result.put(i, (get(i) != 0.0) ^ val ? 1.0 : 0.0);
3335 return result;
3336 }
3337
3338 /** Compute elementwise logical xor against a scalar (in-place). */
3339 public DoubleMatrix xori(double value) {
3340 return xori(value, this);
3341 }
3342
3343 /** Compute elementwise logical xor against a scalar. */
3344 public DoubleMatrix xor(double value) {
3345 return xori(value, new DoubleMatrix(rows, columns));
3346 }
3347 //RJPP-END--------------------------------------------------------------
3348 }