/*
* Roby Joehanes
*
* Copyright 2007 Roby Joehanes
* This file is distributed under the GNU General Public License version 3.0.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package jdistlib.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import jdistlib.rng.MersenneTwister;
import jdistlib.rng.RandomEngine;
/**
* Utility functions to mimic R
* @author Roby Joehanes
*
*/
public class Utilities {
public enum RankTies { AVERAGE, MAX, MIN }
public static final int[] colon(int from, int to) {
int n = Math.abs(to - from) + 1;
int[] d = new int[n];
int inc = to > from ? 1 : -1;
for (int i = 0 ; i < n; i++)
d[i] = from + i*inc;
return d;
}
public static final double[] colon(double from, double to) {
int n = (int) (Math.abs(to - from) + 1);
double[] d = new double[n];
int inc = to > from ? 1 : -1;
for (int i = 0 ; i < n; i++)
d[i] = from + i*inc;
return d;
}
public static final int[] seq(int from, int to, int by) {
int n = (to - from) / by + 1;
int[] d = new int[n];
for (int i = 0 ; i < n; i++)
d[i] = from + i * by;
return d;
}
public static final double[] seq_int(double from, double to, int length_out) {
double[] d = new double[length_out];
double delta = (to - from) / (length_out - 1.0);
for (int i = 0 ; i < length_out; i++)
d[i] = from + i * delta;
return d;
}
public static final double[] seq(double from, double to, double by) {
int n = (int) Math.ceil((to - from + 1e-15) / by);
double[] d = new double[n];
for (int i = 0 ; i < n; i++)
d[i] = from + i * by;
return d;
}
public static final int[] c(int[]... x) {
int n = 0;
for (int i = 0; i < x.length; i++)
n += x[i].length;
int[] v = new int[n];
int w = 0;
for (int i = 0; i < x.length; i++) {
System.arraycopy(x[i], 0, v, w, x[i].length);
w += x[i].length;
}
return v;
}
public static final int[] c(int... x) {
return x;
}
public static final double[] c(double[]... x) {
int n = 0;
for (int i = 0; i < x.length; i++)
n += x[i].length;
double[] v = new double[n];
int w = 0;
for (int i = 0; i < x.length; i++) {
System.arraycopy(x[i], 0, v, w, x[i].length);
w += x[i].length;
}
return v;
}
public static final double[] c(double... x) {
return x;
}
public static final double[] rep(double v, int n) {
double[] r = new double[n];
Arrays.fill(r, v);
return r;
}
public static final double[] rep(double[] v, int n) {
double[] r = new double[n * v.length];
for (int i = 0; i < n; i++)
System.arraycopy(v, 0, r, i * n, v.length);
return r;
}
public static final double[] rep_each(double[] v, int n) {
int vn = v.length;
double[] r = new double[vn * n];
for (int i = 0; i < vn; i++) {
double vi = v[i];
for (int j = 0; j < n; j++)
r[i*n + j] = vi;
}
return r;
}
public static final int[] rep_each(int[] v, int n) {
int vn = v.length;
int[] r = new int[vn * n];
for (int i = 0; i < vn; i++) {
int vi = v[i];
for (int j = 0; j < n; j++)
r[i*n + j] = vi;
}
return r;
}
public static final double[] rec(double[] e) {
double[] v = new double[e.length];
for (int i = 0; i < e.length; i++)
v[i] = 1.0/e[i];
return v;
}
public static final double[] rev(double[] e) {
double[] v = new double[e.length];
for (int i = 0; i < e.length; i++)
v[e.length - i - 1] = e[i];
return v;
}
public static final void print(double... val) {
print(" %g", val);
}
public static final void print(String format, double... val) {
int n = val.length;
for (int i = 0; i < n; i++) {
System.out.print(String.format(format, val[i]));
if ((i + 1) % 6 == 0) System.out.println();
}
System.out.println();
}
/**
* Sort data using radix sort
* @param data
*/
public static final void sort(double[] data) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long[]
a = new long[n],
b = new long[n];
for (int i = 0; i < n; i++)
a[i] = Double.doubleToLongBits(data[i]);
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
}
long[] temp = b; b = a; a = temp;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--)
data[numNegs++] = Double.longBitsToDouble(a[i]);
if (numNegs > 0)
for (int i = numNegs; i < n; i++)
data[i] = Double.longBitsToDouble(a[i - numNegs]);
else
for (int i = 0; i < n; i++)
data[i] = Double.longBitsToDouble(a[i]);
}
/**
* Sort using radix sort
* @param data
* @param idx an index of data, of the same length, useful to sort an entire table
*/
public static final void sort(double[] data, int[] idx) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long[]
a = new long[n],
b = new long[n];
int[]
idx_a = new int[n],
idx_b = new int[n];
for (int i = 0; i < n; i++) {
a[i] = Double.doubleToLongBits(data[i]);
idx_a[i] = idx[i];
}
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
long[] temp = b; b = a; a = temp;
int[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = Double.longBitsToDouble(a[i]);
idx[numNegs++] = idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = Double.longBitsToDouble(a[i - numNegs]);
idx[i] = idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = Double.longBitsToDouble(a[i]);
idx[i] = idx_a[i];
}
}
/**
* Sort using radix sort
* @param data
* @param obj an auxiliary array of objects
*/
@SuppressWarnings("unchecked")
public static final void sort(double[] data, T[] obj) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long[]
a = new long[n],
b = new long[n];
Object[]
idx_a = new Object[n],
idx_b = new Object[n];
for (int i = 0; i < n; i++) {
a[i] = Double.doubleToLongBits(data[i]);
idx_a[i] = obj[i];
}
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
long[] temp = b; b = a; a = temp;
Object[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = Double.longBitsToDouble(a[i]);
obj[numNegs++] = (T) idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = Double.longBitsToDouble(a[i - numNegs]);
obj[i] = (T) idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = Double.longBitsToDouble(a[i]);
obj[i] = (T) idx_a[i];
}
}
/**
* Radix sort
* @param a
*/
public static final void sort(int[] a) {
int
n = a.length,
// Roby's modification: Optimum number of bins
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2))))),
b[] = new int[n],
b_orig[] = b;
for (int mask = ~(-1 << numBins), rshift = 0; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(a[p] & mask) >>> rshift]; // RJ's fix to handle negatives
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (a[p] & mask) >>> rshift; // RJ's fix to handle negatives
--cntarray[key];
b[cntarray[key]] = a[p];
}
int[] temp = b; b = a; a = temp;
}
if (a == b_orig)
System.arraycopy(a, 0, b, 0, n);
int numNegs = 0;
// Negatives are always placed at the end of the array in the correct order.
// So, scan to find the point
for (int i = n - 1; a[i] < 0 && i > 0; i--, numNegs++) ;
if (numNegs > 0) {
System.arraycopy(a, n - numNegs, b, 0, numNegs);
System.arraycopy(a, 0, a, numNegs, n - numNegs);
System.arraycopy(b, 0, a, 0, numNegs);
}
}
public static final void sort(int[] data, int[] idx) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
int[]
a = new int[n],
b = new int[n];
int[]
idx_a = new int[n],
idx_b = new int[n];
for (int i = 0; i < n; i++) {
a[i] = data[i];
idx_a[i] = idx[i];
}
for (int mask = ~(-1 << numBins), rshift = 0; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
int[] temp = b; b = a; a = temp;
int[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = a[i];
idx[numNegs++] = idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = a[i - numNegs];
idx[i] = idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = a[i];
idx[i] = idx_a[i];
}
}
@SuppressWarnings("unchecked")
public static final void sort(int[] data, T[] idx) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
int[]
a = new int[n],
b = new int[n];
Object[]
idx_a = new Object[n],
idx_b = new Object[n];
for (int i = 0; i < n; i++) {
a[i] = data[i];
idx_a[i] = idx[i];
}
for (int mask = ~(-1 << numBins), rshift = 0; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
int[] temp = b; b = a; a = temp;
Object[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = a[i];
idx[numNegs++] = (T) idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = a[i - numNegs];
idx[i] = (T) idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = a[i];
idx[i] = (T) idx_a[i];
}
}
/**
* Radix sort
* @param a
*/
public static final void sort(long[] a) {
int
n = a.length,
// Roby's modification: Optimum number of bins
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long
b[] = new long[n],
b_orig[] = b;
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)]; // RJ's fix to handle negatives
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift); // RJ's fix to handle negatives
--cntarray[key];
b[cntarray[key]] = a[p];
}
long[] temp = b; b = a; a = temp;
}
if (a == b_orig)
System.arraycopy(a, 0, b, 0, n);
int numNegs = 0;
// Negatives are always placed at the end of the array in the correct order.
// So, scan to find the point
for (int i = n - 1; a[i] < 0 && i > 0; i--, numNegs++) ;
if (numNegs > 0) {
System.arraycopy(a, n - numNegs, b, 0, numNegs);
System.arraycopy(a, 0, a, numNegs, n - numNegs);
System.arraycopy(b, 0, a, 0, numNegs);
}
}
public static final void sort(long[] data, int[] idx) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long[]
a = new long[n],
b = new long[n];
int[]
idx_a = new int[n],
idx_b = new int[n];
for (int i = 0; i < n; i++) {
a[i] = data[i];
idx_a[i] = idx[i];
}
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
long[] temp = b; b = a; a = temp;
int[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = a[i];
idx[numNegs++] = idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = a[i - numNegs];
idx[i] = idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = a[i];
idx[i] = idx_a[i];
}
}
@SuppressWarnings("unchecked")
public static final void sort(long[] data, T[] idx) {
// N=5*10^8: Radix = 9919, Quick = 16971 (ms).
int
n = data.length,
numBins = (int) Math.max(4,Math.min(10, Math.round(Math.log(n) / (2 * Math.log(2)))));
long[]
a = new long[n],
b = new long[n];
Object[]
idx_a = new Object[n],
idx_b = new Object[n];
for (int i = 0; i < n; i++) {
a[i] = data[i];
idx_a[i] = idx[i];
}
for (long mask = ~(-1L << numBins), rshift = 0L; mask != 0; mask <<= numBins, rshift += numBins) {
int[] cntarray = new int[1 << numBins];
for (int p = 0; p < n; ++p)
++cntarray[(int) ((a[p] & mask) >>> rshift)];
for (int i = 1; i < cntarray.length; ++i)
cntarray[i] += cntarray[i-1];
for (int p = n-1; p >= 0; --p) {
int key = (int) ((a[p] & mask) >>> rshift);
--cntarray[key];
b[cntarray[key]] = a[p];
idx_b[cntarray[key]] = idx_a[p];
}
long[] temp = b; b = a; a = temp;
Object[] temp_idx = idx_b; idx_b = idx_a; idx_a = temp_idx;
}
int numNegs = 0;
// Negatives are always placed at the end of the array in the reverse order.
// So, scan to find the point
if (a[n - 1] < 0)
for (int i = n - 1; a[i] < 0 && i > 0; i--) {
data[numNegs] = a[i];
idx[numNegs++] = (T) idx_a[i];
}
if (numNegs > 0)
for (int i = numNegs; i < n; i++) {
data[i] = a[i - numNegs];
idx[i] = (T) idx_a[i - numNegs];
}
else
for (int i = 0; i < n; i++) {
data[i] = a[i];
idx[i] = (T) idx_a[i];
}
}
/**
* Converts the integer array e into a double array
* @param e
* @return a double array
*/
public static final double[] to_double(int[] e) {
int n = e.length;
double[] r = new double[n];
for (int i = 0; i < n; i++)
r[i] = e[i];
return r;
}
/**
* Returns the order of the elements of array e
* @param e
*/
public static final int[] order(double[] e) {
int n = e.length;
int[] order = new int[n];
double[] v = new double[n];
System.arraycopy(e, 0, v, 0, n);
for (int i = 0; i < n; i++)
order[i] = i;
sort(v, order);
return order;
}
/**
* Returns the ranks of the elements of array e, resolve ties by averaging
* @param e
*/
public static final double[] rank(double[] e) {
return rank(e, RankTies.AVERAGE);
}
/**
* Returns the ranks of the elements of array e.
* @param e
* @param ties Ties resolution: Average, Min, or Max
* @return NOTE: Rank is index 1-based!
*/
public static final double[] rank(double[] e, RankTies ties) {
int n = e.length;
int[] order = new int[n];
double[] rank = new double[n];
double[] v = new double[n];
System.arraycopy(e, 0, v, 0, n);
for (int i = 0; i < n; i++)
order[i] = i;
sort(v, order);
int j;
for (int i = 0; i < n; i = j+1) {
j = i;
while ((j < n - 1) && (v[j] == v[j+1])) j++;
switch (ties) {
case AVERAGE:
double avg = (i + j) / 2.;
for (int k = i; k <= j; k++)
rank[order[k]] = avg + 1;
break;
case MAX:
for (int k = i; k <= j; k++)
rank[order[k]] = j + 1;
break;
case MIN:
for (int k = i; k <= j; k++)
rank[order[k]] = i + 1;
break;
}
}
return rank;
}
/**
* Permute the array e
* @param e
*/
public static final void permute(double[] e) {
permute(e, new MersenneTwister());
}
/**
* Permute the array e
* @param e
* @param random
*/
public static final void permute(double[] e, RandomEngine random) {
int n = e.length;
for (int i = 0; i < n; i++) {
int
i1 = random.nextInt(n),
i2 = random.nextInt(n);
double t = e[i1]; e[i1] = e[i2]; e[i2] = t;
}
}
/**
* Sample from 1 to n, with size s, without replacement---with default random engine
* @param n
* @param s
* @return a sampled array of size s
*/
public static final double[] sample_int(int n, int s) {
return sample_int(n, s, new MersenneTwister());
}
/**
* Sample from 1 to n, with size s, without replacement
* @param n
* @param s
* @param random random engine
* @return a sampled array of size s
*/
public static final double[] sample_int(int n, int s, RandomEngine random) {
// This code might be subpar in performance, but it works for me.
double[] rand = new double[s];
Set set = new HashSet();
for (int i = 0; i < s; i++) {
do {
int j = (int) (Math.floor(random.random() * n) + 1);
if (!set.contains(j)) {
set.add(j);
rand[i] = j;
break;
}
} while (true);
}
return rand;
}
public static final double[] unique(double[] e) {
LinkedHashSet set = new LinkedHashSet(e.length);
for (double _e : e)
set.add(_e);
int n = set.size(), i = 0;
double[] r = new double[n];
for (double _e: set)
r[i++] = _e;
return r;
}
@SuppressWarnings("unchecked")
public static final S[] unique(S[] e) {
LinkedHashSet set = new LinkedHashSet(e.length);
for (S _e : e)
set.add(_e);
return (S[]) set.toArray();
}
public static final boolean[] is_duplicated(double[] e) {
LinkedHashSet set = new LinkedHashSet(e.length);
int n = e.length, i = 0;
boolean[] r = new boolean[n];
for (double _e : e) {
r[i++] = set.contains(_e);
set.add(_e);
}
return r;
}
public static final boolean[] is_duplicated(S[] e) {
LinkedHashSet set = new LinkedHashSet(e.length);
int n = e.length, i = 0;
boolean[] r = new boolean[n];
for (S _e : e) {
r[i++] = set.contains(_e);
set.add(_e);
}
return r;
}
public static final int[] which(boolean[] e) {
int n = e.length, n_true = 0, j = 0;
for (boolean _e : e)
if (_e) n_true++;
int[] idx = new int[n_true];
for (int i = 0; i < n; i++)
if (e[i])
idx[j++] = i;
return idx;
}
/**
* Compute RLE
* @param e
* @return Double dimension array of 2 x e.length. The first contains the values. The second contains the lengths.
*/
public static final double[][] rle(double[] e) {
List vals = new ArrayList();
List lens = new ArrayList();
double last_val = e[0];
int last_ct = 1, n = e.length;
for (int i = 1; i < n; i++)
if (e[i] != last_val) {
vals.add(last_val);
lens.add(last_ct);
last_val = e[i];
last_ct = 1;
} else
last_ct++;
vals.add(last_val);
lens.add(last_ct);
n = vals.size();
double[] uvals = new double[n];
double[] ulen = new double[n];
for (int i = 0; i < n; i++) {
uvals[i] = vals.get(i);
ulen[i] = lens.get(i);
}
return new double[][] {uvals, ulen};
}
/**
* Mimic the behavior of match function in R.
* @param x
* @param y
* @return match index
*/
public static final int[] match(double[] x, double[] y) {
int nx = x.length, ny = y.length;
int[] r = new int[nx];
for (int i = 0; i < nx; i++) {
r[i] = -1;
for (int j = 0; j < ny; j++)
if (x[i] == y[j]) {
r[i] = j;
break;
}
}
return r;
}
public static final int[] match(int[] x, int[] y) {
int nx = x.length, ny = y.length;
int[] r = new int[nx];
for (int i = 0; i < nx; i++) {
r[i] = -1;
for (int j = 0; j < ny; j++)
if (x[i] == y[j]) {
r[i] = j;
break;
}
}
return r;
}
public static final int[] match(S[] x, S[] y) {
int nx = x.length, ny = y.length;
int[] r = new int[nx];
for (int i = 0; i < nx; i++) {
r[i] = -1;
for (int j = 0; j < ny; j++)
if (x[i].equals(y[j])) {
r[i] = j;
break;
}
}
return r;
}
/**
* Mimic the tabulate function in R
* @param x
* @param n
* @return tabulate
*/
public static final int[] tabulate(int[] x, int n) {
int nx = x.length;
int[] r = new int[n];
for (int i = 0; i < nx; i++) r[x[i]]++;
return r;
}
public static final int[] seq_along(double[] z) {
return colon(1, z.length);
}
/**
* Mimic x[idx] behavior of R
* @param x
* @param idx
* @return array
*/
public static final double[] index(double[] x, int[] idx) {
int n = idx.length;
double[] r = new double[n];
for (int i = 0; i < n; i++)
r[i] = x[idx[i]];
return r;
}
/**
* Mimic x[idx] behavior of R
* @param x
* @param idx
* @return array
*/
public static final double[] index_min1(double[] x, int[] idx) {
int n = idx.length;
double[] r = new double[n];
for (int i = 0; i < n; i++)
r[i] = x[idx[i] - 1];
return r;
}
public static final int[] to_int_array(Collection s) {
int n = s.size();
int[] r = new int[n];
int i = 0;
for (int _s : s)
r[i++] = _s;
return r;
}
public static final double[] to_double_array(Collection s) {
int n = s.size();
double[] r = new double[n];
int i = 0;
for (double _s : s)
r[i++] = _s;
return r;
}
public static final boolean any(boolean... x) {
for (boolean _x: x)
if (_x)
return true;
return false;
}
public static final boolean anyNA(double... x) {
for (double _x: x)
if (Double.isNaN(_x))
return true;
return false;
}
/*
public static final void main (String[] args) {
int n = 100;
double[] x = new double[n];
for (int i = 0; i < n; i++)
x[i] = Math.random() * 100 - 50;
sort(x);
boolean sorted = true;
for (int i = 1; i < n; i++)
if (x[i-1] > x[i]) {
sorted = false;
break;
}
System.out.println(sorted);
}
//*/
}
Ads help maintain this website.