All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.dfki.lt.signalproc.util.MathUtils Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2004-2006 DFKI GmbH.
 * All Rights Reserved.  Use is subject to license terms.
 * 
 * Permission is hereby granted, free of charge, to use and distribute
 * this software and its documentation without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of this work, and to
 * permit persons to whom this work is furnished to do so, subject to
 * the following conditions:
 * 
 * 1. The code must retain the above copyright notice, this list of
 *    conditions and the following disclaimer.
 * 2. Any modifications must be clearly marked as such.
 * 3. Original authors' names are not deleted.
 * 4. The authors' names are not used to endorse or promote products
 *    derived from this software without specific prior written
 *    permission.
 *
 * DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
 * CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 * THIS SOFTWARE.
 */

package de.dfki.lt.signalproc.util;

import java.util.Arrays;
import java.util.Collections;
import java.util.Vector;


// TODO: Auto-generated Javadoc
/**
 * The Class MathUtils.
 *
 * @author Marc Schröder, Oytun Tuerk
 * 
 * 
 * An uninstantiable class, containing static utility methods in the Math domain.
 */
public class MathUtils {
    
    /** The Constant PASCAL. */
    protected static final double PASCAL = 2E-5;
    
    /** The Constant PASCALSQUARE. */
    protected static final double PASCALSQUARE = 4E-10;
    
    /** The Constant LOG10. */
    protected static final double LOG10 = Math.log(10);

    /** The Constant TWOPI. */
    public static final double TWOPI = 2*Math.PI;

    /** The Constant EQUALS. */
    public static final int EQUALS = 0;
    
    /** The Constant GREATER_THAN. */
    public static final int GREATER_THAN = 1;
    
    /** The Constant GREATER_THAN_OR_EQUALS. */
    public static final int GREATER_THAN_OR_EQUALS = 2;
    
    /** The Constant LESS_THAN. */
    public static final int LESS_THAN = 3;
    
    /** The Constant LESS_THAN_OR_EQUALS. */
    public static final int LESS_THAN_OR_EQUALS = 4;
    
    /** The Constant NOT_EQUALS. */
    public static final int NOT_EQUALS = 5;

    /**
     * Checks if is power of two.
     *
     * @param N the n
     * @return true, if is power of two
     */
    public static boolean isPowerOfTwo(int N)
    {
        final int maxBits = 32;
        int n=2;
        for (int i=2; i<=maxBits; i++) {
            if (n==N) return true;
            n<<=1;
        }
        return false;
    }

    /**
     * Closest power of two above.
     *
     * @param N the n
     * @return the int
     */
    public static int closestPowerOfTwoAbove(int N)
    {
        return 1<<(int) Math.ceil(Math.log(N)/Math.log(2));
    }

