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 }