001/* A library for mathematical operations on arrays of longs.
002
003 Copyright (c) 1998-2014 The Regents of the University of California.
004 All rights reserved.
005
006 Permission is hereby granted, without written agreement and without
007 license or royalty fees, to use, copy, modify, and distribute this
008 software and its documentation for any purpose, provided that the above
009 copyright notice and the following two paragraphs appear in all copies
010 of this software.
011
012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
016 SUCH DAMAGE.
017
018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
023 ENHANCEMENTS, OR MODIFICATIONS.
024
025 PT_COPYRIGHT_VERSION_2
026 COPYRIGHTENDKEY
027
028 */
029package ptolemy.math;
030
031///////////////////////////////////////////////////////////////////
032//// LongArrayMath
033
034/**
035 This class provides a library for mathematical operations on long arrays.
036 Unless explicitly noted otherwise, all array arguments are assumed to be
037 non-null. If a null array is passed to a method, a NullPointerException
038 will be thrown in the method or called methods.
039
040 @author Albert Chen, William Wu, Edward A. Lee, Jeff Tsay
041 @version $Id$
042 @since Ptolemy II 1.0
043 @Pt.ProposedRating Yellow (ctsay)
044 @Pt.AcceptedRating Yellow (ctsay)
045 */
046public class LongArrayMath {
047    // Protected constructor prevents construction of this class.
048    protected LongArrayMath() {
049    }
050
051    ///////////////////////////////////////////////////////////////////
052    ////                         public methods                    ////
053
054    /** Return a new array that is the formed by adding z to each element
055     *  of the input array.
056     */
057    public static final long[] add(final long[] array, final long z) {
058        int length = array.length;
059        long[] returnValue = new long[length];
060
061        for (int i = 0; i < length; i++) {
062            returnValue[i] = array[i] + z;
063        }
064
065        return returnValue;
066    }
067
068    /** Return a new array that is the element-by-element sum of the two
069     *  input arrays.
070     *  If the lengths of both arrays are 0, return a new array of length 0.
071     *  If the two arrays do not have the same length, throw an
072     *  IllegalArgumentException.
073     */
074    public static final long[] add(final long[] array1, final long[] array2) {
075        int length = _commonLength(array1, array2, "LongArrayMath.add");
076        long[] returnValue = new long[length];
077
078        for (int i = 0; i < length; i++) {
079            returnValue[i] = array1[i] + array2[i];
080        }
081
082        return returnValue;
083    }
084
085    /** Return a new array that is a copy of the array argument.
086     *  @param array An array of ints.
087     *  @return A new array of ints.
088     */
089    public static final long[] allocCopy(final long[] array) {
090        int elements = array.length;
091        long[] newArray = new long[elements];
092        System.arraycopy(array, 0, newArray, 0, elements);
093        return newArray;
094    }
095
096    /** Return a new array that is the result of appending array2 to the end
097     *  of array1. This method simply calls
098     *  append(array1, 0, array1.length, array2, 0, array2.length)
099     */
100    public static final long[] append(final long[] array1,
101            final long[] array2) {
102        return append(array1, 0, array1.length, array2, 0, array2.length);
103    }
104
105    /** Return a new array that is the result of appending length2
106     *  elements of array2, starting from the array1[idx2] to length1
107     *  elements of array1, starting from array1[idx1].
108     *  Appending empty arrays is supported. In that case, the corresponding
109     *  idx may be any number. Allow System.arraycopy() to throw array access
110     *  exceptions if idx .. idx + length - 1 are not all valid array indices,
111     *  for both of the arrays.
112     *  @param array1 The first array of longs.
113     *  @param idx1 The starting index for array1.
114     *  @param length1 The number of elements of array1 to use.
115     *  @param array2 The second array of longs, which is appended.
116     *  @param idx2 The starting index for array2.
117     *  @param length2 The number of elements of array2 to append.
118     *  @return A new array of longs.
119     */
120    public static final long[] append(final long[] array1, final int idx1,
121            final int length1, final long[] array2, final int idx2,
122            final int length2) {
123        long[] returnValue = new long[length1 + length2];
124
125        if (length1 > 0) {
126            System.arraycopy(array1, idx1, returnValue, 0, length1);
127        }
128
129        if (length2 > 0) {
130            System.arraycopy(array2, idx2, returnValue, length1, length2);
131        }
132
133        return returnValue;
134    }
135
136    /** Return a new array that is formed by applying an instance of a
137     *  LongBinaryOperation to each element in the input array
138     *  and z, using the array elements as the left operands and z
139     *  as the right operand in all cases. (op.operate(array[i], z)).
140     *  If the length of the array is 0, return a new array of length 0.
141     */
142    public static final long[] applyBinaryOperation(LongBinaryOperation op,
143            final long[] array, final long z) {
144        int length = array.length;
145        long[] returnValue = new long[length];
146
147        for (int i = 0; i < length; i++) {
148            returnValue[i] = op.operate(array[i], z);
149        }
150
151        return returnValue;
152    }
153
154    /** Return a new array that is formed by applying an instance of a
155     *  LongBinaryOperation to each element in the input array,
156     *  using z as the left operand in all cases and the array elements
157     *  as the right operands (op.operate(z, array[i])).
158     *  If the length of the array is 0, return a new array of length 0.
159     */
160    public static final long[] applyBinaryOperation(LongBinaryOperation op,
161            final long z, final long[] array) {
162        int length = array.length;
163        long[] returnValue = new long[length];
164
165        for (int i = 0; i < length; i++) {
166            returnValue[i] = op.operate(array[i], z);
167        }
168
169        return returnValue;
170    }
171
172    /** Return a new array that is formed by applying an instance of a
173     *  LongBinaryOperation to the two arrays, element by element,
174     *  using the elements of the first array as the left operands and the
175     *  elements of the second array as the right operands.
176     *  (op.operate(array[i], array2[i])).
177     *  If the lengths of both arrays are 0, return a new array of length 0.
178     *  If the two arrays do not have the same length, throw an
179     *  IllegalArgumentException.
180     */
181    public static final long[] applyBinaryOperation(LongBinaryOperation op,
182            final long[] array1, final long[] array2) {
183        int length = _commonLength(array1, array2,
184                "LongArrayMath.applyBinaryOperation");
185        long[] returnValue = new long[length];
186
187        for (int i = 0; i < length; i++) {
188            returnValue[i] = op.operate(array1[i], array2[i]);
189        }
190
191        return returnValue;
192    }
193
194    /** Return a new array that is formed by applying an instance of a
195     *  LongUnaryOperation to each element in the input array
196     *  (op.operate(array[i])).
197     *  If the length of the array is 0, return a new array of length 0.
198     */
199    public static final long[] applyUnaryOperation(final LongUnaryOperation op,
200            final long[] array) {
201        int length = array.length;
202        long[] returnValue = new long[length];
203
204        for (int i = 0; i < length; i++) {
205            returnValue[i] = op.operate(array[i]);
206        }
207
208        return returnValue;
209    }
210
211    /** Return a new array that is the formed by bitwise ANDing z with
212     *  each element of the input array (array[i] &amp; z).  If the length
213     *  of the array is 0, return a new array of length 0.
214     */
215    public static final long[] bitwiseAnd(final long[] array, final long z) {
216        int length = array.length;
217        long[] returnValue = new long[length];
218
219        for (int i = 0; i < length; i++) {
220            returnValue[i] = array[i] & z;
221        }
222
223        return returnValue;
224    }
225
226    /** Return a new array that is the element-by-element bitwise AND
227     *  of the two input arrays (array1[i] &amp; array2[i]).  If the
228     *  lengths of both arrays are 0, return a new array of length 0.
229     *  If the two arrays do not have the same length, throw an
230     *  IllegalArgumentException.
231     */
232    public static final long[] bitwiseAnd(final long[] array1,
233            final long[] array2) {
234        int length = _commonLength(array1, array2, "LongArrayMath.bitwiseAnd");
235        long[] returnValue = new long[length];
236
237        for (int i = 0; i < length; i++) {
238            returnValue[i] = array1[i] & array2[i];
239        }
240
241        return returnValue;
242    }
243
244    /** Return a new array that is the element-by-element bitwise
245     *  complement of the input array (~array[i]).  If the length of
246     *  the array is 0, return a new array of length 0.
247     */
248    public static final long[] bitwiseComplement(final long[] array) {
249        int length = array.length;
250        long[] returnValue = new long[length];
251
252        for (int i = 0; i < length; i++) {
253            returnValue[i] = ~array[i];
254        }
255
256        return returnValue;
257    }
258
259    /** Return a new array that is the formed by bitwise ORing z with
260     *  each element of the input array (array[i] | z).  If the length
261     *  of the array is 0, return a new array of length 0.
262     */
263    public static final long[] bitwiseOr(final long[] array, final long z) {
264        int length = array.length;
265        long[] returnValue = new long[length];
266
267        for (int i = 0; i < length; i++) {
268            returnValue[i] = array[i] | z;
269        }
270
271        return returnValue;
272    }
273
274    /** Return a new array that is the element-by-element bitwise OR of the two
275     *  input arrays (array1[i] | array2[i]).
276     *  If the lengths of both arrays are 0, return a new array of length 0.
277     *  If the two arrays do not have the same length, throw an
278     *  IllegalArgumentException.
279     */
280    public static final long[] bitwiseOr(final long[] array1,
281            final long[] array2) {
282        int length = _commonLength(array1, array2, "LongArrayMath.bitwiseOr");
283        long[] returnValue = new long[length];
284
285        for (int i = 0; i < length; i++) {
286            returnValue[i] = array1[i] | array2[i];
287        }
288
289        return returnValue;
290    }
291
292    /** Return a new array that is the formed by bitwise XORing z with
293     *  each element of the input array (array[i] ^ z).  If the length
294     *  of the array is 0, return a new array of length 0.
295     */
296    public static final long[] bitwiseXor(final long[] array, final long z) {
297        int length = array.length;
298        long[] returnValue = new long[length];
299
300        for (int i = 0; i < length; i++) {
301            returnValue[i] = array[i] ^ z;
302        }
303
304        return returnValue;
305    }
306
307    /** Return a new array that is the element-by-element bitwise XOR
308     *  of the two input arrays (array1[i] ^ array2[i]).  If the
309     *  lengths of both arrays are 0, return a new array of length 0.
310     *  If the two arrays do not have the same length, throw an
311     *  IllegalArgumentException.
312     */
313    public static final long[] bitwiseXor(final long[] array1,
314            final long[] array2) {
315        int length = _commonLength(array1, array2, "LongArrayMath.bitwiseXor");
316        long[] returnValue = new long[length];
317
318        for (int i = 0; i < length; i++) {
319            returnValue[i] = array1[i] ^ array2[i];
320        }
321
322        return returnValue;
323    }
324
325    /** Return a new array that is the formed by dividing each element
326     *  of the input array by z (array[i] / z).  If the length of the
327     *  array is 0, return a new array of length 0.
328     */
329    public static final long[] divide(final long[] array, final long z) {
330        int length = array.length;
331        long[] returnValue = new long[length];
332
333        for (int i = 0; i < length; i++) {
334            returnValue[i] = array[i] / z;
335        }
336
337        return returnValue;
338    }
339
340    /** Return a new array that is the element-by-element division of
341     *  the first array by the second array (array1[i] / array2[i]).
342     *  If the lengths of both arrays are 0, return a new array of length 0.
343     *  If the two arrays do not have the same length, throw an
344     *  IllegalArgumentException.
345     *  @param array1 The first array of longs.
346     *  @param array2 The second array of longs.
347     *  @return A new array of longs.
348     */
349    public static final long[] divideElements(final long[] array1,
350            final long[] array2) {
351        int length = _commonLength(array1, array2,
352                "LongArrayMath.divideElements");
353        long[] returnValue = new long[length];
354
355        for (int i = 0; i < length; i++) {
356            returnValue[i] = array1[i] / array2[i];
357        }
358
359        return returnValue;
360    }
361
362    /** Return the dot product of the two arrays.
363     *  If the lengths of the array are both 0, return 0L.
364     *  If the two arrays do not have the same length, throw an
365     *  IllegalArgumentException.
366     */
367    public static final long dotProduct(final long[] array1,
368            final long[] array2) {
369        int length = _commonLength(array1, array2, "LongArrayMath.dotProduct");
370
371        long sum = 0L;
372
373        for (int i = 0; i < length; i++) {
374            sum += array1[i] * array2[i];
375        }
376
377        return sum;
378    }
379
380    /** Return a new array that is a copy of the argument except that the
381     *  elements are limited to lie within the specified range.
382     *  <p> If any value is MAX_VALUE or MIN_VALUE,
383     *  then it is replaced by either the top or the bottom, depending on
384     *  its sign.  To leave either the bottom or the top unconstrained,
385     *  specify Long.MIN_VALUE or Long.MAX_VALUE.
386     *  <p> If the length of the array is 0, return a new array of length 0.
387     *  @param array An array of longs.
388     *  @param bottom The bottom limit.
389     *  @param top The top limit.
390     *  @return A new array with values in the range [bottom, top].
391     */
392    public static final long[] limit(final long[] array, final long bottom,
393            final long top) {
394        long[] returnValue = new long[array.length];
395
396        for (int i = 0; i < array.length; i++) {
397            if (array[i] > top || array[i] == Long.MAX_VALUE) {
398                returnValue[i] = top;
399            } else if (array[i] < bottom || array[i] == Long.MIN_VALUE) {
400                returnValue[i] = bottom;
401            } else {
402                returnValue[i] = array[i];
403            }
404        }
405
406        return returnValue;
407    }
408
409    /** Return a new array that is the formed by the modulo of each element
410     *  of the input array and z (array[i] % z).
411     */
412    public static final long[] modulo(final long[] array, final long z) {
413        int length = array.length;
414        long[] returnValue = new long[length];
415
416        for (int i = 0; i < length; i++) {
417            returnValue[i] = array[i] % z;
418        }
419
420        return returnValue;
421    }
422
423    /** Return a new array that is the element-by-element modulo of the two
424     *  input arrays (array1[i] % array2[i]).
425     *  If the lengths of both arrays are 0, return a new array of length 0.
426     *  If the two arrays do not have the same length, throw an
427     *  IllegalArgumentException.
428     */
429    public static final long[] modulo(final long[] array1,
430            final long[] array2) {
431        int length = _commonLength(array1, array2, "LongArrayMath.modulo");
432        long[] returnValue = new long[length];
433
434        for (int i = 0; i < length; i++) {
435            returnValue[i] = array1[i] % array2[i];
436        }
437
438        return returnValue;
439    }
440
441    /** Return a new array that is the element-by-element multiplication of
442     *  the two input arrays.
443     *  If the lengths of both arrays are 0, return a new array of length 0.
444     *  If the two arrays do not have the same length, throw an
445     *  IllegalArgumentException.
446     */
447    public static final long[] multiply(final long[] array1,
448            final long[] array2) {
449        int length = _commonLength(array1, array2, "LongArrayMath.multiply");
450        long[] returnValue = new long[length];
451
452        for (int i = 0; i < length; i++) {
453            returnValue[i] = array1[i] * array2[i];
454        }
455
456        return returnValue;
457    }
458
459    /** Return a new array that is constructed from the argument by
460     *  multiplying each element in the array by the second argument, which is
461     *  a long.
462     *  If the sizes of the array is 0, return a new array of size 0.
463     *  @param array An array of longs.
464     *  @param factor A long.
465     *  @return A new array of longs.
466     */
467    public static final long[] multiply(long[] array, long factor) {
468        int length = array.length;
469        long[] returnValue = new long[length];
470
471        for (int i = 0; i < length; i++) {
472            returnValue[i] = array[i] * factor;
473        }
474
475        return returnValue;
476    }
477
478    /** Return a new array that is the formed by the additive inverse of each
479     *  element of the input array (-array[i]).
480     */
481    public static final long[] negative(final long[] array) {
482        int length = array.length;
483        long[] returnValue = new long[length];
484
485        for (int i = 0; i < length; i++) {
486            returnValue[i] = -array[i];
487        }
488
489        return returnValue;
490    }
491
492    /** Return a new array of longs that is formed by padding the
493     *  middle of the array with 0's. If either the length of the
494     *  input array is odd, the sample with index ceil(L/2) will be
495     *  repeated in the output array, where L is the length of the input array.
496     *  If the length of the input and output arrays are equal, return
497     *  a copy of the input array.
498     *  This method is useful for preparing data for an IFFT.
499     *  @param array An array of longs.
500     *  @param newLength The desired length of the returned array.
501     *  @return A new array of longs.
502     */
503    public static final long[] padMiddle(final long[] array,
504            final int newLength) {
505        int length = array.length;
506
507        int entriesNeeded = newLength - length;
508
509        if (entriesNeeded < 0) {
510            throw new IllegalArgumentException("ptolemy.math."
511                    + "LongArrayMath.padMiddle() : newLength must be "
512                    + ">= length of array.");
513        } else if (entriesNeeded == 0) {
514            return resize(array, newLength); // allocates a new array
515        }
516
517        double halfLength = length * 0.5;
518        int halfLengthFloor = (int) Math.floor(halfLength);
519        int halfLengthCeil = (int) Math.ceil(halfLength);
520        long[] returnValue = new long[newLength];
521
522        System.arraycopy(array, 0, returnValue, 0, halfLengthCeil);
523
524        System.arraycopy(array, halfLengthFloor, returnValue,
525                newLength - halfLengthCeil, halfLengthCeil);
526
527        return returnValue;
528    }
529
530    /** Return a new array of length newLength that is formed by
531     *  either truncating or padding the input array.
532     *  This method simply calls :
533     *  resize(array, newLength, 0)
534     *  @param array An array of longs.
535     *  @param newLength The desired length of the output array.
536     *  @return A new array of longs of length newLength.
537     */
538    public static final long[] resize(final long[] array, final int newLength) {
539        return resize(array, newLength, 0);
540    }
541
542    /** Return a new array of length newLength that is formed by
543     *  either truncating or padding the input array.
544     *  Elements from the input array are copied to the output array,
545     *  starting from array[startIdx] until one of the following conditions
546     *  is met :
547     *  1) The input array has no more elements to copy.
548     *  2) The output array has been completely filled.
549     *  startIdx must index a valid entry in array unless the input array
550     *  is of zero length or the output array is of zero length.
551     *  If case 1) is met, the remainder of the output array is filled with
552     *  zero's, implicitly by Java (padding).
553     *  @param array An array of longs.
554     *  @param newLength The desired length of the output array.
555     *  @param startIdx The starting index for the input array.
556     *  @return A new array of longs of length newLength.
557     */
558    public static final long[] resize(long[] array, final int newLength,
559            final int startIdx) {
560        long[] returnValue = new long[newLength];
561        int copySize = Math.min(newLength, array.length - startIdx);
562
563        if (startIdx >= array.length && copySize > 0) {
564            throw new IllegalArgumentException("resize():  the start index '"
565                    + startIdx + "' is greater than equal to the array length '"
566                    + array.length + "' and the number of items to be copied '"
567                    + copySize + "' is greater than zero.");
568        }
569
570        if (copySize > 0) {
571            System.arraycopy(array, startIdx, returnValue, 0, copySize);
572        }
573
574        return returnValue;
575    }
576
577    /** Return a new array of longs produced by scaling the input
578     *  array elements by scaleFactor.
579     *  If the length of the array is 0, return a new array of length 0.
580     */
581    public static final long[] scale(long[] array, long scaleFactor) {
582        long[] returnValue = new long[array.length];
583
584        for (int i = 0; i < array.length; i++) {
585            returnValue[i] = scaleFactor * array[i];
586        }
587
588        return returnValue;
589    }
590
591    /** Return a new array that is constructed from the argument by
592     *  arithmetically shifting the elements in the array by the
593     *  second argument.  If the second argument is positive, the
594     *  elements are shifted left by the second argument. If the
595     *  second argument is negative, the elements are shifted right
596     *  (arithmetically, with the &gt;&gt;&gt; operator) by the absolute value
597     *  of the second argument. If the second argument is 0, no
598     *  operation is performed (the array is just copied).
599     *
600     *  @param array A first array of longs.
601     *  @param shiftAmount The amount to shift by, positive for left shift,
602     *  negative for right shift.
603     *  @return A new array of longs.
604     */
605    public static final long[] shiftArithmetic(long[] array, int shiftAmount) {
606        long[] returnValue = new long[array.length];
607
608        if (shiftAmount >= 0) {
609            for (int i = 0; i < array.length; i++) {
610                returnValue[i] = array[i] << shiftAmount;
611            }
612        } else if (shiftAmount < 0) {
613            for (int i = 0; i < array.length; i++) {
614                returnValue[i] = array[i] >>> -shiftAmount;
615            }
616        }
617
618        return returnValue;
619    }
620
621    /** Return a new array that is constructed from the argument by
622     *  logically shifting the elements in the array by the second
623     *  argument.  If the second argument is positive, the elements
624     *  are shifted left by the second argument. If the second
625     *  argument is negative, the elements are shifted right
626     *  (logically, with the &gt;&gt;&gt; operator) by the absolute value of
627     *  the second argument. If the second argument is 0, no operation
628     *  is performed (the array is just copied).
629     *
630     *  @param array A first array of longs.
631     *  @param shiftAmount The amount to shift by, positive for left shift,
632     *  negative for right shift.
633     *  @return A new array of longs.
634     */
635    public static final long[] shiftLogical(long[] array, int shiftAmount) {
636        long[] returnValue = new long[array.length];
637
638        if (shiftAmount >= 0) {
639            for (int i = 0; i < array.length; i++) {
640                returnValue[i] = array[i] << shiftAmount;
641            }
642        } else if (shiftAmount < 0) {
643            for (int i = 0; i < array.length; i++) {
644                returnValue[i] = array[i] >> -shiftAmount;
645            }
646        }
647
648        return returnValue;
649    }
650
651    /** Return a new array that is the element-by-element difference of the
652     *  two input arrays, i.e. the first array minus the second array
653     *  (array1[i] - array2[i]).
654     *  If the lengths of both arrays are 0, return a new array of length 0.
655     */
656    public static final long[] subtract(final long[] array1,
657            final long[] array2) {
658        int length = _commonLength(array1, array2, "LongArrayMath.subtract");
659        long[] returnValue = new long[length];
660
661        for (int i = 0; i < length; i++) {
662            returnValue[i] = array1[i] - array2[i];
663        }
664
665        return returnValue;
666    }
667
668    /** Return the sum of the squares of all of the elements in the array.
669     *  This is equivalent to the square of the L2-norm of the array.
670     *  Return 0L if the length of the array is 0.
671     */
672    public static final long sumOfSquares(long[] array) {
673        long sum = 0L;
674
675        for (long element : array) {
676            sum += element * element;
677        }
678
679        return sum;
680    }
681
682    /** Return a new array that is formed by converting the long numbers in
683     *  the argument array to complex numbers. Each complex number has
684     *  real part equal to the value in the argument array and a zero
685     *  imaginary part.
686     *
687     *  @param array An array of long numbers.
688     *  @return A new array of complex numbers.
689     */
690    public static final Complex[] toComplexArray(final long[] array) {
691        int length = array.length;
692        Complex[] returnValue = new Complex[length];
693
694        for (int i = 0; i < length; i++) {
695            returnValue[i] = new Complex(array[i], 0.0);
696        }
697
698        return returnValue;
699    }
700
701    /** Return a new array that is formed by converting the longs in
702     *  the argument array to doubles.  If the length of the argument
703     *  array is 0, return a new array of length 0.
704     *
705     *  @param array An array of long.
706     *  @return A new array of doubles.
707     */
708    public static final double[] toDoubleArray(final long[] array) {
709        int length = array.length;
710        double[] returnValue = new double[length];
711
712        for (int i = 0; i < length; i++) {
713            returnValue[i] = array[i];
714        }
715
716        return returnValue;
717    }
718
719    /** Return a new array that is formed by converting the longs in
720     *  the argument array to doubles.
721     *  If the length of the argument array is 0,
722     *  return a new array of length 0.
723     *  @param array An array of long.
724     *  @return A new array of doubles.
725     */
726    public static final float[] toFloatArray(final long[] array) {
727        int length = array.length;
728        float[] returnValue = new float[length];
729
730        for (int i = 0; i < length; i++) {
731            returnValue[i] = array[i];
732        }
733
734        return returnValue;
735    }
736
737    /** Return a new array that is formed by converting the longs in
738     *  the argument array to integers.
739     *  If the length of the argument array is 0,
740     *  return a new array of length 0.
741     *  @param array An array of long.
742     *  @return A new array of integers.
743     */
744    public static final int[] toIntegerArray(final long[] array) {
745        int length = array.length;
746        int[] returnValue = new int[length];
747
748        for (int i = 0; i < length; i++) {
749            returnValue[i] = (int) array[i];
750        }
751
752        return returnValue;
753    }
754
755    /** Return a new String representing the array, formatted as
756     *  in Java array initializers.
757     */
758    public static final String toString(final long[] array) {
759        return toString(array, ", ", "{", "}");
760    }
761
762    /** Return a new String representing the array, formatted as
763     *  specified by the ArrayStringFormat argument.
764     *  To get a String in the Ptolemy expression language format,
765     *  call this method with ArrayStringFormat.exprASFormat as the
766     *  format argument.
767     */
768    public static final String toString(final long[] array,
769            String elementDelimiter, String vectorBegin, String vectorEnd) {
770        int length = array.length;
771        StringBuffer sb = new StringBuffer();
772
773        sb.append(vectorBegin);
774
775        for (int i = 0; i < length; i++) {
776            sb.append(Long.toString(array[i]));
777
778            if (i < length - 1) {
779                sb.append(elementDelimiter);
780            }
781        }
782
783        sb.append(vectorEnd);
784
785        return new String(sb);
786    }
787
788    /** Return true if all the distances between corresponding elements
789     *  <i>array1</i> and <i>array2</i> are all less than or equal to
790     *  the corresponding elements in <i>maxError</i>. If both arrays
791     *  are empty, return true. If <i>maxError</i> is negative, return
792     *  false.
793     *
794     *  @param array1 The first array.
795     *  @param array2 The second array.
796     *  @param maxError The threshold for the magnitude of the difference.
797     *  @return True if all the distances between corresponding elements
798     *  <i>array1</i> and <i>array2</i> are all less than or equal to
799     *  the corresponding elements in <i>maxError</i>.
800     *  @exception IllegalArgumentException If the arrays are not of the same
801     *   length.
802     */
803    public static final boolean within(final long[] array1, final long[] array2,
804            long maxError) {
805        int length = _commonLength(array1, array2, "LongArrayMath.within");
806
807        for (int i = 0; i < length; i++) {
808            if (array1[i] > array2[i] + maxError
809                    || array1[i] < array2[i] - maxError) {
810                return false;
811            }
812        }
813
814        return true;
815    }
816
817    /** Return true if all the distances between corresponding elements
818     *  <i>array1</i> and <i>array2</i> are all less than or equal to
819     *  the corresponding elements in <i>maxError</i>. If both arrays
820     *  are empty, return true. If any element of <i>maxError</i> is
821     *  negative, return false.
822     *
823     *  @param array1 The first array.
824     *  @param array2 The second array.
825     *  @param maxError The array of thresholds for the magnitudes of
826     *   the difference.
827     *  @return True if all the distances between corresponding elements
828     *  <i>array1</i> and <i>array2</i> are all less than or equal to
829     *  the corresponding elements in <i>maxError</i>.
830     *  @exception IllegalArgumentException If the arrays are not of the same
831     *   length.
832     */
833    public static final boolean within(final long[] array1, final long[] array2,
834            long[] maxError) {
835        int length = _commonLength(array1, array2, "LongArrayMath.within");
836
837        for (int i = 0; i < length; i++) {
838            if (array1[i] > array2[i] + maxError[i]
839                    || array1[i] < array2[i] - maxError[i]) {
840                return false;
841            }
842        }
843
844        return true;
845    }
846
847    ///////////////////////////////////////////////////////////////////
848    ////                         protected methods                 ////
849
850    /** Throw an exception if the two arrays are not of the same length,
851     *  or if either array is null. An exception is NOT thrown if both
852     *  arrays are of length 0. If no exception is thrown, return the common
853     *  length of the arrays.
854     *  @param array1 The first array of longs.
855     *  @param array2 The second array of longs.
856     *  @param methodName A String representing the method name of the caller,
857     *  without parentheses.
858     *  @return The common length of both arrays.
859     */
860    protected static final int _commonLength(final long[] array1,
861            final long[] array2, String methodName) {
862        if (array1 == null) {
863            throw new IllegalArgumentException("ptolemy.math." + methodName
864                    + "() : first input array is null.");
865        }
866
867        if (array2 == null) {
868            throw new IllegalArgumentException("ptolemy.math." + methodName
869                    + "() : second input array is null.");
870        }
871
872        if (array1.length != array2.length) {
873            throw new IllegalArgumentException("ptolemy.math." + methodName
874                    + "() : input arrays must have the same length, "
875                    + "but the first array has length " + array1.length
876                    + " and the second array has length " + array2.length
877                    + ".");
878        }
879
880        return array1.length;
881    }
882}