1 //******************************************************************************
2 //
3 // File: ReduceArrays.java
4 // Package: edu.rit.pj.reduction
5 // Unit: Class edu.rit.pj.reduction.ReduceArrays
6 //
7 // This Java source file is copyright (C) 2007 by Alan Kaminsky. All rights
8 // reserved. For further information, contact the author, Alan Kaminsky, at
9 // ark@cs.rit.edu.
10 //
11 // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12 // software; you can redistribute it and/or modify it under the terms of the GNU
13 // General Public License as published by the Free Software Foundation; either
14 // version 3 of the License, or (at your option) any later version.
15 //
16 // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 //
20 // Linking this library statically or dynamically with other modules is making a
21 // combined work based on this library. Thus, the terms and conditions of the GNU
22 // General Public License cover the whole combination.
23 //
24 // As a special exception, the copyright holders of this library give you
25 // permission to link this library with independent modules to produce an
26 // executable, regardless of the license terms of these independent modules, and
27 // to copy and distribute the resulting executable under terms of your choice,
28 // provided that you also meet, for each linked independent module, the terms
29 // and conditions of the license of that module. An independent module is a module
30 // which is not derived from or based on this library. If you modify this library,
31 // you may extend this exception to your version of the library, but you are not
32 // obligated to do so. If you do not wish to do so, delete this exception
33 // statement from your version.
34 //
35 // A copy of the GNU General Public License is provided in the file gpl.txt. You
36 // may also obtain a copy of the GNU General Public License on the World Wide
37 // Web at http://www.gnu.org/licenses/gpl.html.
38 //
39 //******************************************************************************
40 package edu.rit.pj.reduction;
41
42 import edu.rit.util.Range;
43
44 /**
45 * Class ReduceArrays provides static methods for reduction operations on arrays
46 * and matrices of primitive types and object types.
47 * <P>
48 * <I>Note:</I> The operations in class ReduceArrays are not multiple thread
49 * safe.
50 *
51 * @author Alan Kaminsky
52 * @version 20-Jun-2007
53 */
54 public class ReduceArrays {
55
56 // Prevent construction.
57 private ReduceArrays() {
58 }
59
60 // Exported operations.
61 /**
62 * Combine a range of elements from one Boolean array with a range of
63 * elements in another Boolean array. The number of elements combined is the
64 * smaller of <code>srcRange</code>'s length and <code>dstRange</code>'s length.
65 * Either or both of <code>srcRange</code>'s and <code>dstRange</code>'s strides may
66 * be greater than 1.
67 * <P>
68 * For each destination array element <I>D</I> in the destination range and
69 * each corresponding source array element <I>S</I> in the source range,
70 * <I>D</I> is set to <I>D op S</I>.
71 *
72 * @param src Source array.
73 * @param srcRange Range of source elements.
74 * @param dst Destination array.
75 * @param dstRange Range of destination elements.
76 * @param op Binary operation.
77 * @exception NullPointerException (unchecked exception) Thrown if any
78 * argument is null.
79 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
80 * index in <code>srcRange</code> is outside the bounds of the source array.
81 * Thrown if any index in
82 * <code>dstRange</code> is outside the bounds of the destination array.
83 */
84 public static void reduce(boolean[] src,
85 Range srcRange,
86 boolean[] dst,
87 Range dstRange,
88 BooleanOp op) {
89 int len = Math.min(srcRange.length(), dstRange.length());
90 if (len == 0) {
91 return;
92 }
93 int srcLower = srcRange.lb();
94 int dstLower = dstRange.lb();
95 int srcStride = srcRange.stride();
96 int dstStride = dstRange.stride();
97 int srcUpper = srcLower + (len - 1) * srcStride;
98 int dstUpper = dstLower + (len - 1) * dstStride;
99 if (0 > srcLower || srcUpper >= src.length) {
100 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
101 + ", srcRange = " + srcRange);
102 }
103 if (0 > dstLower || dstUpper >= dst.length) {
104 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
105 + ", dstRange = " + dstRange);
106 }
107 if (src != dst || srcLower > dstLower) {
108 for (int i = srcLower, j = dstLower;
109 i <= srcUpper;
110 i += srcStride, j += dstStride) {
111 dst[j] = op.op(dst[j], src[i]);
112 }
113 } else if (srcLower < dstLower) {
114 for (int i = srcUpper, j = dstUpper;
115 i >= srcLower;
116 i -= srcStride, j -= dstStride) {
117 dst[j] = op.op(dst[j], src[i]);
118 }
119 }
120 }
121
122 /**
123 * Combine a range of elements from one byte array with a range of elements
124 * in another byte array. The number of elements combined is the smaller of
125 * <code>srcRange</code>'s length and <code>dstRange</code>'s length. Either or both
126 * of <code>srcRange</code>'s and <code>dstRange</code>'s strides may be greater
127 * than 1.
128 * <P>
129 * For each destination array element <I>D</I> in the destination range and
130 * each corresponding source array element <I>S</I> in the source range,
131 * <I>D</I> is set to <I>D op S</I>.
132 *
133 * @param src Source array.
134 * @param srcRange Range of source elements.
135 * @param dst Destination array.
136 * @param dstRange Range of destination elements.
137 * @param op Binary operation.
138 * @exception NullPointerException (unchecked exception) Thrown if any
139 * argument is null.
140 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
141 * index in <code>srcRange</code> is outside the bounds of the source array.
142 * Thrown if any index in
143 * <code>dstRange</code> is outside the bounds of the destination array.
144 */
145 public static void reduce(byte[] src,
146 Range srcRange,
147 byte[] dst,
148 Range dstRange,
149 ByteOp op) {
150 int len = Math.min(srcRange.length(), dstRange.length());
151 if (len == 0) {
152 return;
153 }
154 int srcLower = srcRange.lb();
155 int dstLower = dstRange.lb();
156 int srcStride = srcRange.stride();
157 int dstStride = dstRange.stride();
158 int srcUpper = srcLower + (len - 1) * srcStride;
159 int dstUpper = dstLower + (len - 1) * dstStride;
160 if (0 > srcLower || srcUpper >= src.length) {
161 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
162 + ", srcRange = " + srcRange);
163 }
164 if (0 > dstLower || dstUpper >= dst.length) {
165 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
166 + ", dstRange = " + dstRange);
167 }
168 if (src != dst || srcLower > dstLower) {
169 for (int i = srcLower, j = dstLower;
170 i <= srcUpper;
171 i += srcStride, j += dstStride) {
172 dst[j] = op.op(dst[j], src[i]);
173 }
174 } else if (srcLower < dstLower) {
175 for (int i = srcUpper, j = dstUpper;
176 i >= srcLower;
177 i -= srcStride, j -= dstStride) {
178 dst[j] = op.op(dst[j], src[i]);
179 }
180 }
181 }
182
183 /**
184 * Combine a range of elements from one character array with a range of
185 * elements in another character array. The number of elements combined is
186 * the smaller of <code>srcRange</code>'s length and <code>dstRange</code>'s length.
187 * Either or both of <code>srcRange</code>'s and <code>dstRange</code>'s strides may
188 * be greater than 1.
189 * <P>
190 * For each destination array element <I>D</I> in the destination range and
191 * each corresponding source array element <I>S</I> in the source range,
192 * <I>D</I> is set to <I>D op S</I>.
193 *
194 * @param src Source array.
195 * @param srcRange Range of source elements.
196 * @param dst Destination array.
197 * @param dstRange Range of destination elements.
198 * @param op Binary operation.
199 * @exception NullPointerException (unchecked exception) Thrown if any
200 * argument is null.
201 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
202 * index in <code>srcRange</code> is outside the bounds of the source array.
203 * Thrown if any index in
204 * <code>dstRange</code> is outside the bounds of the destination array.
205 */
206 public static void reduce(char[] src,
207 Range srcRange,
208 char[] dst,
209 Range dstRange,
210 CharacterOp op) {
211 int len = Math.min(srcRange.length(), dstRange.length());
212 if (len == 0) {
213 return;
214 }
215 int srcLower = srcRange.lb();
216 int dstLower = dstRange.lb();
217 int srcStride = srcRange.stride();
218 int dstStride = dstRange.stride();
219 int srcUpper = srcLower + (len - 1) * srcStride;
220 int dstUpper = dstLower + (len - 1) * dstStride;
221 if (0 > srcLower || srcUpper >= src.length) {
222 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
223 + ", srcRange = " + srcRange);
224 }
225 if (0 > dstLower || dstUpper >= dst.length) {
226 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
227 + ", dstRange = " + dstRange);
228 }
229 if (src != dst || srcLower > dstLower) {
230 for (int i = srcLower, j = dstLower;
231 i <= srcUpper;
232 i += srcStride, j += dstStride) {
233 dst[j] = op.op(dst[j], src[i]);
234 }
235 } else if (srcLower < dstLower) {
236 for (int i = srcUpper, j = dstUpper;
237 i >= srcLower;
238 i -= srcStride, j -= dstStride) {
239 dst[j] = op.op(dst[j], src[i]);
240 }
241 }
242 }
243
244 /**
245 * Combine a range of elements from one double array with a range of
246 * elements in another double array. The number of elements combined is the
247 * smaller of <code>srcRange</code>'s length and <code>dstRange</code>'s length.
248 * Either or both of <code>srcRange</code>'s and <code>dstRange</code>'s strides may
249 * be greater than 1.
250 * <P>
251 * For each destination array element <I>D</I> in the destination range and
252 * each corresponding source array element <I>S</I> in the source range,
253 * <I>D</I> is set to <I>D op S</I>.
254 *
255 * @param src Source array.
256 * @param srcRange Range of source elements.
257 * @param dst Destination array.
258 * @param dstRange Range of destination elements.
259 * @param op Binary operation.
260 * @exception NullPointerException (unchecked exception) Thrown if any
261 * argument is null.
262 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
263 * index in <code>srcRange</code> is outside the bounds of the source array.
264 * Thrown if any index in
265 * <code>dstRange</code> is outside the bounds of the destination array.
266 */
267 public static void reduce(double[] src,
268 Range srcRange,
269 double[] dst,
270 Range dstRange,
271 DoubleOp op) {
272 int len = Math.min(srcRange.length(), dstRange.length());
273 if (len == 0) {
274 return;
275 }
276 int srcLower = srcRange.lb();
277 int dstLower = dstRange.lb();
278 int srcStride = srcRange.stride();
279 int dstStride = dstRange.stride();
280 int srcUpper = srcLower + (len - 1) * srcStride;
281 int dstUpper = dstLower + (len - 1) * dstStride;
282 if (0 > srcLower || srcUpper >= src.length) {
283 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
284 + ", srcRange = " + srcRange);
285 }
286 if (0 > dstLower || dstUpper >= dst.length) {
287 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
288 + ", dstRange = " + dstRange);
289 }
290 if (src != dst || srcLower > dstLower) {
291 for (int i = srcLower, j = dstLower;
292 i <= srcUpper;
293 i += srcStride, j += dstStride) {
294 dst[j] = op.op(dst[j], src[i]);
295 }
296 } else if (srcLower < dstLower) {
297 for (int i = srcUpper, j = dstUpper;
298 i >= srcLower;
299 i -= srcStride, j -= dstStride) {
300 dst[j] = op.op(dst[j], src[i]);
301 }
302 }
303 }
304
305 /**
306 * Combine a range of elements from one float array with a range of elements
307 * in another float array. The number of elements combined is the smaller of
308 * <code>srcRange</code>'s length and <code>dstRange</code>'s length. Either or both
309 * of <code>srcRange</code>'s and <code>dstRange</code>'s strides may be greater
310 * than 1.
311 * <P>
312 * For each destination array element <I>D</I> in the destination range and
313 * each corresponding source array element <I>S</I> in the source range,
314 * <I>D</I> is set to <I>D op S</I>.
315 *
316 * @param src Source array.
317 * @param srcRange Range of source elements.
318 * @param dst Destination array.
319 * @param dstRange Range of destination elements.
320 * @param op Binary operation.
321 * @exception NullPointerException (unchecked exception) Thrown if any
322 * argument is null.
323 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
324 * index in <code>srcRange</code> is outside the bounds of the source array.
325 * Thrown if any index in
326 * <code>dstRange</code> is outside the bounds of the destination array.
327 */
328 public static void reduce(float[] src,
329 Range srcRange,
330 float[] dst,
331 Range dstRange,
332 FloatOp op) {
333 int len = Math.min(srcRange.length(), dstRange.length());
334 if (len == 0) {
335 return;
336 }
337 int srcLower = srcRange.lb();
338 int dstLower = dstRange.lb();
339 int srcStride = srcRange.stride();
340 int dstStride = dstRange.stride();
341 int srcUpper = srcLower + (len - 1) * srcStride;
342 int dstUpper = dstLower + (len - 1) * dstStride;
343 if (0 > srcLower || srcUpper >= src.length) {
344 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
345 + ", srcRange = " + srcRange);
346 }
347 if (0 > dstLower || dstUpper >= dst.length) {
348 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
349 + ", dstRange = " + dstRange);
350 }
351 if (src != dst || srcLower > dstLower) {
352 for (int i = srcLower, j = dstLower;
353 i <= srcUpper;
354 i += srcStride, j += dstStride) {
355 dst[j] = op.op(dst[j], src[i]);
356 }
357 } else if (srcLower < dstLower) {
358 for (int i = srcUpper, j = dstUpper;
359 i >= srcLower;
360 i -= srcStride, j -= dstStride) {
361 dst[j] = op.op(dst[j], src[i]);
362 }
363 }
364 }
365
366 /**
367 * Combine a range of elements from one integer array with a range of
368 * elements in another integer array. The number of elements combined is the
369 * smaller of <code>srcRange</code>'s length and <code>dstRange</code>'s length.
370 * Either or both of <code>srcRange</code>'s and <code>dstRange</code>'s strides may
371 * be greater than 1.
372 * <P>
373 * For each destination array element <I>D</I> in the destination range and
374 * each corresponding source array element <I>S</I> in the source range,
375 * <I>D</I> is set to <I>D op S</I>.
376 *
377 * @param src Source array.
378 * @param srcRange Range of source elements.
379 * @param dst Destination array.
380 * @param dstRange Range of destination elements.
381 * @param op Binary operation.
382 * @exception NullPointerException (unchecked exception) Thrown if any
383 * argument is null.
384 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
385 * index in <code>srcRange</code> is outside the bounds of the source array.
386 * Thrown if any index in
387 * <code>dstRange</code> is outside the bounds of the destination array.
388 */
389 public static void reduce(int[] src,
390 Range srcRange,
391 int[] dst,
392 Range dstRange,
393 IntegerOp op) {
394 int len = Math.min(srcRange.length(), dstRange.length());
395 if (len == 0) {
396 return;
397 }
398 int srcLower = srcRange.lb();
399 int dstLower = dstRange.lb();
400 int srcStride = srcRange.stride();
401 int dstStride = dstRange.stride();
402 int srcUpper = srcLower + (len - 1) * srcStride;
403 int dstUpper = dstLower + (len - 1) * dstStride;
404 if (0 > srcLower || srcUpper >= src.length) {
405 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
406 + ", srcRange = " + srcRange);
407 }
408 if (0 > dstLower || dstUpper >= dst.length) {
409 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
410 + ", dstRange = " + dstRange);
411 }
412 if (src != dst || srcLower > dstLower) {
413 for (int i = srcLower, j = dstLower;
414 i <= srcUpper;
415 i += srcStride, j += dstStride) {
416 dst[j] = op.op(dst[j], src[i]);
417 }
418 } else if (srcLower < dstLower) {
419 for (int i = srcUpper, j = dstUpper;
420 i >= srcLower;
421 i -= srcStride, j -= dstStride) {
422 dst[j] = op.op(dst[j], src[i]);
423 }
424 }
425 }
426
427 /**
428 * Combine a range of elements from one long array with a range of elements
429 * in another long array. The number of elements combined is the smaller of
430 * <code>srcRange</code>'s length and <code>dstRange</code>'s length. Either or both
431 * of <code>srcRange</code>'s and <code>dstRange</code>'s strides may be greater
432 * than 1.
433 * <P>
434 * For each destination array element <I>D</I> in the destination range and
435 * each corresponding source array element <I>S</I> in the source range,
436 * <I>D</I> is set to <I>D op S</I>.
437 *
438 * @param src Source array.
439 * @param srcRange Range of source elements.
440 * @param dst Destination array.
441 * @param dstRange Range of destination elements.
442 * @param op Binary operation.
443 * @exception NullPointerException (unchecked exception) Thrown if any
444 * argument is null.
445 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
446 * index in <code>srcRange</code> is outside the bounds of the source array.
447 * Thrown if any index in
448 * <code>dstRange</code> is outside the bounds of the destination array.
449 */
450 public static void reduce(long[] src,
451 Range srcRange,
452 long[] dst,
453 Range dstRange,
454 LongOp op) {
455 int len = Math.min(srcRange.length(), dstRange.length());
456 if (len == 0) {
457 return;
458 }
459 int srcLower = srcRange.lb();
460 int dstLower = dstRange.lb();
461 int srcStride = srcRange.stride();
462 int dstStride = dstRange.stride();
463 int srcUpper = srcLower + (len - 1) * srcStride;
464 int dstUpper = dstLower + (len - 1) * dstStride;
465 if (0 > srcLower || srcUpper >= src.length) {
466 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
467 + ", srcRange = " + srcRange);
468 }
469 if (0 > dstLower || dstUpper >= dst.length) {
470 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
471 + ", dstRange = " + dstRange);
472 }
473 if (src != dst || srcLower > dstLower) {
474 for (int i = srcLower, j = dstLower;
475 i <= srcUpper;
476 i += srcStride, j += dstStride) {
477 dst[j] = op.op(dst[j], src[i]);
478 }
479 } else if (srcLower < dstLower) {
480 for (int i = srcUpper, j = dstUpper;
481 i >= srcLower;
482 i -= srcStride, j -= dstStride) {
483 dst[j] = op.op(dst[j], src[i]);
484 }
485 }
486 }
487
488 /**
489 * Combine a range of elements from one short array with a range of elements
490 * in another short array. The number of elements combined is the smaller of
491 * <code>srcRange</code>'s length and <code>dstRange</code>'s length. Either or both
492 * of <code>srcRange</code>'s and <code>dstRange</code>'s strides may be greater
493 * than 1.
494 * <P>
495 * For each destination array element <I>D</I> in the destination range and
496 * each corresponding source array element <I>S</I> in the source range,
497 * <I>D</I> is set to <I>D op S</I>.
498 *
499 * @param src Source array.
500 * @param srcRange Range of source elements.
501 * @param dst Destination array.
502 * @param dstRange Range of destination elements.
503 * @param op Binary operation.
504 * @exception NullPointerException (unchecked exception) Thrown if any
505 * argument is null.
506 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
507 * index in <code>srcRange</code> is outside the bounds of the source array.
508 * Thrown if any index in
509 * <code>dstRange</code> is outside the bounds of the destination array.
510 */
511 public static void reduce(short[] src,
512 Range srcRange,
513 short[] dst,
514 Range dstRange,
515 ShortOp op) {
516 int len = Math.min(srcRange.length(), dstRange.length());
517 if (len == 0) {
518 return;
519 }
520 int srcLower = srcRange.lb();
521 int dstLower = dstRange.lb();
522 int srcStride = srcRange.stride();
523 int dstStride = dstRange.stride();
524 int srcUpper = srcLower + (len - 1) * srcStride;
525 int dstUpper = dstLower + (len - 1) * dstStride;
526 if (0 > srcLower || srcUpper >= src.length) {
527 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
528 + ", srcRange = " + srcRange);
529 }
530 if (0 > dstLower || dstUpper >= dst.length) {
531 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
532 + ", dstRange = " + dstRange);
533 }
534 if (src != dst || srcLower > dstLower) {
535 for (int i = srcLower, j = dstLower;
536 i <= srcUpper;
537 i += srcStride, j += dstStride) {
538 dst[j] = op.op(dst[j], src[i]);
539 }
540 } else if (srcLower < dstLower) {
541 for (int i = srcUpper, j = dstUpper;
542 i >= srcLower;
543 i -= srcStride, j -= dstStride) {
544 dst[j] = op.op(dst[j], src[i]);
545 }
546 }
547 }
548
549 /**
550 * Combine a range of elements from one object array with a range of
551 * elements in another object array. The number of elements combined is the
552 * smaller of <code>srcRange</code>'s length and <code>dstRange</code>'s length.
553 * Either or both of <code>srcRange</code>'s and <code>dstRange</code>'s strides may
554 * be greater than 1.
555 * <P>
556 * For each destination array element <I>D</I> in the destination range and
557 * each corresponding source array element <I>S</I> in the source range,
558 * <I>D</I> is set to <I>D op S</I>.
559 *
560 * @param <ST> Data type that extends the destination matrix element data type.
561 * @param <DT> Destination array element data type.
562 * @param src Source array.
563 * @param srcRange Range of source elements.
564 * @param dst Destination array.
565 * @param dstRange Range of destination elements.
566 * @param op Binary operation.
567 * @exception NullPointerException (unchecked exception) Thrown if any
568 * argument is null.
569 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
570 * index in <code>srcRange</code> is outside the bounds of the source array.
571 * Thrown if any index in
572 * <code>dstRange</code> is outside the bounds of the destination array.
573 */
574 public static <DT, ST extends DT> void reduce(ST[] src,
575 Range srcRange,
576 DT[] dst,
577 Range dstRange,
578 ObjectOp<DT> op) {
579 int len = Math.min(srcRange.length(), dstRange.length());
580 if (len == 0) {
581 return;
582 }
583 int srcLower = srcRange.lb();
584 int dstLower = dstRange.lb();
585 int srcStride = srcRange.stride();
586 int dstStride = dstRange.stride();
587 int srcUpper = srcLower + (len - 1) * srcStride;
588 int dstUpper = dstLower + (len - 1) * dstStride;
589 if (0 > srcLower || srcUpper >= src.length) {
590 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src indexes = 0.." + (src.length - 1)
591 + ", srcRange = " + srcRange);
592 }
593 if (0 > dstLower || dstUpper >= dst.length) {
594 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst indexes = 0.." + (dst.length - 1)
595 + ", dstRange = " + dstRange);
596 }
597 if (src != dst || srcLower > dstLower) {
598 for (int i = srcLower, j = dstLower;
599 i <= srcUpper;
600 i += srcStride, j += dstStride) {
601 dst[j] = op.op(dst[j], src[i]);
602 }
603 } else if (srcLower < dstLower) {
604 for (int i = srcUpper, j = dstUpper;
605 i >= srcLower;
606 i -= srcStride, j -= dstStride) {
607 dst[j] = op.op(dst[j], src[i]);
608 }
609 }
610 }
611
612 /**
613 * Combine a range of elements from one Boolean matrix with a range of
614 * elements in another Boolean matrix. The number of rows combined is the
615 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
616 * length. Within each row, the number of columns combined is the smaller of
617 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
618 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
619 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
620 * that the source matrix is fully allocated; each row in the source matrix
621 * is the same length; the destination matrix is fully allocated; and each
622 * row in the destination matrix is the same length.
623 * <P>
624 * For each destination matrix element <I>D</I> in the destination row and
625 * column ranges and each corresponding source matrix element <I>S</I> in
626 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
627 *
628 * @param src Source matrix.
629 * @param srcRowRange Range of source rows.
630 * @param srcColRange Range of source columns.
631 * @param dst Destination matrix.
632 * @param dstRowRange Range of destination rows.
633 * @param dstColRange Range of destination columns.
634 * @param op Binary operation.
635 * @exception NullPointerException (unchecked exception) Thrown if any
636 * argument is null.
637 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
638 * index in <code>srcRowRange</code> is outside the row bounds of the source
639 * matrix. Thrown if any index in
640 * <code>srcColRange</code> is outside the column bounds of the source matrix.
641 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
642 * the destination matrix. Thrown if any index in
643 * <code>dstColRange</code> is outside the column bounds of the destination
644 * matrix.
645 */
646 public static void reduce(boolean[][] src,
647 Range srcRowRange,
648 Range srcColRange,
649 boolean[][] dst,
650 Range dstRowRange,
651 Range dstColRange,
652 BooleanOp op) {
653 int len = Math.min(srcRowRange.length(), dstRowRange.length());
654 if (len == 0) {
655 return;
656 }
657 int srcRowLower = srcRowRange.lb();
658 int dstRowLower = dstRowRange.lb();
659 int srcRowStride = srcRowRange.stride();
660 int dstRowStride = dstRowRange.stride();
661 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
662 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
663 if (0 > srcRowLower || srcRowUpper >= src.length) {
664 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
665 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
666 }
667 if (0 > dstRowLower || dstRowUpper >= dst.length) {
668 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
669 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
670 }
671 if (src != dst || srcRowLower > dstRowLower) {
672 for (int i = srcRowLower, j = dstRowLower;
673 i <= srcRowUpper;
674 i += srcRowStride, j += dstRowStride) {
675 reduce(src[i], srcColRange, dst[j], dstColRange, op);
676 }
677 } else if (srcRowLower < dstRowLower) {
678 for (int i = srcRowUpper, j = dstRowUpper;
679 i >= srcRowLower;
680 i -= srcRowStride, j -= dstRowStride) {
681 reduce(src[i], srcColRange, dst[j], dstColRange, op);
682 }
683 }
684 }
685
686 /**
687 * Combine a range of elements from one byte matrix with a range of elements
688 * in another byte matrix. The number of rows combined is the smaller of
689 * <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s length. Within
690 * each row, the number of columns combined is the smaller of
691 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
692 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
693 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
694 * that the source matrix is fully allocated; each row in the source matrix
695 * is the same length; the destination matrix is fully allocated; and each
696 * row in the destination matrix is the same length.
697 * <P>
698 * For each destination matrix element <I>D</I> in the destination row and
699 * column ranges and each corresponding source matrix element <I>S</I> in
700 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
701 *
702 * @param src Source matrix.
703 * @param srcRowRange Range of source rows.
704 * @param srcColRange Range of source columns.
705 * @param dst Destination matrix.
706 * @param dstRowRange Range of destination rows.
707 * @param dstColRange Range of destination columns.
708 * @param op Binary operation.
709 * @exception NullPointerException (unchecked exception) Thrown if any
710 * argument is null.
711 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
712 * index in <code>srcRowRange</code> is outside the row bounds of the source
713 * matrix. Thrown if any index in
714 * <code>srcColRange</code> is outside the column bounds of the source matrix.
715 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
716 * the destination matrix. Thrown if any index in
717 * <code>dstColRange</code> is outside the column bounds of the destination
718 * matrix.
719 */
720 public static void reduce(byte[][] src,
721 Range srcRowRange,
722 Range srcColRange,
723 byte[][] dst,
724 Range dstRowRange,
725 Range dstColRange,
726 ByteOp op) {
727 int len = Math.min(srcRowRange.length(), dstRowRange.length());
728 if (len == 0) {
729 return;
730 }
731 int srcRowLower = srcRowRange.lb();
732 int dstRowLower = dstRowRange.lb();
733 int srcRowStride = srcRowRange.stride();
734 int dstRowStride = dstRowRange.stride();
735 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
736 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
737 if (0 > srcRowLower || srcRowUpper >= src.length) {
738 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
739 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
740 }
741 if (0 > dstRowLower || dstRowUpper >= dst.length) {
742 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
743 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
744 }
745 if (src != dst || srcRowLower > dstRowLower) {
746 for (int i = srcRowLower, j = dstRowLower;
747 i <= srcRowUpper;
748 i += srcRowStride, j += dstRowStride) {
749 reduce(src[i], srcColRange, dst[j], dstColRange, op);
750 }
751 } else if (srcRowLower < dstRowLower) {
752 for (int i = srcRowUpper, j = dstRowUpper;
753 i >= srcRowLower;
754 i -= srcRowStride, j -= dstRowStride) {
755 reduce(src[i], srcColRange, dst[j], dstColRange, op);
756 }
757 }
758 }
759
760 /**
761 * Combine a range of elements from one character matrix with a range of
762 * elements in another character matrix. The number of rows combined is the
763 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
764 * length. Within each row, the number of columns combined is the smaller of
765 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
766 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
767 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
768 * that the source matrix is fully allocated; each row in the source matrix
769 * is the same length; the destination matrix is fully allocated; and each
770 * row in the destination matrix is the same length.
771 * <P>
772 * For each destination matrix element <I>D</I> in the destination row and
773 * column ranges and each corresponding source matrix element <I>S</I> in
774 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
775 *
776 * @param src Source matrix.
777 * @param srcRowRange Range of source rows.
778 * @param srcColRange Range of source columns.
779 * @param dst Destination matrix.
780 * @param dstRowRange Range of destination rows.
781 * @param dstColRange Range of destination columns.
782 * @param op Binary operation.
783 * @exception NullPointerException (unchecked exception) Thrown if any
784 * argument is null.
785 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
786 * index in <code>srcRowRange</code> is outside the row bounds of the source
787 * matrix. Thrown if any index in
788 * <code>srcColRange</code> is outside the column bounds of the source matrix.
789 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
790 * the destination matrix. Thrown if any index in
791 * <code>dstColRange</code> is outside the column bounds of the destination
792 * matrix.
793 */
794 public static void reduce(char[][] src,
795 Range srcRowRange,
796 Range srcColRange,
797 char[][] dst,
798 Range dstRowRange,
799 Range dstColRange,
800 CharacterOp op) {
801 int len = Math.min(srcRowRange.length(), dstRowRange.length());
802 if (len == 0) {
803 return;
804 }
805 int srcRowLower = srcRowRange.lb();
806 int dstRowLower = dstRowRange.lb();
807 int srcRowStride = srcRowRange.stride();
808 int dstRowStride = dstRowRange.stride();
809 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
810 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
811 if (0 > srcRowLower || srcRowUpper >= src.length) {
812 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
813 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
814 }
815 if (0 > dstRowLower || dstRowUpper >= dst.length) {
816 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
817 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
818 }
819 if (src != dst || srcRowLower > dstRowLower) {
820 for (int i = srcRowLower, j = dstRowLower;
821 i <= srcRowUpper;
822 i += srcRowStride, j += dstRowStride) {
823 reduce(src[i], srcColRange, dst[j], dstColRange, op);
824 }
825 } else if (srcRowLower < dstRowLower) {
826 for (int i = srcRowUpper, j = dstRowUpper;
827 i >= srcRowLower;
828 i -= srcRowStride, j -= dstRowStride) {
829 reduce(src[i], srcColRange, dst[j], dstColRange, op);
830 }
831 }
832 }
833
834 /**
835 * Combine a range of elements from one double matrix with a range of
836 * elements in another double matrix. The number of rows combined is the
837 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
838 * length. Within each row, the number of columns combined is the smaller of
839 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
840 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
841 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
842 * that the source matrix is fully allocated; each row in the source matrix
843 * is the same length; the destination matrix is fully allocated; and each
844 * row in the destination matrix is the same length.
845 *
846 * @param src Source matrix.
847 * @param srcRowRange Range of source rows.
848 * @param srcColRange Range of source columns.
849 * @param dst Destination matrix.
850 * @param dstRowRange Range of destination rows.
851 * @param dstColRange Range of destination columns.
852 * @param op Binary operation.
853 * @exception NullPointerException (unchecked exception) Thrown if any
854 * argument is null.
855 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
856 * index in <code>srcRowRange</code> is outside the row bounds of the source
857 * matrix. Thrown if any index in
858 * <code>srcColRange</code> is outside the column bounds of the source matrix.
859 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
860 * the destination matrix. Thrown if any index in
861 * <code>dstColRange</code> is outside the column bounds of the destination
862 * matrix.
863 */
864 public static void reduce(double[][] src,
865 Range srcRowRange,
866 Range srcColRange,
867 double[][] dst,
868 Range dstRowRange,
869 Range dstColRange,
870 DoubleOp op) {
871 int len = Math.min(srcRowRange.length(), dstRowRange.length());
872 if (len == 0) {
873 return;
874 }
875 int srcRowLower = srcRowRange.lb();
876 int dstRowLower = dstRowRange.lb();
877 int srcRowStride = srcRowRange.stride();
878 int dstRowStride = dstRowRange.stride();
879 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
880 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
881 if (0 > srcRowLower || srcRowUpper >= src.length) {
882 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
883 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
884 }
885 if (0 > dstRowLower || dstRowUpper >= dst.length) {
886 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
887 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
888 }
889 if (src != dst || srcRowLower > dstRowLower) {
890 for (int i = srcRowLower, j = dstRowLower;
891 i <= srcRowUpper;
892 i += srcRowStride, j += dstRowStride) {
893 reduce(src[i], srcColRange, dst[j], dstColRange, op);
894 }
895 } else if (srcRowLower < dstRowLower) {
896 for (int i = srcRowUpper, j = dstRowUpper;
897 i >= srcRowLower;
898 i -= srcRowStride, j -= dstRowStride) {
899 reduce(src[i], srcColRange, dst[j], dstColRange, op);
900 }
901 }
902 }
903
904 /**
905 * Combine a range of elements from one float matrix with a range of
906 * elements in another float matrix. The number of rows combined is the
907 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
908 * length. Within each row, the number of columns combined is the smaller of
909 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
910 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
911 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
912 * that the source matrix is fully allocated; each row in the source matrix
913 * is the same length; the destination matrix is fully allocated; and each
914 * row in the destination matrix is the same length.
915 * <P>
916 * For each destination matrix element <I>D</I> in the destination row and
917 * column ranges and each corresponding source matrix element <I>S</I> in
918 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
919 *
920 * @param src Source matrix.
921 * @param srcRowRange Range of source rows.
922 * @param srcColRange Range of source columns.
923 * @param dst Destination matrix.
924 * @param dstRowRange Range of destination rows.
925 * @param dstColRange Range of destination columns.
926 * @param op Binary operation.
927 * @exception NullPointerException (unchecked exception) Thrown if any
928 * argument is null.
929 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
930 * index in <code>srcRowRange</code> is outside the row bounds of the source
931 * matrix. Thrown if any index in
932 * <code>srcColRange</code> is outside the column bounds of the source matrix.
933 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
934 * the destination matrix. Thrown if any index in
935 * <code>dstColRange</code> is outside the column bounds of the destination
936 * matrix.
937 */
938 public static void reduce(float[][] src,
939 Range srcRowRange,
940 Range srcColRange,
941 float[][] dst,
942 Range dstRowRange,
943 Range dstColRange,
944 FloatOp op) {
945 int len = Math.min(srcRowRange.length(), dstRowRange.length());
946 if (len == 0) {
947 return;
948 }
949 int srcRowLower = srcRowRange.lb();
950 int dstRowLower = dstRowRange.lb();
951 int srcRowStride = srcRowRange.stride();
952 int dstRowStride = dstRowRange.stride();
953 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
954 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
955 if (0 > srcRowLower || srcRowUpper >= src.length) {
956 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
957 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
958 }
959 if (0 > dstRowLower || dstRowUpper >= dst.length) {
960 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
961 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
962 }
963 if (src != dst || srcRowLower > dstRowLower) {
964 for (int i = srcRowLower, j = dstRowLower;
965 i <= srcRowUpper;
966 i += srcRowStride, j += dstRowStride) {
967 reduce(src[i], srcColRange, dst[j], dstColRange, op);
968 }
969 } else if (srcRowLower < dstRowLower) {
970 for (int i = srcRowUpper, j = dstRowUpper;
971 i >= srcRowLower;
972 i -= srcRowStride, j -= dstRowStride) {
973 reduce(src[i], srcColRange, dst[j], dstColRange, op);
974 }
975 }
976 }
977
978 /**
979 * Combine a range of elements from one integer matrix with a range of
980 * elements in another integer matrix. The number of rows combined is the
981 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
982 * length. Within each row, the number of columns combined is the smaller of
983 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
984 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
985 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
986 * that the source matrix is fully allocated; each row in the source matrix
987 * is the same length; the destination matrix is fully allocated; and each
988 * row in the destination matrix is the same length.
989 * <P>
990 * For each destination matrix element <I>D</I> in the destination row and
991 * column ranges and each corresponding source matrix element <I>S</I> in
992 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
993 *
994 * @param src Source matrix.
995 * @param srcRowRange Range of source rows.
996 * @param srcColRange Range of source columns.
997 * @param dst Destination matrix.
998 * @param dstRowRange Range of destination rows.
999 * @param dstColRange Range of destination columns.
1000 * @param op Binary operation.
1001 * @exception NullPointerException (unchecked exception) Thrown if any
1002 * argument is null.
1003 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
1004 * index in <code>srcRowRange</code> is outside the row bounds of the source
1005 * matrix. Thrown if any index in
1006 * <code>srcColRange</code> is outside the column bounds of the source matrix.
1007 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
1008 * the destination matrix. Thrown if any index in
1009 * <code>dstColRange</code> is outside the column bounds of the destination
1010 * matrix.
1011 */
1012 public static void reduce(int[][] src,
1013 Range srcRowRange,
1014 Range srcColRange,
1015 int[][] dst,
1016 Range dstRowRange,
1017 Range dstColRange,
1018 IntegerOp op) {
1019 int len = Math.min(srcRowRange.length(), dstRowRange.length());
1020 if (len == 0) {
1021 return;
1022 }
1023 int srcRowLower = srcRowRange.lb();
1024 int dstRowLower = dstRowRange.lb();
1025 int srcRowStride = srcRowRange.stride();
1026 int dstRowStride = dstRowRange.stride();
1027 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
1028 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
1029 if (0 > srcRowLower || srcRowUpper >= src.length) {
1030 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
1031 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
1032 }
1033 if (0 > dstRowLower || dstRowUpper >= dst.length) {
1034 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
1035 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
1036 }
1037 if (src != dst || srcRowLower > dstRowLower) {
1038 for (int i = srcRowLower, j = dstRowLower;
1039 i <= srcRowUpper;
1040 i += srcRowStride, j += dstRowStride) {
1041 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1042 }
1043 } else if (srcRowLower < dstRowLower) {
1044 for (int i = srcRowUpper, j = dstRowUpper;
1045 i >= srcRowLower;
1046 i -= srcRowStride, j -= dstRowStride) {
1047 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1048 }
1049 }
1050 }
1051
1052 /**
1053 * Combine a range of elements from one long matrix with a range of elements
1054 * in another long matrix. The number of rows combined is the smaller of
1055 * <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s length. Within
1056 * each row, the number of columns combined is the smaller of
1057 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
1058 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
1059 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
1060 * that the source matrix is fully allocated; each row in the source matrix
1061 * is the same length; the destination matrix is fully allocated; and each
1062 * row in the destination matrix is the same length.
1063 * <P>
1064 * For each destination matrix element <I>D</I> in the destination row and
1065 * column ranges and each corresponding source matrix element <I>S</I> in
1066 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
1067 *
1068 * @param src Source matrix.
1069 * @param srcRowRange Range of source rows.
1070 * @param srcColRange Range of source columns.
1071 * @param dst Destination matrix.
1072 * @param dstRowRange Range of destination rows.
1073 * @param dstColRange Range of destination columns.
1074 * @param op Binary operation.
1075 * @exception NullPointerException (unchecked exception) Thrown if any
1076 * argument is null.
1077 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
1078 * index in <code>srcRowRange</code> is outside the row bounds of the source
1079 * matrix. Thrown if any index in
1080 * <code>srcColRange</code> is outside the column bounds of the source matrix.
1081 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
1082 * the destination matrix. Thrown if any index in
1083 * <code>dstColRange</code> is outside the column bounds of the destination
1084 * matrix.
1085 */
1086 public static void reduce(long[][] src,
1087 Range srcRowRange,
1088 Range srcColRange,
1089 long[][] dst,
1090 Range dstRowRange,
1091 Range dstColRange,
1092 LongOp op) {
1093 int len = Math.min(srcRowRange.length(), dstRowRange.length());
1094 if (len == 0) {
1095 return;
1096 }
1097 int srcRowLower = srcRowRange.lb();
1098 int dstRowLower = dstRowRange.lb();
1099 int srcRowStride = srcRowRange.stride();
1100 int dstRowStride = dstRowRange.stride();
1101 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
1102 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
1103 if (0 > srcRowLower || srcRowUpper >= src.length) {
1104 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
1105 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
1106 }
1107 if (0 > dstRowLower || dstRowUpper >= dst.length) {
1108 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
1109 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
1110 }
1111 if (src != dst || srcRowLower > dstRowLower) {
1112 for (int i = srcRowLower, j = dstRowLower;
1113 i <= srcRowUpper;
1114 i += srcRowStride, j += dstRowStride) {
1115 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1116 }
1117 } else if (srcRowLower < dstRowLower) {
1118 for (int i = srcRowUpper, j = dstRowUpper;
1119 i >= srcRowLower;
1120 i -= srcRowStride, j -= dstRowStride) {
1121 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1122 }
1123 }
1124 }
1125
1126 /**
1127 * Combine a range of elements from one short matrix with a range of
1128 * elements in another short matrix. The number of rows combined is the
1129 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
1130 * length. Within each row, the number of columns combined is the smaller of
1131 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
1132 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
1133 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
1134 * that the source matrix is fully allocated; each row in the source matrix
1135 * is the same length; the destination matrix is fully allocated; and each
1136 * row in the destination matrix is the same length.
1137 * <P>
1138 * For each destination matrix element <I>D</I> in the destination row and
1139 * column ranges and each corresponding source matrix element <I>S</I> in
1140 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
1141 *
1142 * @param src Source matrix.
1143 * @param srcRowRange Range of source rows.
1144 * @param srcColRange Range of source columns.
1145 * @param dst Destination matrix.
1146 * @param dstRowRange Range of destination rows.
1147 * @param dstColRange Range of destination columns.
1148 * @param op Binary operation.
1149 * @exception NullPointerException (unchecked exception) Thrown if any
1150 * argument is null.
1151 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
1152 * index in <code>srcRowRange</code> is outside the row bounds of the source
1153 * matrix. Thrown if any index in
1154 * <code>srcColRange</code> is outside the column bounds of the source matrix.
1155 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
1156 * the destination matrix. Thrown if any index in
1157 * <code>dstColRange</code> is outside the column bounds of the destination
1158 * matrix.
1159 */
1160 public static void reduce(short[][] src,
1161 Range srcRowRange,
1162 Range srcColRange,
1163 short[][] dst,
1164 Range dstRowRange,
1165 Range dstColRange,
1166 ShortOp op) {
1167 int len = Math.min(srcRowRange.length(), dstRowRange.length());
1168 if (len == 0) {
1169 return;
1170 }
1171 int srcRowLower = srcRowRange.lb();
1172 int dstRowLower = dstRowRange.lb();
1173 int srcRowStride = srcRowRange.stride();
1174 int dstRowStride = dstRowRange.stride();
1175 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
1176 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
1177 if (0 > srcRowLower || srcRowUpper >= src.length) {
1178 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
1179 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
1180 }
1181 if (0 > dstRowLower || dstRowUpper >= dst.length) {
1182 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
1183 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
1184 }
1185 if (src != dst || srcRowLower > dstRowLower) {
1186 for (int i = srcRowLower, j = dstRowLower;
1187 i <= srcRowUpper;
1188 i += srcRowStride, j += dstRowStride) {
1189 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1190 }
1191 } else if (srcRowLower < dstRowLower) {
1192 for (int i = srcRowUpper, j = dstRowUpper;
1193 i >= srcRowLower;
1194 i -= srcRowStride, j -= dstRowStride) {
1195 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1196 }
1197 }
1198 }
1199
1200 /**
1201 * Combine a range of elements from one object matrix with a range of
1202 * elements in another object matrix. The number of rows combined is the
1203 * smaller of <code>srcRowRange</code>'s length and <code>dstRowRange</code>'s
1204 * length. Within each row, the number of columns combined is the smaller of
1205 * <code>srcColRange</code>'s length and <code>dstColRange</code>'s length. Any of
1206 * <code>srcRowRange</code>'s, <code>srcColRange</code>'s, <code>dstRowRange</code>'s,
1207 * and <code>dstColRange</code>'s strides may be greater than 1. It is assumed
1208 * that the source matrix is fully allocated; each row in the source matrix
1209 * is the same length; the destination matrix is fully allocated; and each
1210 * row in the destination matrix is the same length.
1211 * <P>
1212 * For each destination matrix element <I>D</I> in the destination row and
1213 * column ranges and each corresponding source matrix element <I>S</I> in
1214 * the source row and column ranges, <I>D</I> is set to <I>D op S</I>.
1215 *
1216 * @param <ST> Data type that extends the destination matrix element data type.
1217 * @param <DT> Destination matrix element data type.
1218 * @param src Source matrix.
1219 * @param srcRowRange Range of source rows.
1220 * @param srcColRange Range of source columns.
1221 * @param dst Destination matrix.
1222 * @param dstRowRange Range of destination rows.
1223 * @param dstColRange Range of destination columns.
1224 * @param op Binary operation.
1225 * @exception NullPointerException (unchecked exception) Thrown if any
1226 * argument is null.
1227 * @exception IndexOutOfBoundsException (unchecked exception) Thrown if any
1228 * index in <code>srcRowRange</code> is outside the row bounds of the source
1229 * matrix. Thrown if any index in
1230 * <code>srcColRange</code> is outside the column bounds of the source matrix.
1231 * Thrown if any index in <code>dstRowRange</code> is outside the row bounds of
1232 * the destination matrix. Thrown if any index in
1233 * <code>dstColRange</code> is outside the column bounds of the destination
1234 * matrix.
1235 */
1236 public static <DT, ST extends DT> void reduce(ST[][] src,
1237 Range srcRowRange,
1238 Range srcColRange,
1239 DT[][] dst,
1240 Range dstRowRange,
1241 Range dstColRange,
1242 ObjectOp<DT> op) {
1243 int len = Math.min(srcRowRange.length(), dstRowRange.length());
1244 if (len == 0) {
1245 return;
1246 }
1247 int srcRowLower = srcRowRange.lb();
1248 int dstRowLower = dstRowRange.lb();
1249 int srcRowStride = srcRowRange.stride();
1250 int dstRowStride = dstRowRange.stride();
1251 int srcRowUpper = srcRowLower + (len - 1) * srcRowStride;
1252 int dstRowUpper = dstRowLower + (len - 1) * dstRowStride;
1253 if (0 > srcRowLower || srcRowUpper >= src.length) {
1254 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): src row indexes = 0.."
1255 + (src.length - 1) + ", srcRowRange = " + srcRowRange);
1256 }
1257 if (0 > dstRowLower || dstRowUpper >= dst.length) {
1258 throw new IndexOutOfBoundsException("ReduceArrays.reduce(): dst row indexes = 0.."
1259 + (dst.length - 1) + ", dstRowRange = " + dstRowRange);
1260 }
1261 if (src != dst || srcRowLower > dstRowLower) {
1262 for (int i = srcRowLower, j = dstRowLower;
1263 i <= srcRowUpper;
1264 i += srcRowStride, j += dstRowStride) {
1265 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1266 }
1267 } else if (srcRowLower < dstRowLower) {
1268 for (int i = srcRowUpper, j = dstRowUpper;
1269 i >= srcRowLower;
1270 i -= srcRowStride, j -= dstRowStride) {
1271 reduce(src[i], srcColRange, dst[j], dstColRange, op);
1272 }
1273 }
1274 }
1275
1276 }