001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    
018    package org.apache.commons.math3.util;
019    
020    import java.util.List;
021    import java.util.ArrayList;
022    import java.util.Comparator;
023    import java.util.Collections;
024    
025    import org.apache.commons.math3.exception.DimensionMismatchException;
026    import org.apache.commons.math3.exception.MathInternalError;
027    import org.apache.commons.math3.exception.NonMonotonicSequenceException;
028    import org.apache.commons.math3.exception.NotPositiveException;
029    import org.apache.commons.math3.exception.NotStrictlyPositiveException;
030    import org.apache.commons.math3.exception.NullArgumentException;
031    import org.apache.commons.math3.exception.MathIllegalArgumentException;
032    import org.apache.commons.math3.exception.util.LocalizedFormats;
033    import org.apache.commons.math3.exception.MathArithmeticException;
034    
035    /**
036     * Arrays utilities.
037     *
038     * @since 3.0
039     * @version $Id: MathArrays.java 1422313 2012-12-15 18:53:41Z psteitz $
040     */
041    public class MathArrays {
042        /** Factor used for splitting double numbers: n = 2^27 + 1 (i.e. {@value}). */
043        private static final int SPLIT_FACTOR = 0x8000001;
044    
045        /**
046         * Private constructor.
047         */
048        private MathArrays() {}
049    
050        /**
051         * Real-valued function that operate on an array or a part of it.
052         * @since 3.1
053         */
054        public interface Function {
055            /**
056             * Operates on an entire array.
057             *
058             * @param array Array to operate on.
059             * @return the result of the operation.
060             */
061            double evaluate(double[] array);
062            /**
063             * @param array Array to operate on.
064             * @param startIndex Index of the first element to take into account.
065             * @param numElements Number of elements to take into account.
066             * @return the result of the operation.
067             */
068            double evaluate(double[] array,
069                            int startIndex,
070                            int numElements);
071        }
072    
073        /**
074         * Creates an array whose contents will be the element-by-element
075         * addition of the arguments.
076         *
077         * @param a First term of the addition.
078         * @param b Second term of the addition.
079         * @return a new array {@code r} where {@code r[i] = a[i] + b[i]}.
080         * @throws DimensionMismatchException if the array lengths differ.
081         * @since 3.1
082         */
083        public static double[] ebeAdd(double[] a,
084                                      double[] b) {
085            if (a.length != b.length) {
086                throw new DimensionMismatchException(a.length, b.length);
087            }
088    
089            final double[] result = a.clone();
090            for (int i = 0; i < a.length; i++) {
091                result[i] += b[i];
092            }
093            return result;
094        }
095        /**
096         * Creates an array whose contents will be the element-by-element
097         * subtraction of the second argument from the first.
098         *
099         * @param a First term.
100         * @param b Element to be subtracted.
101         * @return a new array {@code r} where {@code r[i] = a[i] - b[i]}.
102         * @throws DimensionMismatchException if the array lengths differ.
103         * @since 3.1
104         */
105        public static double[] ebeSubtract(double[] a,
106                                           double[] b) {
107            if (a.length != b.length) {
108                throw new DimensionMismatchException(a.length, b.length);
109            }
110    
111            final double[] result = a.clone();
112            for (int i = 0; i < a.length; i++) {
113                result[i] -= b[i];
114            }
115            return result;
116        }
117        /**
118         * Creates an array whose contents will be the element-by-element
119         * multiplication of the arguments.
120         *
121         * @param a First factor of the multiplication.
122         * @param b Second factor of the multiplication.
123         * @return a new array {@code r} where {@code r[i] = a[i] * b[i]}.
124         * @throws DimensionMismatchException if the array lengths differ.
125         * @since 3.1
126         */
127        public static double[] ebeMultiply(double[] a,
128                                           double[] b) {
129            if (a.length != b.length) {
130                throw new DimensionMismatchException(a.length, b.length);
131            }
132    
133            final double[] result = a.clone();
134            for (int i = 0; i < a.length; i++) {
135                result[i] *= b[i];
136            }
137            return result;
138        }
139        /**
140         * Creates an array whose contents will be the element-by-element
141         * division of the first argument by the second.
142         *
143         * @param a Numerator of the division.
144         * @param b Denominator of the division.
145         * @return a new array {@code r} where {@code r[i] = a[i] / b[i]}.
146         * @throws DimensionMismatchException if the array lengths differ.
147         * @since 3.1
148         */
149        public static double[] ebeDivide(double[] a,
150                                         double[] b) {
151            if (a.length != b.length) {
152                throw new DimensionMismatchException(a.length, b.length);
153            }
154    
155            final double[] result = a.clone();
156            for (int i = 0; i < a.length; i++) {
157                result[i] /= b[i];
158            }
159            return result;
160        }
161    
162        /**
163         * Calculates the L<sub>1</sub> (sum of abs) distance between two points.
164         *
165         * @param p1 the first point
166         * @param p2 the second point
167         * @return the L<sub>1</sub> distance between the two points
168         */
169        public static double distance1(double[] p1, double[] p2) {
170            double sum = 0;
171            for (int i = 0; i < p1.length; i++) {
172                sum += FastMath.abs(p1[i] - p2[i]);
173            }
174            return sum;
175        }
176    
177        /**
178         * Calculates the L<sub>1</sub> (sum of abs) distance between two points.
179         *
180         * @param p1 the first point
181         * @param p2 the second point
182         * @return the L<sub>1</sub> distance between the two points
183         */
184        public static int distance1(int[] p1, int[] p2) {
185          int sum = 0;
186          for (int i = 0; i < p1.length; i++) {
187              sum += FastMath.abs(p1[i] - p2[i]);
188          }
189          return sum;
190        }
191    
192        /**
193         * Calculates the L<sub>2</sub> (Euclidean) distance between two points.
194         *
195         * @param p1 the first point
196         * @param p2 the second point
197         * @return the L<sub>2</sub> distance between the two points
198         */
199        public static double distance(double[] p1, double[] p2) {
200            double sum = 0;
201            for (int i = 0; i < p1.length; i++) {
202                final double dp = p1[i] - p2[i];
203                sum += dp * dp;
204            }
205            return FastMath.sqrt(sum);
206        }
207    
208        /**
209         * Calculates the L<sub>2</sub> (Euclidean) distance between two points.
210         *
211         * @param p1 the first point
212         * @param p2 the second point
213         * @return the L<sub>2</sub> distance between the two points
214         */
215        public static double distance(int[] p1, int[] p2) {
216          double sum = 0;
217          for (int i = 0; i < p1.length; i++) {
218              final double dp = p1[i] - p2[i];
219              sum += dp * dp;
220          }
221          return FastMath.sqrt(sum);
222        }
223    
224        /**
225         * Calculates the L<sub>&infin;</sub> (max of abs) distance between two points.
226         *
227         * @param p1 the first point
228         * @param p2 the second point
229         * @return the L<sub>&infin;</sub> distance between the two points
230         */
231        public static double distanceInf(double[] p1, double[] p2) {
232            double max = 0;
233            for (int i = 0; i < p1.length; i++) {
234                max = FastMath.max(max, FastMath.abs(p1[i] - p2[i]));
235            }
236            return max;
237        }
238    
239        /**
240         * Calculates the L<sub>&infin;</sub> (max of abs) distance between two points.
241         *
242         * @param p1 the first point
243         * @param p2 the second point
244         * @return the L<sub>&infin;</sub> distance between the two points
245         */
246        public static int distanceInf(int[] p1, int[] p2) {
247            int max = 0;
248            for (int i = 0; i < p1.length; i++) {
249                max = FastMath.max(max, FastMath.abs(p1[i] - p2[i]));
250            }
251            return max;
252        }
253    
254        /**
255         * Specification of ordering direction.
256         */
257        public static enum OrderDirection {
258            /** Constant for increasing direction. */
259            INCREASING,
260            /** Constant for decreasing direction. */
261            DECREASING
262        }
263    
264        /**
265         * Check that an array is monotonically increasing or decreasing.
266         *
267         * @param <T> the type of the elements in the specified array
268         * @param val Values.
269         * @param dir Ordering direction.
270         * @param strict Whether the order should be strict.
271         * @return {@code true} if sorted, {@code false} otherwise.
272         */
273        public static  <T extends Comparable<? super T>> boolean isMonotonic(T[] val,
274                                          OrderDirection dir,
275                                          boolean strict) {
276            T previous = val[0];
277            final int max = val.length;
278            for (int i = 1; i < max; i++) {
279                final int comp;
280                switch (dir) {
281                case INCREASING:
282                    comp = previous.compareTo(val[i]);
283                    if (strict) {
284                        if (comp >= 0) {
285                            return false;
286                        }
287                    } else {
288                        if (comp > 0) {
289                            return false;
290                        }
291                    }
292                    break;
293                case DECREASING:
294                    comp = val[i].compareTo(previous);
295                    if (strict) {
296                        if (comp >= 0) {
297                            return false;
298                        }
299                    } else {
300                        if (comp > 0) {
301                           return false;
302                        }
303                    }
304                    break;
305                default:
306                    // Should never happen.
307                    throw new MathInternalError();
308                }
309    
310                previous = val[i];
311            }
312            return true;
313        }
314    
315        /**
316         * Check that an array is monotonically increasing or decreasing.
317         *
318         * @param val Values.
319         * @param dir Ordering direction.
320         * @param strict Whether the order should be strict.
321         * @return {@code true} if sorted, {@code false} otherwise.
322         */
323        public static boolean isMonotonic(double[] val,
324                                          OrderDirection dir,
325                                          boolean strict) {
326            return checkOrder(val, dir, strict, false);
327        }
328    
329        /**
330         * Check that the given array is sorted.
331         *
332         * @param val Values.
333         * @param dir Ordering direction.
334         * @param strict Whether the order should be strict.
335         * @param abort Whether to throw an exception if the check fails.
336         * @return {@code true} if the array is sorted.
337         * @throws NonMonotonicSequenceException if the array is not sorted
338         * and {@code abort} is {@code true}.
339         */
340        public static boolean checkOrder(double[] val, OrderDirection dir,
341                                         boolean strict, boolean abort)
342            throws NonMonotonicSequenceException {
343            double previous = val[0];
344            final int max = val.length;
345    
346            int index;
347            ITEM:
348            for (index = 1; index < max; index++) {
349                switch (dir) {
350                case INCREASING:
351                    if (strict) {
352                        if (val[index] <= previous) {
353                            break ITEM;
354                        }
355                    } else {
356                        if (val[index] < previous) {
357                            break ITEM;
358                        }
359                    }
360                    break;
361                case DECREASING:
362                    if (strict) {
363                        if (val[index] >= previous) {
364                            break ITEM;
365                        }
366                    } else {
367                        if (val[index] > previous) {
368                            break ITEM;
369                        }
370                    }
371                    break;
372                default:
373                    // Should never happen.
374                    throw new MathInternalError();
375                }
376    
377                previous = val[index];
378            }
379    
380            if (index == max) {
381                // Loop completed.
382                return true;
383            }
384    
385            // Loop early exit means wrong ordering.
386            if (abort) {
387                throw new NonMonotonicSequenceException(val[index], previous, index, dir, strict);
388            } else {
389                return false;
390            }
391        }
392    
393        /**
394         * Check that the given array is sorted.
395         *
396         * @param val Values.
397         * @param dir Ordering direction.
398         * @param strict Whether the order should be strict.
399         * @throws NonMonotonicSequenceException if the array is not sorted.
400         * @since 2.2
401         */
402        public static void checkOrder(double[] val, OrderDirection dir,
403                                      boolean strict) throws NonMonotonicSequenceException {
404            checkOrder(val, dir, strict, true);
405        }
406    
407        /**
408         * Check that the given array is sorted in strictly increasing order.
409         *
410         * @param val Values.
411         * @throws NonMonotonicSequenceException if the array is not sorted.
412         * @since 2.2
413         */
414        public static void checkOrder(double[] val) throws NonMonotonicSequenceException {
415            checkOrder(val, OrderDirection.INCREASING, true);
416        }
417    
418        /**
419         * Throws DimensionMismatchException if the input array is not rectangular.
420         *
421         * @param in array to be tested
422         * @throws NullArgumentException if input array is null
423         * @throws DimensionMismatchException if input array is not rectangular
424         * @since 3.1
425         */
426        public static void checkRectangular(final long[][] in)
427            throws NullArgumentException, DimensionMismatchException {
428            MathUtils.checkNotNull(in);
429            for (int i = 1; i < in.length; i++) {
430                if (in[i].length != in[0].length) {
431                    throw new DimensionMismatchException(
432                            LocalizedFormats.DIFFERENT_ROWS_LENGTHS,
433                            in[i].length, in[0].length);
434                }
435            }
436        }
437    
438        /**
439         * Check that all entries of the input array are strictly positive.
440         *
441         * @param in Array to be tested
442         * @throws NotStrictlyPositiveException if any entries of the array are not
443         * strictly positive.
444         * @since 3.1
445         */
446        public static void checkPositive(final double[] in)
447            throws NotStrictlyPositiveException {
448            for (int i = 0; i < in.length; i++) {
449                if (in[i] <= 0) {
450                    throw new NotStrictlyPositiveException(in[i]);
451                }
452            }
453        }
454    
455        /**
456         * Check that all entries of the input array are >= 0.
457         *
458         * @param in Array to be tested
459         * @throws NotPositiveException if any array entries are less than 0.
460         * @since 3.1
461         */
462        public static void checkNonNegative(final long[] in)
463            throws NotPositiveException {
464            for (int i = 0; i < in.length; i++) {
465                if (in[i] < 0) {
466                    throw new NotPositiveException(in[i]);
467                }
468            }
469        }
470    
471        /**
472         * Check all entries of the input array are >= 0.
473         *
474         * @param in Array to be tested
475         * @throws NotPositiveException if any array entries are less than 0.
476         * @since 3.1
477         */
478        public static void checkNonNegative(final long[][] in)
479            throws NotPositiveException {
480            for (int i = 0; i < in.length; i ++) {
481                for (int j = 0; j < in[i].length; j++) {
482                    if (in[i][j] < 0) {
483                        throw new NotPositiveException(in[i][j]);
484                    }
485                }
486            }
487        }
488    
489        /**
490         * Returns the Cartesian norm (2-norm), handling both overflow and underflow.
491         * Translation of the minpack enorm subroutine.
492         *
493         * The redistribution policy for MINPACK is available
494         * <a href="http://www.netlib.org/minpack/disclaimer">here</a>, for
495         * convenience, it is reproduced below.</p>
496         *
497         * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
498         * <tr><td>
499         *    Minpack Copyright Notice (1999) University of Chicago.
500         *    All rights reserved
501         * </td></tr>
502         * <tr><td>
503         * Redistribution and use in source and binary forms, with or without
504         * modification, are permitted provided that the following conditions
505         * are met:
506         * <ol>
507         *  <li>Redistributions of source code must retain the above copyright
508         *      notice, this list of conditions and the following disclaimer.</li>
509         * <li>Redistributions in binary form must reproduce the above
510         *     copyright notice, this list of conditions and the following
511         *     disclaimer in the documentation and/or other materials provided
512         *     with the distribution.</li>
513         * <li>The end-user documentation included with the redistribution, if any,
514         *     must include the following acknowledgment:
515         *     {@code This product includes software developed by the University of
516         *           Chicago, as Operator of Argonne National Laboratory.}
517         *     Alternately, this acknowledgment may appear in the software itself,
518         *     if and wherever such third-party acknowledgments normally appear.</li>
519         * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
520         *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
521         *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
522         *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
523         *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
524         *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
525         *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
526         *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
527         *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
528         *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
529         *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
530         *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
531         *     BE CORRECTED.</strong></li>
532         * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
533         *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
534         *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
535         *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
536         *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
537         *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
538         *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
539         *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
540         *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
541         *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
542         * <ol></td></tr>
543         * </table>
544         *
545         * @param v Vector of doubles.
546         * @return the 2-norm of the vector.
547         * @since 2.2
548         */
549        public static double safeNorm(double[] v) {
550            double rdwarf = 3.834e-20;
551            double rgiant = 1.304e+19;
552            double s1 = 0;
553            double s2 = 0;
554            double s3 = 0;
555            double x1max = 0;
556            double x3max = 0;
557            double floatn = v.length;
558            double agiant = rgiant / floatn;
559            for (int i = 0; i < v.length; i++) {
560                double xabs = Math.abs(v[i]);
561                if (xabs < rdwarf || xabs > agiant) {
562                    if (xabs > rdwarf) {
563                        if (xabs > x1max) {
564                            double r = x1max / xabs;
565                            s1= 1 + s1 * r * r;
566                            x1max = xabs;
567                        } else {
568                            double r = xabs / x1max;
569                            s1 += r * r;
570                        }
571                    } else {
572                        if (xabs > x3max) {
573                            double r = x3max / xabs;
574                            s3= 1 + s3 * r * r;
575                            x3max = xabs;
576                        } else {
577                            if (xabs != 0) {
578                                double r = xabs / x3max;
579                                s3 += r * r;
580                            }
581                        }
582                    }
583                } else {
584                    s2 += xabs * xabs;
585                }
586            }
587            double norm;
588            if (s1 != 0) {
589                norm = x1max * Math.sqrt(s1 + (s2 / x1max) / x1max);
590            } else {
591                if (s2 == 0) {
592                    norm = x3max * Math.sqrt(s3);
593                } else {
594                    if (s2 >= x3max) {
595                        norm = Math.sqrt(s2 * (1 + (x3max / s2) * (x3max * s3)));
596                    } else {
597                        norm = Math.sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
598                    }
599                }
600            }
601            return norm;
602        }
603    
604        /**
605         * Sort an array in ascending order in place and perform the same reordering
606         * of entries on other arrays. For example, if
607         * {@code x = [3, 1, 2], y = [1, 2, 3]} and {@code z = [0, 5, 7]}, then
608         * {@code sortInPlace(x, y, z)} will update {@code x} to {@code [1, 2, 3]},
609         * {@code y} to {@code [2, 3, 1]} and {@code z} to {@code [5, 7, 0]}.
610         *
611         * @param x Array to be sorted and used as a pattern for permutation
612         * of the other arrays.
613         * @param yList Set of arrays whose permutations of entries will follow
614         * those performed on {@code x}.
615         * @throws DimensionMismatchException if any {@code y} is not the same
616         * size as {@code x}.
617         * @throws NullArgumentException if {@code x} or any {@code y} is null.
618         * @since 3.0
619         */
620        public static void sortInPlace(double[] x, double[] ... yList)
621            throws DimensionMismatchException, NullArgumentException {
622            sortInPlace(x, OrderDirection.INCREASING, yList);
623        }
624    
625        /**
626         * Sort an array in place and perform the same reordering of entries on
627         * other arrays.  This method works the same as the other
628         * {@link #sortInPlace(double[], double[][]) sortInPlace} method, but
629         * allows the order of the sort to be provided in the {@code dir}
630         * parameter.
631         *
632         * @param x Array to be sorted and used as a pattern for permutation
633         * of the other arrays.
634         * @param dir Order direction.
635         * @param yList Set of arrays whose permutations of entries will follow
636         * those performed on {@code x}.
637         * @throws DimensionMismatchException if any {@code y} is not the same
638         * size as {@code x}.
639         * @throws NullArgumentException if {@code x} or any {@code y} is null
640         * @since 3.0
641         */
642        public static void sortInPlace(double[] x,
643                                       final OrderDirection dir,
644                                       double[] ... yList)
645            throws NullArgumentException, DimensionMismatchException {
646            if (x == null) {
647                throw new NullArgumentException();
648            }
649    
650            final int len = x.length;
651            final List<Pair<Double, double[]>> list
652                = new ArrayList<Pair<Double, double[]>>(len);
653    
654            final int yListLen = yList.length;
655            for (int i = 0; i < len; i++) {
656                final double[] yValues = new double[yListLen];
657                for (int j = 0; j < yListLen; j++) {
658                    double[] y = yList[j];
659                    if (y == null) {
660                        throw new NullArgumentException();
661                    }
662                    if (y.length != len) {
663                        throw new DimensionMismatchException(y.length, len);
664                    }
665                    yValues[j] = y[i];
666                }
667                list.add(new Pair<Double, double[]>(x[i], yValues));
668            }
669    
670            final Comparator<Pair<Double, double[]>> comp
671                = new Comparator<Pair<Double, double[]>>() {
672                public int compare(Pair<Double, double[]> o1,
673                                   Pair<Double, double[]> o2) {
674                    int val;
675                    switch (dir) {
676                    case INCREASING:
677                        val = o1.getKey().compareTo(o2.getKey());
678                    break;
679                    case DECREASING:
680                        val = o2.getKey().compareTo(o1.getKey());
681                    break;
682                    default:
683                        // Should never happen.
684                        throw new MathInternalError();
685                    }
686                    return val;
687                }
688            };
689    
690            Collections.sort(list, comp);
691    
692            for (int i = 0; i < len; i++) {
693                final Pair<Double, double[]> e = list.get(i);
694                x[i] = e.getKey();
695                final double[] yValues = e.getValue();
696                for (int j = 0; j < yListLen; j++) {
697                    yList[j][i] = yValues[j];
698                }
699            }
700        }
701    
702        /**
703         * Creates a copy of the {@code source} array.
704         *
705         * @param source Array to be copied.
706         * @return the copied array.
707         */
708         public static int[] copyOf(int[] source) {
709             return copyOf(source, source.length);
710         }
711    
712        /**
713         * Creates a copy of the {@code source} array.
714         *
715         * @param source Array to be copied.
716         * @return the copied array.
717         */
718         public static double[] copyOf(double[] source) {
719             return copyOf(source, source.length);
720         }
721    
722        /**
723         * Creates a copy of the {@code source} array.
724         *
725         * @param source Array to be copied.
726         * @param len Number of entries to copy. If smaller then the source
727         * length, the copy will be truncated, if larger it will padded with
728         * zeroes.
729         * @return the copied array.
730         */
731        public static int[] copyOf(int[] source, int len) {
732             final int[] output = new int[len];
733             System.arraycopy(source, 0, output, 0, FastMath.min(len, source.length));
734             return output;
735         }
736    
737        /**
738         * Creates a copy of the {@code source} array.
739         *
740         * @param source Array to be copied.
741         * @param len Number of entries to copy. If smaller then the source
742         * length, the copy will be truncated, if larger it will padded with
743         * zeroes.
744         * @return the copied array.
745         */
746        public static double[] copyOf(double[] source, int len) {
747             final double[] output = new double[len];
748             System.arraycopy(source, 0, output, 0, FastMath.min(len, source.length));
749             return output;
750         }
751    
752        /**
753         * Compute a linear combination accurately.
754         * This method computes the sum of the products
755         * <code>a<sub>i</sub> b<sub>i</sub></code> to high accuracy.
756         * It does so by using specific multiplication and addition algorithms to
757         * preserve accuracy and reduce cancellation effects.
758         * <br/>
759         * It is based on the 2005 paper
760         * <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
761         * Accurate Sum and Dot Product</a> by Takeshi Ogita, Siegfried M. Rump,
762         * and Shin'ichi Oishi published in SIAM J. Sci. Comput.
763         *
764         * @param a Factors.
765         * @param b Factors.
766         * @return <code>&Sigma;<sub>i</sub> a<sub>i</sub> b<sub>i</sub></code>.
767         * @throws DimensionMismatchException if arrays dimensions don't match
768         */
769        public static double linearCombination(final double[] a, final double[] b)
770            throws DimensionMismatchException {
771            final int len = a.length;
772            if (len != b.length) {
773                throw new DimensionMismatchException(len, b.length);
774            }
775    
776            final double[] prodHigh = new double[len];
777            double prodLowSum = 0;
778    
779            for (int i = 0; i < len; i++) {
780                final double ai = a[i];
781                final double ca = SPLIT_FACTOR * ai;
782                final double aHigh = ca - (ca - ai);
783                final double aLow = ai - aHigh;
784    
785                final double bi = b[i];
786                final double cb = SPLIT_FACTOR * bi;
787                final double bHigh = cb - (cb - bi);
788                final double bLow = bi - bHigh;
789                prodHigh[i] = ai * bi;
790                final double prodLow = aLow * bLow - (((prodHigh[i] -
791                                                        aHigh * bHigh) -
792                                                       aLow * bHigh) -
793                                                      aHigh * bLow);
794                prodLowSum += prodLow;
795            }
796    
797    
798            final double prodHighCur = prodHigh[0];
799            double prodHighNext = prodHigh[1];
800            double sHighPrev = prodHighCur + prodHighNext;
801            double sPrime = sHighPrev - prodHighNext;
802            double sLowSum = (prodHighNext - (sHighPrev - sPrime)) + (prodHighCur - sPrime);
803    
804            final int lenMinusOne = len - 1;
805            for (int i = 1; i < lenMinusOne; i++) {
806                prodHighNext = prodHigh[i + 1];
807                final double sHighCur = sHighPrev + prodHighNext;
808                sPrime = sHighCur - prodHighNext;
809                sLowSum += (prodHighNext - (sHighCur - sPrime)) + (sHighPrev - sPrime);
810                sHighPrev = sHighCur;
811            }
812    
813            double result = sHighPrev + (prodLowSum + sLowSum);
814    
815            if (Double.isNaN(result)) {
816                // either we have split infinite numbers or some coefficients were NaNs,
817                // just rely on the naive implementation and let IEEE754 handle this
818                result = 0;
819                for (int i = 0; i < len; ++i) {
820                    result += a[i] * b[i];
821                }
822            }
823    
824            return result;
825        }
826    
827        /**
828         * Compute a linear combination accurately.
829         * <p>
830         * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
831         * a<sub>2</sub>&times;b<sub>2</sub> to high accuracy. It does
832         * so by using specific multiplication and addition algorithms to
833         * preserve accuracy and reduce cancellation effects. It is based
834         * on the 2005 paper <a
835         * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
836         * Accurate Sum and Dot Product</a> by Takeshi Ogita,
837         * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
838         * </p>
839         * @param a1 first factor of the first term
840         * @param b1 second factor of the first term
841         * @param a2 first factor of the second term
842         * @param b2 second factor of the second term
843         * @return a<sub>1</sub>&times;b<sub>1</sub> +
844         * a<sub>2</sub>&times;b<sub>2</sub>
845         * @see #linearCombination(double, double, double, double, double, double)
846         * @see #linearCombination(double, double, double, double, double, double, double, double)
847         */
848        public static double linearCombination(final double a1, final double b1,
849                                               final double a2, final double b2) {
850    
851            // the code below is split in many additions/subtractions that may
852            // appear redundant. However, they should NOT be simplified, as they
853            // use IEEE754 floating point arithmetic rounding properties.
854            // as an example, the expression "ca1 - (ca1 - a1)" is NOT the same as "a1"
855            // The variable naming conventions are that xyzHigh contains the most significant
856            // bits of xyz and xyzLow contains its least significant bits. So theoretically
857            // xyz is the sum xyzHigh + xyzLow, but in many cases below, this sum cannot
858            // be represented in only one double precision number so we preserve two numbers
859            // to hold it as long as we can, combining the high and low order bits together
860            // only at the end, after cancellation may have occurred on high order bits
861    
862            // split a1 and b1 as two 26 bits numbers
863            final double ca1        = SPLIT_FACTOR * a1;
864            final double a1High     = ca1 - (ca1 - a1);
865            final double a1Low      = a1 - a1High;
866            final double cb1        = SPLIT_FACTOR * b1;
867            final double b1High     = cb1 - (cb1 - b1);
868            final double b1Low      = b1 - b1High;
869    
870            // accurate multiplication a1 * b1
871            final double prod1High  = a1 * b1;
872            final double prod1Low   = a1Low * b1Low - (((prod1High - a1High * b1High) - a1Low * b1High) - a1High * b1Low);
873    
874            // split a2 and b2 as two 26 bits numbers
875            final double ca2        = SPLIT_FACTOR * a2;
876            final double a2High     = ca2 - (ca2 - a2);
877            final double a2Low      = a2 - a2High;
878            final double cb2        = SPLIT_FACTOR * b2;
879            final double b2High     = cb2 - (cb2 - b2);
880            final double b2Low      = b2 - b2High;
881    
882            // accurate multiplication a2 * b2
883            final double prod2High  = a2 * b2;
884            final double prod2Low   = a2Low * b2Low - (((prod2High - a2High * b2High) - a2Low * b2High) - a2High * b2Low);
885    
886            // accurate addition a1 * b1 + a2 * b2
887            final double s12High    = prod1High + prod2High;
888            final double s12Prime   = s12High - prod2High;
889            final double s12Low     = (prod2High - (s12High - s12Prime)) + (prod1High - s12Prime);
890    
891            // final rounding, s12 may have suffered many cancellations, we try
892            // to recover some bits from the extra words we have saved up to now
893            double result = s12High + (prod1Low + prod2Low + s12Low);
894    
895            if (Double.isNaN(result)) {
896                // either we have split infinite numbers or some coefficients were NaNs,
897                // just rely on the naive implementation and let IEEE754 handle this
898                result = a1 * b1 + a2 * b2;
899            }
900    
901            return result;
902        }
903    
904        /**
905         * Compute a linear combination accurately.
906         * <p>
907         * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
908         * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
909         * to high accuracy. It does so by using specific multiplication and
910         * addition algorithms to preserve accuracy and reduce cancellation effects.
911         * It is based on the 2005 paper <a
912         * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
913         * Accurate Sum and Dot Product</a> by Takeshi Ogita,
914         * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
915         * </p>
916         * @param a1 first factor of the first term
917         * @param b1 second factor of the first term
918         * @param a2 first factor of the second term
919         * @param b2 second factor of the second term
920         * @param a3 first factor of the third term
921         * @param b3 second factor of the third term
922         * @return a<sub>1</sub>&times;b<sub>1</sub> +
923         * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub>
924         * @see #linearCombination(double, double, double, double)
925         * @see #linearCombination(double, double, double, double, double, double, double, double)
926         */
927        public static double linearCombination(final double a1, final double b1,
928                                               final double a2, final double b2,
929                                               final double a3, final double b3) {
930    
931            // the code below is split in many additions/subtractions that may
932            // appear redundant. However, they should NOT be simplified, as they
933            // do use IEEE754 floating point arithmetic rounding properties.
934            // as an example, the expression "ca1 - (ca1 - a1)" is NOT the same as "a1"
935            // The variables naming conventions are that xyzHigh contains the most significant
936            // bits of xyz and xyzLow contains its least significant bits. So theoretically
937            // xyz is the sum xyzHigh + xyzLow, but in many cases below, this sum cannot
938            // be represented in only one double precision number so we preserve two numbers
939            // to hold it as long as we can, combining the high and low order bits together
940            // only at the end, after cancellation may have occurred on high order bits
941    
942            // split a1 and b1 as two 26 bits numbers
943            final double ca1        = SPLIT_FACTOR * a1;
944            final double a1High     = ca1 - (ca1 - a1);
945            final double a1Low      = a1 - a1High;
946            final double cb1        = SPLIT_FACTOR * b1;
947            final double b1High     = cb1 - (cb1 - b1);
948            final double b1Low      = b1 - b1High;
949    
950            // accurate multiplication a1 * b1
951            final double prod1High  = a1 * b1;
952            final double prod1Low   = a1Low * b1Low - (((prod1High - a1High * b1High) - a1Low * b1High) - a1High * b1Low);
953    
954            // split a2 and b2 as two 26 bits numbers
955            final double ca2        = SPLIT_FACTOR * a2;
956            final double a2High     = ca2 - (ca2 - a2);
957            final double a2Low      = a2 - a2High;
958            final double cb2        = SPLIT_FACTOR * b2;
959            final double b2High     = cb2 - (cb2 - b2);
960            final double b2Low      = b2 - b2High;
961    
962            // accurate multiplication a2 * b2
963            final double prod2High  = a2 * b2;
964            final double prod2Low   = a2Low * b2Low - (((prod2High - a2High * b2High) - a2Low * b2High) - a2High * b2Low);
965    
966            // split a3 and b3 as two 26 bits numbers
967            final double ca3        = SPLIT_FACTOR * a3;
968            final double a3High     = ca3 - (ca3 - a3);
969            final double a3Low      = a3 - a3High;
970            final double cb3        = SPLIT_FACTOR * b3;
971            final double b3High     = cb3 - (cb3 - b3);
972            final double b3Low      = b3 - b3High;
973    
974            // accurate multiplication a3 * b3
975            final double prod3High  = a3 * b3;
976            final double prod3Low   = a3Low * b3Low - (((prod3High - a3High * b3High) - a3Low * b3High) - a3High * b3Low);
977    
978            // accurate addition a1 * b1 + a2 * b2
979            final double s12High    = prod1High + prod2High;
980            final double s12Prime   = s12High - prod2High;
981            final double s12Low     = (prod2High - (s12High - s12Prime)) + (prod1High - s12Prime);
982    
983            // accurate addition a1 * b1 + a2 * b2 + a3 * b3
984            final double s123High   = s12High + prod3High;
985            final double s123Prime  = s123High - prod3High;
986            final double s123Low    = (prod3High - (s123High - s123Prime)) + (s12High - s123Prime);
987    
988            // final rounding, s123 may have suffered many cancellations, we try
989            // to recover some bits from the extra words we have saved up to now
990            double result = s123High + (prod1Low + prod2Low + prod3Low + s12Low + s123Low);
991    
992            if (Double.isNaN(result)) {
993                // either we have split infinite numbers or some coefficients were NaNs,
994                // just rely on the naive implementation and let IEEE754 handle this
995                result = a1 * b1 + a2 * b2 + a3 * b3;
996            }
997    
998            return result;
999        }
1000    
1001        /**
1002         * Compute a linear combination accurately.
1003         * <p>
1004         * This method computes a<sub>1</sub>&times;b<sub>1</sub> +
1005         * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
1006         * a<sub>4</sub>&times;b<sub>4</sub>
1007         * to high accuracy. It does so by using specific multiplication and
1008         * addition algorithms to preserve accuracy and reduce cancellation effects.
1009         * It is based on the 2005 paper <a
1010         * href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.2.1547">
1011         * Accurate Sum and Dot Product</a> by Takeshi Ogita,
1012         * Siegfried M. Rump, and Shin'ichi Oishi published in SIAM J. Sci. Comput.
1013         * </p>
1014         * @param a1 first factor of the first term
1015         * @param b1 second factor of the first term
1016         * @param a2 first factor of the second term
1017         * @param b2 second factor of the second term
1018         * @param a3 first factor of the third term
1019         * @param b3 second factor of the third term
1020         * @param a4 first factor of the third term
1021         * @param b4 second factor of the third term
1022         * @return a<sub>1</sub>&times;b<sub>1</sub> +
1023         * a<sub>2</sub>&times;b<sub>2</sub> + a<sub>3</sub>&times;b<sub>3</sub> +
1024         * a<sub>4</sub>&times;b<sub>4</sub>
1025         * @see #linearCombination(double, double, double, double)
1026         * @see #linearCombination(double, double, double, double, double, double)
1027         */
1028        public static double linearCombination(final double a1, final double b1,
1029                                               final double a2, final double b2,
1030                                               final double a3, final double b3,
1031                                               final double a4, final double b4) {
1032    
1033            // the code below is split in many additions/subtractions that may
1034            // appear redundant. However, they should NOT be simplified, as they
1035            // do use IEEE754 floating point arithmetic rounding properties.
1036            // as an example, the expression "ca1 - (ca1 - a1)" is NOT the same as "a1"
1037            // The variables naming conventions are that xyzHigh contains the most significant
1038            // bits of xyz and xyzLow contains its least significant bits. So theoretically
1039            // xyz is the sum xyzHigh + xyzLow, but in many cases below, this sum cannot
1040            // be represented in only one double precision number so we preserve two numbers
1041            // to hold it as long as we can, combining the high and low order bits together
1042            // only at the end, after cancellation may have occurred on high order bits
1043    
1044            // split a1 and b1 as two 26 bits numbers
1045            final double ca1        = SPLIT_FACTOR * a1;
1046            final double a1High     = ca1 - (ca1 - a1);
1047            final double a1Low      = a1 - a1High;
1048            final double cb1        = SPLIT_FACTOR * b1;
1049            final double b1High     = cb1 - (cb1 - b1);
1050            final double b1Low      = b1 - b1High;
1051    
1052            // accurate multiplication a1 * b1
1053            final double prod1High  = a1 * b1;
1054            final double prod1Low   = a1Low * b1Low - (((prod1High - a1High * b1High) - a1Low * b1High) - a1High * b1Low);
1055    
1056            // split a2 and b2 as two 26 bits numbers
1057            final double ca2        = SPLIT_FACTOR * a2;
1058            final double a2High     = ca2 - (ca2 - a2);
1059            final double a2Low      = a2 - a2High;
1060            final double cb2        = SPLIT_FACTOR * b2;
1061            final double b2High     = cb2 - (cb2 - b2);
1062            final double b2Low      = b2 - b2High;
1063    
1064            // accurate multiplication a2 * b2
1065            final double prod2High  = a2 * b2;
1066            final double prod2Low   = a2Low * b2Low - (((prod2High - a2High * b2High) - a2Low * b2High) - a2High * b2Low);
1067    
1068            // split a3 and b3 as two 26 bits numbers
1069            final double ca3        = SPLIT_FACTOR * a3;
1070            final double a3High     = ca3 - (ca3 - a3);
1071            final double a3Low      = a3 - a3High;
1072            final double cb3        = SPLIT_FACTOR * b3;
1073            final double b3High     = cb3 - (cb3 - b3);
1074            final double b3Low      = b3 - b3High;
1075    
1076            // accurate multiplication a3 * b3
1077            final double prod3High  = a3 * b3;
1078            final double prod3Low   = a3Low * b3Low - (((prod3High - a3High * b3High) - a3Low * b3High) - a3High * b3Low);
1079    
1080            // split a4 and b4 as two 26 bits numbers
1081            final double ca4        = SPLIT_FACTOR * a4;
1082            final double a4High     = ca4 - (ca4 - a4);
1083            final double a4Low      = a4 - a4High;
1084            final double cb4        = SPLIT_FACTOR * b4;
1085            final double b4High     = cb4 - (cb4 - b4);
1086            final double b4Low      = b4 - b4High;
1087    
1088            // accurate multiplication a4 * b4
1089            final double prod4High  = a4 * b4;
1090            final double prod4Low   = a4Low * b4Low - (((prod4High - a4High * b4High) - a4Low * b4High) - a4High * b4Low);
1091    
1092            // accurate addition a1 * b1 + a2 * b2
1093            final double s12High    = prod1High + prod2High;
1094            final double s12Prime   = s12High - prod2High;
1095            final double s12Low     = (prod2High - (s12High - s12Prime)) + (prod1High - s12Prime);
1096    
1097            // accurate addition a1 * b1 + a2 * b2 + a3 * b3
1098            final double s123High   = s12High + prod3High;
1099            final double s123Prime  = s123High - prod3High;
1100            final double s123Low    = (prod3High - (s123High - s123Prime)) + (s12High - s123Prime);
1101    
1102            // accurate addition a1 * b1 + a2 * b2 + a3 * b3 + a4 * b4
1103            final double s1234High  = s123High + prod4High;
1104            final double s1234Prime = s1234High - prod4High;
1105            final double s1234Low   = (prod4High - (s1234High - s1234Prime)) + (s123High - s1234Prime);
1106    
1107            // final rounding, s1234 may have suffered many cancellations, we try
1108            // to recover some bits from the extra words we have saved up to now
1109            double result = s1234High + (prod1Low + prod2Low + prod3Low + prod4Low + s12Low + s123Low + s1234Low);
1110    
1111            if (Double.isNaN(result)) {
1112                // either we have split infinite numbers or some coefficients were NaNs,
1113                // just rely on the naive implementation and let IEEE754 handle this
1114                result = a1 * b1 + a2 * b2 + a3 * b3 + a4 * b4;
1115            }
1116    
1117            return result;
1118        }
1119    
1120        /**
1121         * Returns true iff both arguments are null or have same dimensions and all
1122         * their elements are equal as defined by
1123         * {@link Precision#equals(float,float)}.
1124         *
1125         * @param x first array
1126         * @param y second array
1127         * @return true if the values are both null or have same dimension
1128         * and equal elements.
1129         */
1130        public static boolean equals(float[] x, float[] y) {
1131            if ((x == null) || (y == null)) {
1132                return !((x == null) ^ (y == null));
1133            }
1134            if (x.length != y.length) {
1135                return false;
1136            }
1137            for (int i = 0; i < x.length; ++i) {
1138                if (!Precision.equals(x[i], y[i])) {
1139                    return false;
1140                }
1141            }
1142            return true;
1143        }
1144    
1145        /**
1146         * Returns true iff both arguments are null or have same dimensions and all
1147         * their elements are equal as defined by
1148         * {@link Precision#equalsIncludingNaN(double,double) this method}.
1149         *
1150         * @param x first array
1151         * @param y second array
1152         * @return true if the values are both null or have same dimension and
1153         * equal elements
1154         * @since 2.2
1155         */
1156        public static boolean equalsIncludingNaN(float[] x, float[] y) {
1157            if ((x == null) || (y == null)) {
1158                return !((x == null) ^ (y == null));
1159            }
1160            if (x.length != y.length) {
1161                return false;
1162            }
1163            for (int i = 0; i < x.length; ++i) {
1164                if (!Precision.equalsIncludingNaN(x[i], y[i])) {
1165                    return false;
1166                }
1167            }
1168            return true;
1169        }
1170    
1171        /**
1172         * Returns {@code true} iff both arguments are {@code null} or have same
1173         * dimensions and all their elements are equal as defined by
1174         * {@link Precision#equals(double,double)}.
1175         *
1176         * @param x First array.
1177         * @param y Second array.
1178         * @return {@code true} if the values are both {@code null} or have same
1179         * dimension and equal elements.
1180         */
1181        public static boolean equals(double[] x, double[] y) {
1182            if ((x == null) || (y == null)) {
1183                return !((x == null) ^ (y == null));
1184            }
1185            if (x.length != y.length) {
1186                return false;
1187            }
1188            for (int i = 0; i < x.length; ++i) {
1189                if (!Precision.equals(x[i], y[i])) {
1190                    return false;
1191                }
1192            }
1193            return true;
1194        }
1195    
1196        /**
1197         * Returns {@code true} iff both arguments are {@code null} or have same
1198         * dimensions and all their elements are equal as defined by
1199         * {@link Precision#equalsIncludingNaN(double,double) this method}.
1200         *
1201         * @param x First array.
1202         * @param y Second array.
1203         * @return {@code true} if the values are both {@code null} or have same
1204         * dimension and equal elements.
1205         * @since 2.2
1206         */
1207        public static boolean equalsIncludingNaN(double[] x, double[] y) {
1208            if ((x == null) || (y == null)) {
1209                return !((x == null) ^ (y == null));
1210            }
1211            if (x.length != y.length) {
1212                return false;
1213            }
1214            for (int i = 0; i < x.length; ++i) {
1215                if (!Precision.equalsIncludingNaN(x[i], y[i])) {
1216                    return false;
1217                }
1218            }
1219            return true;
1220        }
1221    
1222         /**
1223          * Normalizes an array to make it sum to a specified value.
1224          * Returns the result of the transformation <pre>
1225          *    x |-> x * normalizedSum / sum
1226          * </pre>
1227          * applied to each non-NaN element x of the input array, where sum is the
1228          * sum of the non-NaN entries in the input array.</p>
1229          *
1230          * <p>Throws IllegalArgumentException if {@code normalizedSum} is infinite
1231          * or NaN and ArithmeticException if the input array contains any infinite elements
1232          * or sums to 0.</p>
1233          *
1234          * <p>Ignores (i.e., copies unchanged to the output array) NaNs in the input array.</p>
1235          *
1236          * @param values Input array to be normalized
1237          * @param normalizedSum Target sum for the normalized array
1238          * @return the normalized array.
1239          * @throws MathArithmeticException if the input array contains infinite
1240          * elements or sums to zero.
1241          * @throws MathIllegalArgumentException if the target sum is infinite or {@code NaN}.
1242          * @since 2.1
1243          */
1244         public static double[] normalizeArray(double[] values, double normalizedSum)
1245             throws MathIllegalArgumentException, MathArithmeticException {
1246             if (Double.isInfinite(normalizedSum)) {
1247                 throw new MathIllegalArgumentException(LocalizedFormats.NORMALIZE_INFINITE);
1248             }
1249             if (Double.isNaN(normalizedSum)) {
1250                 throw new MathIllegalArgumentException(LocalizedFormats.NORMALIZE_NAN);
1251             }
1252             double sum = 0d;
1253             final int len = values.length;
1254             double[] out = new double[len];
1255             for (int i = 0; i < len; i++) {
1256                 if (Double.isInfinite(values[i])) {
1257                     throw new MathIllegalArgumentException(LocalizedFormats.INFINITE_ARRAY_ELEMENT, values[i], i);
1258                 }
1259                 if (!Double.isNaN(values[i])) {
1260                     sum += values[i];
1261                 }
1262             }
1263             if (sum == 0) {
1264                 throw new MathArithmeticException(LocalizedFormats.ARRAY_SUMS_TO_ZERO);
1265             }
1266             for (int i = 0; i < len; i++) {
1267                 if (Double.isNaN(values[i])) {
1268                     out[i] = Double.NaN;
1269                 } else {
1270                     out[i] = values[i] * normalizedSum / sum;
1271                 }
1272             }
1273             return out;
1274         }
1275    }