001/*
002 A library for mathematical operations on arrays of doubles.
003
004 This file was automatically generated with a preprocessor, so that
005 similar array operations are supported on ints, longs, floats, and doubles.
006
007 Copyright (c) 2004-2013 The Regents of the University of California.
008 All rights reserved.
009
010 Permission is hereby granted, without written agreement and without
011 license or royalty fees, to use, copy, modify, and distribute this
012 software and its documentation for any purpose, provided that the above
013 copyright notice and the following two paragraphs appear in all copies
014 of this software.
015
016 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
017 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
018 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
019 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
020 SUCH DAMAGE.
021
022 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
023 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
024 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
025 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
026 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
027 ENHANCEMENTS, OR MODIFICATIONS.
028
029 PT_COPYRIGHT_VERSION_2
030 COPYRIGHTENDKEY
031
032 */
033package ptolemy.math;
034
035///////////////////////////////////////////////////////////////////
036//// FractionArrayMath
037
038/**
039 A library for mathematical operations on Fraction arrays.
040
041 <p>Unless explicitly noted otherwise, all array arguments are assumed to be
042 non-null. If a null array is passed to a method, a NullPointerException
043 will be thrown in the method or called methods.
044
045 @author Adam Cataldo
046 @version $Id$
047 @since Ptolemy II 5.0
048 @Pt.ProposedRating Red (acataldo)
049 @Pt.AcceptedRating Red (cxh)
050 */
051public class FractionArrayMath {
052    // Protected constructor prevents construction of this class.
053    protected FractionArrayMath() {
054    }
055
056    ///////////////////////////////////////////////////////////////////
057    ////                         public methods                    ////
058
059    /** Return a new array that is the formed by adding z to each element
060     *  of the input array.
061     */
062    public static final Fraction[] add(Fraction[] array, final Fraction z) {
063        int length = array.length;
064        Fraction[] returnValue = new Fraction[length];
065
066        for (int i = 0; i < length; i++) {
067            returnValue[i] = array[i].add(z);
068        }
069
070        return returnValue;
071    }
072
073    /** Return a new array that is the element-by-element sum of the two
074     *  input arrays.
075     *  If the lengths of both arrays are 0, return a new array of length 0.
076     *  If the two arrays do not have the same length, throw an
077     *  IllegalArgumentException.
078     */
079    public static final Fraction[] add(final Fraction[] array1,
080            final Fraction[] array2) {
081        int length = _commonLength(array1, array2, "FractionArrayMath.add");
082        Fraction[] returnValue = new Fraction[length];
083
084        for (int i = 0; i < length; i++) {
085            returnValue[i] = array1[i].add(array2[i]);
086        }
087
088        return returnValue;
089    }
090
091    /** Return a new array that is a copy of the array argument.
092     *  @param array An array of Fractions.
093     *  @return A new array of Fractions.
094     */
095    public static final Fraction[] allocCopy(final Fraction[] array) {
096        int elements = array.length;
097        Fraction[] newArray = new Fraction[elements];
098        System.arraycopy(array, 0, newArray, 0, elements);
099        return newArray;
100    }
101
102    /** Return a new array that is the result of appending array2 to the end
103     *  of array1. This method simply calls
104     *  append(array1, 0, array1.length, array2, 0, array2.length)
105     */
106    public static final Fraction[] append(final Fraction[] array1,
107            final Fraction[] array2) {
108        return append(array1, 0, array1.length, array2, 0, array2.length);
109    }
110
111    /** Return a new array that is the result of appending length2
112     *  elements of array2, starting from the array2[idx2] to length1
113     *  elements of array1, starting from array1[idx1].  Appending
114     *  empty arrays is supported. In that case, the corresponding idx
115     *  may be any number. Allow System.arraycopy() to throw array
116     *  access exceptions if idx .. idx + length - 1 are not all valid
117     *  array indices, for both of the arrays.
118     *
119     *  @param array1 The first array of Fractions.
120     *  @param idx1 The starting index for array1.
121     *  @param length1 The number of elements of array1 to use.
122     *  @param array2 The second array of Fractions, which is appended.
123     *  @param idx2 The starting index for array2.
124     *  @param length2 The number of elements of array2 to append.
125     *  @return A new array of doubles.
126     */
127    public static final Fraction[] append(final Fraction[] array1,
128            final int idx1, final int length1, final Fraction[] array2,
129            final int idx2, final int length2) {
130        Fraction[] returnValue = new Fraction[length1 + length2];
131
132        if (length1 > 0) {
133            System.arraycopy(array1, idx1, returnValue, 0, length1);
134        }
135
136        if (length2 > 0) {
137            System.arraycopy(array2, idx2, returnValue, length1, length2);
138        }
139
140        return returnValue;
141    }
142
143    /** Return a new array that is the element-by-element division of
144     *  the first array by the second array.
145     *  @param num The numerator array of Fractions.
146     *  @param den The denominator array of Fractions.
147     *  @return A new array of Fractions.
148     */
149    public static final Fraction[] divide(Fraction[] num, Fraction[] den) {
150        int length = _commonLength(num, den, "divide");
151        Fraction[] returnValue = new Fraction[length];
152
153        for (int i = 0; i < length; i++) {
154            returnValue[i] = num[i].divide(den[i]);
155        }
156
157        return returnValue;
158    }
159
160    /** Return the dot product of the two arrays.
161     *  If the lengths of the array are both 0, return 0/1.
162     *  If the two arrays do not have the same length, throw an
163     *  IllegalArgumentException.
164     */
165    public static final Fraction dotProduct(final Fraction[] array1,
166            final Fraction[] array2) {
167        int length = _commonLength(array1, array2,
168                "FractionArrayMath.dotProduct");
169
170        Fraction sum = new Fraction(0, 1);
171
172        for (int i = 0; i < length; i++) {
173            sum = sum.add(array1[i].multiply(array2[i]));
174        }
175
176        return sum;
177    }
178
179    /** Returns true if the two input arrays have all elements
180     *  equal.
181     *
182     * @param array1 The first input array.
183     * @param array2 The second input array.
184     * @return True if array1 == array2.
185     */
186    public static final boolean equals(final Fraction[] array1,
187            final Fraction[] array2) {
188        boolean output = true;
189
190        if (array1.length != array2.length) {
191            output = false;
192        } else {
193            for (int i = 0; i < array1.length; i++) {
194                output = output && array1[i].equals(array2[i]);
195            }
196        }
197
198        return output;
199    }
200
201    /** Return a new array that is the element-by-element multiplication of
202     *  the two input arrays.
203     *  If the lengths of both arrays are 0, return a new array of length 0.
204     *  If the two arrays do not have the same length, throw an
205     *  IllegalArgumentException.
206     */
207    public static final Fraction[] multiply(final Fraction[] array1,
208            final Fraction[] array2) {
209        int length = _commonLength(array1, array2,
210                "FractionArrayMath.multiply");
211        Fraction[] returnValue = new Fraction[length];
212
213        for (int i = 0; i < length; i++) {
214            returnValue[i] = array1[i].multiply(array2[i]);
215        }
216
217        return returnValue;
218    }
219
220    /** Return a new array that is constructed from the argument by
221     *  multiplying each element in the array by the second argument, which is
222     *  a Fraction.
223     *  If the sizes of the array is 0, return a new array of size 0.
224     *  @param array An array of Fractions.
225     *  @param factor A Fraction.
226     *  @return A new array of Fractions.
227     */
228    public static final Fraction[] multiply(Fraction[] array, Fraction factor) {
229        int length = array.length;
230        Fraction[] returnValue = new Fraction[length];
231
232        for (int i = 0; i < length; i++) {
233            returnValue[i] = array[i].multiply(factor);
234        }
235
236        return returnValue;
237    }
238
239    /** Return a new array that is the formed by the additive inverse of each
240     *  element of the input array (-array[i]).
241     */
242    public static final Fraction[] negative(final Fraction[] array) {
243        int length = array.length;
244        Fraction[] returnValue = new Fraction[length];
245
246        for (int i = 0; i < length; i++) {
247            returnValue[i] = array[i].negate();
248        }
249
250        return returnValue;
251    }
252
253    /** Return a new array that is the element-by-element difference of the
254     *  two input arrays, i.e. the first array minus the second array
255     *  (array1[i] - array2[i]).
256     *  If the lengths of both arrays are 0, return a new array of length 0.
257     */
258    public static final Fraction[] subtract(final Fraction[] array1,
259            final Fraction[] array2) {
260        int length = _commonLength(array1, array2,
261                "FractionArrayMath.subtract");
262        Fraction[] returnValue = new Fraction[length];
263
264        for (int i = 0; i < length; i++) {
265            returnValue[i] = array1[i].subtract(array2[i]);
266        }
267
268        return returnValue;
269    }
270
271    /** Return the sum of the elements in the array.
272     *  Return 0/1 if the length of the array is 0.
273     */
274    public static final Fraction sum(Fraction[] array) {
275        Fraction sum = new Fraction(0, 1);
276
277        for (Fraction element : array) {
278            sum = sum.add(element);
279        }
280
281        return sum;
282    }
283
284    /** Return a new array that is formed by converting the Fractions in
285     *  the argument array to doubles.  If the length of the argument
286     *  array is 0, return a new array of length 0.
287     *  @param array An array of Fractions.
288     *  @return A new array of doubles.
289     */
290    public static final double[] toDoubleArray(final Fraction[] array) {
291        int length = array.length;
292        double[] returnValue = new double[length];
293
294        for (int i = 0; i < length; i++) {
295            returnValue[i] = array[i].toDouble();
296        }
297
298        return returnValue;
299    }
300
301    /** Return a new String representing the array, formatted as
302     *  in Java array initializers.
303     */
304    public static final String toString(final Fraction[] array) {
305        return toString(array, ", ", "{", "}");
306    }
307
308    /** Return a new String representing the array, formatted as
309     *  specified by the ArrayStringFormat argument.
310     *  To get a String in the Ptolemy expression language format,
311     *  call this method with ArrayStringFormat.exprASFormat as the
312     *  format argument.
313     */
314    public static final String toString(final Fraction[] array,
315            String elementDelimiter, String vectorBegin, String vectorEnd) {
316        int length = array.length;
317        StringBuffer sb = new StringBuffer();
318
319        sb.append(vectorBegin);
320
321        for (int i = 0; i < length; i++) {
322            sb.append(array[i].toString());
323
324            if (i < length - 1) {
325                sb.append(elementDelimiter);
326            }
327        }
328
329        sb.append(vectorEnd);
330
331        return new String(sb);
332    }
333
334    /** Throw an exception if the two arrays are not of the same length,
335     *  or if either array is null. An exception is NOT thrown if both
336     *  arrays are of length 0. If no exception is thrown, return the common
337     *  length of the arrays.
338     *  @param array1 The first array of Fractions.
339     *  @param array2 The second array of Fractions.
340     *  @param methodName A String representing the method name of the caller,
341     *  without parentheses.
342     *  @return The common length of both arrays.
343     */
344    protected static final int _commonLength(final Fraction[] array1,
345            final Fraction[] array2, String methodName) {
346        if (array1 == null) {
347            throw new IllegalArgumentException("ptolemy.math." + methodName
348                    + "() : first input array is null.");
349        }
350
351        if (array2 == null) {
352            throw new IllegalArgumentException("ptolemy.math." + methodName
353                    + "() : second input array is null.");
354        }
355
356        if (array1.length != array2.length) {
357            throw new IllegalArgumentException("ptolemy.math." + methodName
358                    + "() : input arrays must have the same length, "
359                    + "but the first array has length " + array1.length
360                    + " and the second array has length " + array2.length
361                    + ".");
362        }
363
364        return array1.length;
365    }
366}