    /**
     * Find next valley location.
     *
     * @param data the data
     * @param startIndex the start index
     * @return the int
     */
    public static int findNextValleyLocation(double[] data, int startIndex)
    {
        for (int i=startIndex+1; idata[i]) return i-1;
        }
        return data.length-1;
    }

    /**
     * Find the maximum of all elements in the array, ignoring elements that are NaN.
     *
     * @param data the data
     * @return the index number of the maximum element
     */
    public static int findGlobalPeakLocation(double[] data)
    {
        double max = Double.NaN;
        int imax = -1;
        for (int i=0; i max) {
                max = data[i];
                imax = i;
            }
        }
        return imax;
    }

    /**
     * Find the minimum of all elements in the array, ignoring elements that are NaN.
     *
     * @param data the data
     * @return the index number of the minimum element
     */
    public static int findGlobalValleyLocation(double[] data)
    {
        double min = Double.NaN;
        int imin = -1;
        for (int i=0; i max) max = data[i];
        }
        return max;
    }

    /**
     * Max.
     *
     * @param data the data
     * @return the int
     */
    public static int max(int[] data)
    {
        int max = data[0];
        for (int i=1; i max) 
                max = data[i];
        }
        return max;
    }

    /**
     * Find the maximum of the absolute values of all elements in the array, ignoring elements that are NaN.
     *
     * @param data the data
     * @return the double
     */
    public static double absMax(double[] data)
    {
        double max = Double.NaN;
        for (int i=0; i max) max = abs;
        }
        return max;
    }

    /**
     * Find the minimum of all elements in the array, ignoring elements that are NaN.
     *
     * @param data the data
     * @return the double
     */
    public static double min(double[] data)
    {
        double min = Double.NaN;
        for (int i=0; iendIndex)
            startIndex = endIndex;

        for (int i=startIndex; i<=endIndex; i++) {
            if (Double.isNaN(data[i]))
                throw new IllegalArgumentException("NaN not allowed in mean calculation");
            mean += data[i];
            total++;
        }
        mean /= total;
        return mean;
    }

    /**
     * Compute the mean of all elements in the array with given indices. No missing values (NaN) are allowed.
     *
     * @param data the data
     * @param inds the inds
     * @return the double
     */
    public static double mean(double[] data, int [] inds)
    {
        double mean = 0;
        for (int i=0; iendIndex)
            startIndex = endIndex;

        for (int i=startIndex; i<=endIndex; i++) {
            if (Float.isNaN(data[i]))
                throw new IllegalArgumentException("NaN not allowed in mean calculation");
            mean += data[i];
            total++;
        }
        mean /= total;
        return mean;
    }

    /**
     * Mean.
     *
     * @param data the data
     * @return the float
     */
    public static float mean(float[] data)
    {
        return mean(data, 0, data.length-1);
    }

    /**
     * Compute the mean of all elements in the array with given indices. No missing values (NaN) are allowed.
     *
     * @param data the data
     * @param inds the inds
     * @return the float
     */
    public static float mean(float[] data, int [] inds)
    {
        float mean = 0;
        for (int i=0; idata.length-1)
            startIndex=data.length-1;
        if (endIndexdata.length-1)
            endIndex=data.length-1;

        for (int i=startIndex; i<=endIndex; i++)
            var += (data[i]-meanVal)*(data[i]-meanVal);

        if (endIndex-startIndex>1)
            var /= (endIndex-startIndex);

        return var;
    }

    /**
     * Variance.
     *
     * @param x the x
     * @param meanVector the mean vector
     * @return the double[]
     */
    public static double[] variance(double[][]x, double[] meanVector)
    {
        return variance(x, meanVector, true);   
    }

    /**
     * Returns the variance of rows or columns of matrix x.
     *
     * @param x the matrix consisting of row vectors
     * @param meanVector the mean vector
     * @param isAlongRows the is along rows
     * @return the double[]
     */
    public static double[] variance(double[][]x, double[] meanVector, boolean isAlongRows)
    {
        double[] var = null;

        if (x!=null && x[0]!=null && x[0].length>0 && meanVector != null)
        {
            if (isAlongRows) 
            {
                var = new double[x[0].length];
                int j, i;
                for (j=0; j should return a matrix provided that the sizes are appropriate
    /**
     * Matrix product.
     *
     * @param x the x
     * @param y the y
     * @return the double[][]
     */
    public static double[][] matrixProduct(double[][] x, double[][] y)
    {
        double[][] z = null;

        if (x!=null && y!=null)
        {
            if (x.length==1 && y.length==1) //Special case -- diagonal matrix multiplication, returns a diagonal matrix
            {
                assert x[0].length==y[0].length;
                z = new double[1][x[0].length];
                for (int i=0; iMath.min(c.real.length-1,c.imag.length-1))
            startInd=Math.min(c.real.length-1,c.imag.length-1);
        if (endIndMath.min(c.real.length-1,c.imag.length-1))
            endInd=Math.min(c.real.length-1,c.imag.length-1);

        double[] dbs = new double[endInd-startInd+1];
        for (int i=startInd; i<=endInd; i++)
            dbs[i-startInd] = 10*log10(c.real[i]*c.real[i]+c.imag[i]*c.imag[i]);

        return dbs;
    }

    /**
     * Convert energy from db scale to linear scale.
     *
     * @param dbEnergy the db energy
     * @return energy on a linear scale.
     */
    public static double db2linear(double dbEnergy)
    {
        if (Double.isNaN(dbEnergy)) return 0.;
        else return exp10(dbEnergy/10);
    }

    /**
     * Db2linear.
     *
     * @param dbEnergies the db energies
     * @return the double[]
     */
    public static double[] db2linear(double[] dbEnergies)
    {
        return exp10(divide(dbEnergies, 10));
    }

    /**
     * Db2amplitude.
     *
     * @param dbAmplitude the db amplitude
     * @return the float
     */
    public static float db2amplitude(float dbAmplitude)
    {
        if (Float.isNaN(dbAmplitude)) return 0.0f;
        else return (float)(Math.pow(10.0, dbAmplitude/20));
    }

    /**
     * Db2amplitude.
     *
     * @param dbAmplitude the db amplitude
     * @return the double
     */
    public static double db2amplitude(double dbAmplitude)
    {
        if (Double.isNaN(dbAmplitude)) return 0.;
        else return Math.pow(10.0, dbAmplitude/20);
    }

    /**
     * Radian2degrees.
     *
     * @param rad the rad
     * @return the float
     */
    public static float radian2degrees(float rad)
    {
        return (float)((rad/MathUtils.TWOPI)*360.0f);
    }

    /**
     * Radian2degrees.
     *
     * @param rad the rad
     * @return the double
     */
    public static double radian2degrees(double rad)
    {
        return (rad/MathUtils.TWOPI)*360.0;
    }

    /**
     * Build the sum of the squared difference of all elements 
     * with the same index numbers in the arrays.
     *
     * @param a the a
     * @param b the b
     * @return the double
     */
    public static double sumSquaredError(double[] a, double[] b)
    {
        if (a.length != b.length) {
            throw new IllegalArgumentException("Arrays must be equal length");
        }
        double sum = 0;
        for (int i=0; iminimumValue)
                c[i] = Math.log(a[i]);
            else
                c[i] = fixedValue;
        }
        return c;
    }

    /**
     * Log10.
     *
     * @param a the a
     * @return the double[]
     */
    public static double[] log10(double[] a)
    {
        double[] c = new double[a.length];
        for (int i=0; i0)
            {
                real = new double[len];
                imag = new double[len];

                Arrays.fill(real, 0.0);
                Arrays.fill(imag, 0.0);
            }
            else
            {
                real = null;
                imag = null;
            }
        }
    }

    /* Performs interpolation to increase or decrease the size of array x
       to newLength*/
    /**
     * Interpolate.
     *
     * @param x the x
     * @param newLength the new length
     * @return the double[]
     */
    public static double [] interpolate(double [] x, int newLength)
    {
        double [] y = null;
        if (newLength>0)
        {
            int N = x.length;
            if (N==1)
            {
                y = new double[1];
                y[0]=x[0];
                return y;
            }
            else if (newLength==1)
            {
                y = new double[1];
                int ind = (int)Math.floor(N*0.5+0.5);
                ind = Math.max(1, ind);
                ind = Math.min(ind, N);
                y[0]= x[ind-1];
                return y;
            }
            else
            {
                y = new double[newLength];
                double Beta = ((double)newLength)/N;
                double newBeta = 1.0;

                if (newLength>2)
                    newBeta=(N-2.0)/(newLength-2.0);

                y[0] = x[0];
                y[1] = x[1];
                y[newLength-1] = x[N-1];

                double tmp, alpha;
                int i, j;
                for (i=2; i<=newLength-2; i++) 
                {
                    tmp = 1.0+(i-1)*newBeta;
                    j = (int)Math.floor(tmp);
                    alpha = tmp-j;
                    y[i] = (1.0-alpha)*x[Math.max(0,j)] + alpha*x[Math.min(N-1,j+1)];
                }
            }
        }

        return y;
    }

    /**
     * Gets the max.
     *
     * @param x the x
     * @return the max
     */
    public static int getMax(int [] x)
    {
        int maxx = x[0];
        for (int i=1; imaxx)
                maxx = x[i];
        }

        return maxx;
    }

    /**
     * Gets the min index.
     *
     * @param x the x
     * @return the min index
     */
    public static int getMinIndex(int [] x)
    {
        return getMinIndex(x, 0);
    }

    /**
     * Gets the min index.
     *
     * @param x the x
     * @param startInd the start ind
     * @return the min index
     */
    public static int getMinIndex(int [] x, int startInd)
    {
        return getMinIndex(x, startInd, x.length-1);
    }

    /**
     * Gets the min index.
     *
     * @param x the x
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the min index
     */
    public static int getMinIndex(int [] x, int startInd, int endInd)
    {
        return getExtremaIndex(x, false, startInd, endInd);
    }

    /**
     * Gets the max index.
     *
     * @param x the x
     * @return the max index
     */
    public static int getMaxIndex(int [] x)
    {
        return getMaxIndex(x, 0);
    }

    /**
     * Gets the max index.
     *
     * @param x the x
     * @param startInd the start ind
     * @return the max index
     */
    public static int getMaxIndex(int [] x, int startInd)
    {
        return getMaxIndex(x, startInd, x.length-1);
    }

    /**
     * Gets the max index.
     *
     * @param x the x
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the max index
     */
    public static int getMaxIndex(int [] x, int startInd, int endInd)
    {
        return getExtremaIndex(x, true, startInd, endInd);
    }

    /**
     * Gets the extrema index.
     *
     * @param x the x
     * @param isMax the is max
     * @return the extrema index
     */
    public static int getExtremaIndex(int [] x, boolean isMax)
    {
        return getExtremaIndex(x, isMax, 0);
    }

    /**
     * Gets the extrema index.
     *
     * @param x the x
     * @param isMax the is max
     * @param startInd the start ind
     * @return the extrema index
     */
    public static int getExtremaIndex(int [] x, boolean isMax, int startInd)
    {
        return getExtremaIndex(x, isMax, startInd, x.length-1);
    }

    /**
     * Gets the extrema index.
     *
     * @param x the x
     * @param isMax the is max
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the extrema index
     */
    public static int getExtremaIndex(int [] x, boolean isMax, int startInd, int endInd)
    {
        int extrema = x[0];
        int extremaInd = 0;
        if (startInd<0)
            startInd=0;
        if (endInd>x.length-1)
            endInd = x.length-1;
        if (startInd>endInd)
            startInd=endInd;

        if (isMax)
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]>extrema)
                {
                    extrema = x[i];
                    extremaInd = i;
                }
            }
        }
        else
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]x.length-1)
            endInd = x.length-1;
        if (startInd>endInd)
            startInd=endInd;

        if (isMax)
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]>extrema)
                {
                    extrema = x[i];
                    extremaInd = i;
                }
            }
        }
        else
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]x.length-1)
            endInd = x.length-1;
        if (startInd>endInd)
            startInd=endInd;

        if (isMax)
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]>extrema)
                {
                    extrema = x[i];
                    extremaInd = i;
                }
            }
        }
        else
        {
            for (int i=startInd; i<=endInd; i++)
            {
                if (x[i]maxx)
                maxx = x[i];
        }

        return maxx;
    }

    /**
     * Gets the max.
     *
     * @param x the x
     * @return the max
     */
    public static float getMax(float [] x)
    {
        float maxx = x[0];
        for (int i=1; imaxx)
                maxx = x[i];
        }

        return maxx;
    }

    /**
     * Gets the min.
     *
     * @param x the x
     * @return the min
     */
    public static int getMin(int [] x)
    {
        int minn = x[0];
        for (int i=1; imaxx)
                maxx = Math.abs(x[i]);
        }

        return maxx;
    }

    //Return the local peak index for values x[startInd],x[startInd+1],...,x[endInd]
                                                                             // Note that the returned index is in the range [startInd,endInd]
                                                                                                                              // If there is no local peak, -1 is returned. This means that the peak is either at [startInd] or [endInd].
    // However, it is the responsibility of the calling function to further check this situation as the returned index
    // will be -1 in both cases
    /**
     * Gets the abs max ind.
     *
     * @param x the x
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the abs max ind
     */
    public static int getAbsMaxInd(double [] x, int startInd, int endInd)
    {
        int index = -1;
        double max = x[startInd];

        for (int i=startInd+1; imax && x[i]>x[i-1] && x[i]>x[i+1])
            {
                max = x[i];
                index = i;
            }
        }

        return index;
    }

    //Return an array where each entry is set to val
    /**
     * Filled array.
     *
     * @param val the val
     * @param len the len
     * @return the double[]
     */
    public static double [] filledArray(double val, int len)
    {
        double [] x = null;

        if (len>0)
        {
            x = new double[len];
            for (int i=0; i0)
        {
            x = new int[len];
            for (int i=0; i0)
            {
                indices = new int[total];
                int count = 0;
                for (i=0; i=total)
                        break;
                }
            }
        }
        
        return indices;
    }
    
    //Returns the indices that satisfy both comparator1, val1 or comparator2, val2
    /**
     * Find or.
     *
     * @param x the x
     * @param comparator1 the comparator1
     * @param val1 the val1
     * @param comparator2 the comparator2
     * @param val2 the val2
     * @return the int[]
     */
    public static int [] findOr(double[] x, int comparator1, double val1, int comparator2, double val2)
    {
        int[] indices = null;
        int[] indices1 = find(x, comparator1, val1);
        int[] indices2 = find(x, comparator2, val2);
        
        if (indices1!=null || indices2!=null)
        {
            int total = 0;
            if (indices1!=null)
                total+=indices1.length;
            if (indices2!=null)
                total+=indices2.length;
            int[] tmpIndices = new int[total];
            int currentPos = 0;
            if (indices1!=null)
            {
                System.arraycopy(indices1, 0, tmpIndices, 0, indices1.length);
                currentPos = indices1.length;
            }
            if (indices2!=null)
                System.arraycopy(indices2, 0, tmpIndices, currentPos, indices2.length);
            
            indices = StringUtils.getDifferentItemsList(tmpIndices);
        }
        
        return indices;
    }
    
    //Returns the indices satisying the condition specificed by the comparator and val
    /**
     * Find.
     *
     * @param x the x
     * @param comparator the comparator
     * @param val the val
     * @return the int[]
     */
    public static int [] find(double[] x, int comparator, double val)
    {
        int [] inds = null;
        int totalFound = 0;

        switch (comparator)
        {
        case EQUALS:
            for (int i=0; ival)
                    totalFound++;
            }
            break;
        case GREATER_THAN_OR_EQUALS:
            for (int i=0; i=val)
                    totalFound++;
            }
            break;
        case LESS_THAN:
            for (int i=0; i0)
        {
            int currentInd = 0;
            inds = new int[totalFound];

            switch (comparator)
            {
            case EQUALS:
                for (int i=0; ival)
                    {
                        inds[currentInd++] = i;
                        totalFound++;
                    }
                }
                break;
            case GREATER_THAN_OR_EQUALS:
                for (int i=0; i=val)
                    {
                        inds[currentInd++] = i;
                        totalFound++;
                    }
                }
                break;
            case LESS_THAN:
                for (int i=0; i=x[j] && xi[i]maxVal)
            ret = maxVal;

        return ret;
    }

    /**
     * Check limits.
     *
     * @param val the val
     * @param minVal the min val
     * @param maxVal the max val
     * @return the double
     */
    public static double CheckLimits(double val, double minVal, double maxVal)
    {
        double ret = val;

        if (retmaxVal)
            ret = maxVal;

        return ret;
    }

    /**
     * Check limits.
     *
     * @param val the val
     * @param minVal the min val
     * @param maxVal the max val
     * @return the float
     */
    public static float CheckLimits(float val, float minVal, float maxVal)
    {
        float ret = val;

        if (retmaxVal)
            ret = maxVal;

        return ret;
    }

    //Find the extremum points that are larger/smaller than numLefNs and numRightNs neighbours and larger/smaller than the given th value
    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftN the num left n
     * @param numRightN the num right n
     * @param isMaxima the is maxima
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int numLeftN, int numRightN, boolean isMaxima)
    {
        return getExtrema(x, numLeftN, numRightN, isMaxima, 0); 
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftN the num left n
     * @param numRightN the num right n
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int numLeftN, int numRightN, boolean isMaxima, int startInd)
    {
        return getExtrema(x, numLeftN, numRightN, isMaxima, startInd, x.length-1);
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftN the num left n
     * @param numRightN the num right n
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int numLeftN, int numRightN, boolean isMaxima, int startInd, int endInd)
    {
        double th;

        if (isMaxima)
            th = MathUtils.getMin(x)-1.0;
        else
            th = MathUtils.getMax(x)+1.0;

        return getExtrema(x, numLeftN, numRightN, isMaxima, startInd, endInd, th);
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftN the num left n
     * @param numRightN the num right n
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @param endInd the end ind
     * @param th the th
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int numLeftN, int numRightN, boolean isMaxima, int startInd, int endInd, double th)
    {
        int [] numLeftNs = new int[x.length];
        int [] numRightNs = new int[x.length];
        Arrays.fill(numLeftNs, numLeftN);
        Arrays.fill(numRightNs, numRightN);

        return getExtrema(x, numLeftNs, numRightNs, isMaxima, startInd, endInd, th); 
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftNs the num left ns
     * @param numRightNs the num right ns
     * @param isMaxima the is maxima
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int [] numLeftNs, int [] numRightNs, boolean isMaxima)
    { 
        return getExtrema(x, numLeftNs, numRightNs, isMaxima, 0);
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftNs the num left ns
     * @param numRightNs the num right ns
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int [] numLeftNs, int [] numRightNs, boolean isMaxima, int startInd)
    {
        return getExtrema(x, numLeftNs, numRightNs, isMaxima, startInd, x.length-1);
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftNs the num left ns
     * @param numRightNs the num right ns
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @param endInd the end ind
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int [] numLeftNs, int [] numRightNs, boolean isMaxima, int startInd, int endInd)
    {   
        double th;

        if (isMaxima)
            th = MathUtils.getMin(x)-1.0;
        else
            th = MathUtils.getMax(x)+1.0;

        return getExtrema(x, numLeftNs, numRightNs, isMaxima, startInd, endInd, th);
    }

    /**
     * Gets the extrema.
     *
     * @param x the x
     * @param numLeftNs the num left ns
     * @param numRightNs the num right ns
     * @param isMaxima the is maxima
     * @param startInd the start ind
     * @param endInd the end ind
     * @param th the th
     * @return the extrema
     */
    public static int [] getExtrema(double [] x, int [] numLeftNs, int [] numRightNs, boolean isMaxima, int startInd, int endInd, double th)
    {
        int [] tmpInds = new int[x.length];
        int [] inds = null;
        int total = 0;

        int i, j;
        boolean bExtremum;

        if (startInd<0)
            startInd=0;
        if (endInd>x.length-1)
            endInd=x.length-1;
        if (startInd>endInd)
            startInd=endInd;

        if (isMaxima) //Search for maxima
        {
            for (i=startInd; i<=endInd; i++)
            {
                if (x[i]>th)
                {    
                    bExtremum = true;

                    if (i-numLeftNs[i]>=0)
                    {
                        for (j=i-numLeftNs[i]; j=0)
                    {
                        for (j=i-numLeftNs[i]; jx[j])
                            {
                                bExtremum = false;
                                break;
                            }
                        }

                        if (bExtremum)
                        {
                            if (i+numRightNs[i]x[j])
                                    {
                                        bExtremum = false;
                                        break;
                                    }
                                }
                            }
                            else
                                bExtremum = false;
                        }
                    }
                    else
                        bExtremum = false;
                }
                else
                    bExtremum = false;

                if (bExtremum)
                    tmpInds[total++] = i;
            }
        }  

        if (total>0)
        {
            inds = new int[total];
            System.arraycopy(tmpInds, 0, inds, 0, total);
        }

        return inds; 
    }

    //Returns an array of values selected randomly in the interval [0.0,1.0)
    /**
     * Gets the randoms.
     *
     * @param len the len
     * @return the randoms
     */
    public static double [] getRandoms(int len)
    {
        return getRandoms(len, 0.0, 1.0);
    }

    //Returns an array of values selected randomly in the interval minVal and maxVal
    /**
     * Gets the randoms.
     *
     * @param len the len
     * @param minVal the min val
     * @param maxVal the max val
     * @return the randoms
     */
    public static double [] getRandoms(int len, double minVal, double maxVal)
    {
        double [] x = null;

        if (len>0)
        {
            x = new double[len];
            if (minVal>maxVal)
            {
                double tmp = minVal;
                minVal = maxVal;
                maxVal = tmp;
            }

            for (int i=0; i0)
        {
            float minDiff = Math.abs(x[0]-val);
            float tmpDiff;
            ind = 0;

            for (int i=1; i0)
        {
            int minDiff = Math.abs(x[0]-val);
            int tmpDiff;
            ind = 0;

            for (int i=1; i0.5*TWOPI)
        {
            if (unwrappedPhaseInRadians>prevPhaseInRadians)
                unwrappedPhaseInRadians -= TWOPI;
            else
                unwrappedPhaseInRadians += TWOPI;
        }

        return unwrappedPhaseInRadians;
    }

    //Unwarps phaseInDegrees to range [lowestDegree, lowestDegree+360.0)
    /**
     * Unwrap to range.
     *
     * @param phaseInDegrees the phase in degrees
     * @param lowestDegree the lowest degree
     * @return the float
     */
    public static float unwrapToRange(float phaseInDegrees, float lowestDegree)
    {
        float retVal = phaseInDegrees;
        if (retVal=lowestDegree+360.0f)
        {
            while (retVal>=lowestDegree+360.0f)
                retVal -= 360.0f;
        }

        return retVal;
    }

    /**
     * Db2neper.
     *
     * @param db the db
     * @return the double
     */
    public static double db2neper(double db)
    {
        return 20.0*db/Math.log(10.0);
    }

    /**
     * Db2neper.
     *
     * @param dbs the dbs
     * @return the double[]
     */
    public static double [] db2neper(double [] dbs)
    {
        double [] nepers = null;

        if (dbs!=null && dbs.length>0)
        {
            nepers = new double[dbs.length];

            for (int i=0; i0)
        {
            dbs = new double[nepers.length];

            for (int i=0; i0)
        {
            lins = new double[nepers.length];

            for (int i=0; i0)
        {
            y = new float[x.length];
            for (int i=0; i0)
        {
            y = new float[x.length];
            for (int i=0; i0)
        {
            y = new double[x.length];
            for (int i=0; i v = new Vector();
        for (int i=0; i0)
                totalPaths *= totalItemsInNodes[i];
        }

        int [][] pathInds = new int[totalPaths][totalItemsInNodes.length];
        int [] currentPath = new int[totalItemsInNodes.length];

        int count = 0;

        Arrays.fill(currentPath, 0);
        System.arraycopy(currentPath, 0, pathInds[count++], 0, currentPath.length);

        while (count=0; i--)
            {
                if (currentPath[i]+1x.length-1)
            startIndex=x.length-1;
        if (endIndexx.length-1)
            endIndex=x.length-1;

        int[] indices = new int[endIndex-startIndex+1];
        double[] x2 = new double[endIndex-startIndex+1];
        int i;

        for (i=startIndex; i<=endIndex; i++)
        {
            indices[i-startIndex] = i;
            x2[i-startIndex] = x[i];
        }

        quickSort(x2, indices);

        for (i=startIndex; i<=endIndex; i++)
            x[i] = x2[i-startIndex];

        return indices;
    }


    //Sorts x, y is also sorted as x so it can be used to obtain sorted indices
    //Sorting is from lowest to highest
    /**
     * Quick sort.
     *
     * @param x the x
     * @param y the y
     */
    public static void quickSort(double[] x, int[] y)
    {
        assert x.length==y.length;

        quickSort(x, y, 0, x.length-1);
    }

    //Sorting is from lowest to highest
    /**
     * Quick sort.
     *
     * @param x the x
     * @param y the y
     * @param startIndex the start index
     * @param endIndex the end index
     */
    public static void quickSort(double[] x, int[] y, int startIndex, int endIndex)
    {   
        if(startIndexpivot);

            if(i>=j) 
                break;

            t = x[i]; 
            ty = y[i];

            x[i] = x[j];
            y[i] = y[j];

            x[j] = t;
            y[j] = ty;
        }

        t = x[startIndex]; 
        ty = y[startIndex];

        x[startIndex] = x[j]; 
        y[startIndex] = y[j];

        x[j] = t;
        y[j] = ty;

        return j;
    }

    /**
     * Normalize to sum up to.
     *
     * @param x the x
     * @param sumUp the sum up
     * @return the double[]
     */
    public static double[] normalizeToSumUpTo(double[] x, double sumUp)
    {
        return normalizeToSumUpTo(x, x.length, sumUp);
    }

    /**
     * Normalize to sum up to.
     *
     * @param x the x
     * @param len the len
     * @param sumUp the sum up
     * @return the double[]
     */
    public static double[] normalizeToSumUpTo(double[] x, int len, double sumUp)
    {
        if (len>x.length)
            len=x.length;

        double[] y = new double[len];

        double total = 0.0;
        int i;

        for (i=0; i0.0)
        {
            for (i=0; ix.length)
            len=x.length;

        double[] y = new double[len];

        double xmin = MathUtils.min(x);
        double xmax = MathUtils.max(x);
        int i;

        if (xmax>xmin)
        {
            for (i=0; ix.length-1)
            index=x.length-1;

        return x[index];
    }

    //Returns 1/N sum_i=0^N-1(|x[i]|)
    /**
     * Abs mean.
     *
     * @param x the x
     * @return the double
     */
    public static double absMean(double[] x)
    {
        double m = 0.0;

        for (int i=0; ii) 
                        temp[j-1][k-1] = matrix[j][k];
                }
            }

            result += matrix[0][i]*Math.pow(-1,(double)i)*determinant(temp); 
        }

        return result;
    } 

    /**
     * Random.
     *
     * @param numSamples the num samples
     * @return the double[]
     */
    public static double[] random(int numSamples)
    {
        double[] x = null;

        if (numSamples>0)
        {
            x = new double[numSamples];
            for (int i=0; i big) 
                    big=temp;
            if (big == 0.0) 
                System.out.println("Singular matrix in routine ludcmp");
            vv[i-1]=1.0/big;
        }
        
        for (j=1;j<=n;j++) 
        {
            for (i=1;i= big) 
                {
                    big=dum;
                    imax=i;
                }
            }
            
            if (j != imax) 
            {
                for (k=1;k<=n;k++) 
                {
                    dum=a[imax-1][k-1];
                    a[imax-1][k-1]=a[j-1][k-1];
                    a[j-1][k-1]=dum;
                }
                d[0] = -d[0];
                vv[imax-1]=vv[j-1];
            }
            indx[j-1]=imax;
            if (a[j-1][j-1] == 0.0) 
                a[j-1][j-1]=TINY;
            if (j != n) 
            {
                dum=1.0/(a[j-1][j-1]);
                for (i=j+1;i<=n;i++) 
                    a[i-1][j-1] *= dum;
            }
        }
    }
    
    /**
     * Lu substitute.
     *
     * @param a the a
     * @param indx the indx
     * @param b the b
     */
    public static void luSubstitute(double[][] a, int[] indx, double b[])
    {
        int n = a.length;
        int i=0;
        int ii=0;
        int ip,j;
        double sum;

        for (i=1;i<=n;i++) 
        {
            ip=indx[i-1];
            sum=b[ip-1];
            b[ip-1]=b[i-1];
            if (ii!=0)
            {
                for (j=ii;j<=i-1;j++) 
                    sum -= a[i-1][j-1]*b[j-1];
            }
            else if (sum!=0.0) 
                ii=i;
            b[i-1]=sum;
        }
        for (i=n;i>=1;i--) 
        {
            sum=b[i-1];
            for (j=i+1;j<=n;j++) 
                sum -= a[i-1][j-1]*b[j-1];
            
            b[i-1]=sum/a[i-1][i-1];
        }
    }
    //
    
    /**
     * Log add.
     *
     * @param x the x
     * @param y the y
     * @return the double
     */
    public static double logAdd(double x, double y) 
    {
        if (y > x) 
        {
            double temp = x;
            x = y;
            y = temp;
        }

        if (x==Double.NEGATIVE_INFINITY)
            return x;

        double negDiff = y - x;
        if (negDiff < -20)
            return x;

        return x + Math.log(1.0 + Math.exp(negDiff));
    }
    
    //Returns the index of largest element in x which is smaller than val
    //x should be sorted in increasing order to get a meaningful result
    /**
     * Gets the largest index smaller than.
     *
     * @param x the x
     * @param val the val
     * @return the largest index smaller than
     */
    public static int getLargestIndexSmallerThan(double[] x, double val)
    {
        int index = -1;
        
        if (x!=null)
        {
            for (int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy