/**
* Copyright (c) Rich Hickey. All rights reserved.
* The use and distribution terms for this software are covered by the
* Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
* which can be found in the file epl-v10.html at the root of this distribution.
* By using this software in any fashion, you are agreeing to be bound by
* the terms of this license.
* You must not remove this notice, or any other, from this software.
**/
/* rich Mar 31, 2008 */
package clojure.lang;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.math.MathContext;
public class Numbers{
static interface Ops{
Ops combine(Ops y);
Ops opsWith(LongOps x);
Ops opsWith(DoubleOps x);
Ops opsWith(RatioOps x);
Ops opsWith(BigIntOps x);
Ops opsWith(BigDecimalOps x);
public boolean isZero(Number x);
public boolean isPos(Number x);
public boolean isNeg(Number x);
public Number add(Number x, Number y);
public Number addP(Number x, Number y);
public Number multiply(Number x, Number y);
public Number multiplyP(Number x, Number y);
public Number divide(Number x, Number y);
public Number quotient(Number x, Number y);
public Number remainder(Number x, Number y);
public boolean equiv(Number x, Number y);
public boolean lt(Number x, Number y);
public Number negate(Number x);
public Number negateP(Number x);
public Number inc(Number x);
public Number incP(Number x);
public Number dec(Number x);
public Number decP(Number x);
}
static abstract class OpsP implements Ops{
public Number addP(Number x, Number y){
return add(x, y);
}
public Number multiplyP(Number x, Number y){
return multiply(x, y);
}
public Number negateP(Number x){
return negate(x);
}
public Number incP(Number x){
return inc(x);
}
public Number decP(Number x){
return dec(x);
}
}
static public boolean isZero(Object x){
return ops(x).isZero((Number)x);
}
static public boolean isPos(Object x){
return ops(x).isPos((Number)x);
}
static public boolean isNeg(Object x){
return ops(x).isNeg((Number)x);
}
static public Number minus(Object x){
return ops(x).negate((Number)x);
}
static public Number minusP(Object x){
return ops(x).negateP((Number)x);
}
static public Number inc(Object x){
return ops(x).inc((Number)x);
}
static public Number incP(Object x){
return ops(x).incP((Number)x);
}
static public Number dec(Object x){
return ops(x).dec((Number)x);
}
static public Number decP(Object x){
return ops(x).decP((Number)x);
}
static public Number add(Object x, Object y){
return ops(x).combine(ops(y)).add((Number)x, (Number)y);
}
static public Number addP(Object x, Object y){
return ops(x).combine(ops(y)).addP((Number)x, (Number)y);
}
static public Number minus(Object x, Object y){
Ops yops = ops(y);
return ops(x).combine(yops).add((Number)x, yops.negate((Number)y));
}
static public Number minusP(Object x, Object y){
Ops yops = ops(y);
Number negativeY = yops.negateP((Number) y);
Ops negativeYOps = ops(negativeY);
return ops(x).combine(negativeYOps).addP((Number)x, negativeY);
}
static public Number multiply(Object x, Object y){
return ops(x).combine(ops(y)).multiply((Number)x, (Number)y);
}
static public Number multiplyP(Object x, Object y){
return ops(x).combine(ops(y)).multiplyP((Number)x, (Number)y);
}
static public Number divide(Object x, Object y){
Ops yops = ops(y);
if(yops.isZero((Number)y))
throw new ArithmeticException("Divide by zero");
return ops(x).combine(yops).divide((Number)x, (Number)y);
}
static public Number quotient(Object x, Object y){
Ops yops = ops(y);
if(yops.isZero((Number) y))
throw new ArithmeticException("Divide by zero");
return ops(x).combine(yops).quotient((Number)x, (Number)y);
}
static public Number remainder(Object x, Object y){
Ops yops = ops(y);
if(yops.isZero((Number) y))
throw new ArithmeticException("Divide by zero");
return ops(x).combine(yops).remainder((Number)x, (Number)y);
}
static public double quotient(double n, double d){
if(d == 0)
throw new ArithmeticException("Divide by zero");
double q = n / d;
if(q <= Long.MAX_VALUE && q >= Long.MIN_VALUE)
{
return (double)(long) q;
}
else
{ //bigint quotient
return new BigDecimal(q).toBigInteger().doubleValue();
}
}
static public double remainder(double n, double d){
if(d == 0)
throw new ArithmeticException("Divide by zero");
double q = n / d;
if(q <= Long.MAX_VALUE && q >= Long.MIN_VALUE)
{
return (n - ((long) q) * d);
}
else
{ //bigint quotient
Number bq = new BigDecimal(q).toBigInteger();
return (n - bq.doubleValue() * d);
}
}
static public boolean equiv(Object x, Object y){
return equiv((Number) x, (Number) y);
}
static public boolean equiv(Number x, Number y){
return ops(x).combine(ops(y)).equiv(x, y);
}
static public boolean equal(Number x, Number y){
return category(x) == category(y)
&& ops(x).combine(ops(y)).equiv(x, y);
}
static public boolean lt(Object x, Object y){
return ops(x).combine(ops(y)).lt((Number)x, (Number)y);
}
static public boolean lte(Object x, Object y){
return !ops(x).combine(ops(y)).lt((Number)y, (Number)x);
}
static public boolean gt(Object x, Object y){
return ops(x).combine(ops(y)).lt((Number)y, (Number)x);
}
static public boolean gte(Object x, Object y){
return !ops(x).combine(ops(y)).lt((Number)x, (Number)y);
}
static public int compare(Number x, Number y){
Ops ops = ops(x).combine(ops(y));
if(ops.lt(x, y))
return -1;
else if(ops.lt(y, x))
return 1;
return 0;
}
static BigInt toBigInt(Object x){
if(x instanceof BigInt)
return (BigInt) x;
if(x instanceof BigInteger)
return BigInt.fromBigInteger((BigInteger) x);
else
return BigInt.fromLong(((Number) x).longValue());
}
static BigInteger toBigInteger(Object x){
if(x instanceof BigInteger)
return (BigInteger) x;
else if(x instanceof BigInt)
return ((BigInt) x).toBigInteger();
else
return BigInteger.valueOf(((Number) x).longValue());
}
static BigDecimal toBigDecimal(Object x){
if(x instanceof BigDecimal)
return (BigDecimal) x;
else if(x instanceof BigInt)
{
BigInt bi = (BigInt) x;
if(bi.bipart == null)
return BigDecimal.valueOf(bi.lpart);
else
return new BigDecimal(bi.bipart);
}
else if(x instanceof BigInteger)
return new BigDecimal((BigInteger) x);
else if(x instanceof Double)
return new BigDecimal(((Number) x).doubleValue());
else if(x instanceof Float)
return new BigDecimal(((Number) x).doubleValue());
else if(x instanceof Ratio)
{
Ratio r = (Ratio)x;
return (BigDecimal)divide(new BigDecimal(r.numerator), r.denominator);
}
else
return BigDecimal.valueOf(((Number) x).longValue());
}
static public Ratio toRatio(Object x){
if(x instanceof Ratio)
return (Ratio) x;
else if(x instanceof BigDecimal)
{
BigDecimal bx = (BigDecimal) x;
BigInteger bv = bx.unscaledValue();
int scale = bx.scale();
if(scale < 0)
return new Ratio(bv.multiply(BigInteger.TEN.pow(-scale)), BigInteger.ONE);
else
return new Ratio(bv, BigInteger.TEN.pow(scale));
}
return new Ratio(toBigInteger(x), BigInteger.ONE);
}
static public Number rationalize(Number x){
if(x instanceof Float || x instanceof Double)
return rationalize(BigDecimal.valueOf(x.doubleValue()));
else if(x instanceof BigDecimal)
{
BigDecimal bx = (BigDecimal) x;
BigInteger bv = bx.unscaledValue();
int scale = bx.scale();
if(scale < 0)
return BigInt.fromBigInteger(bv.multiply(BigInteger.TEN.pow(-scale)));
else
return divide(bv, BigInteger.TEN.pow(scale));
}
return x;
}
//static Number box(int val){
// return Integer.valueOf(val);
//}
//static Number box(long val){
// return Long.valueOf(val);
//}
//
//static Double box(double val){
// return Double.valueOf(val);
//}
//
//static Double box(float val){
// return Double.valueOf((double) val);
//}
static public Number reduceBigInt(BigInt val){
if(val.bipart == null)
return num(val.lpart);
else
return val.bipart;
}
static public Number divide(BigInteger n, BigInteger d){
if(d.equals(BigInteger.ZERO))
throw new ArithmeticException("Divide by zero");
BigInteger gcd = n.gcd(d);
if(gcd.equals(BigInteger.ZERO))
return BigInt.ZERO;
n = n.divide(gcd);
d = d.divide(gcd);
if(d.equals(BigInteger.ONE))
return BigInt.fromBigInteger(n);
else if(d.equals(BigInteger.ONE.negate()))
return BigInt.fromBigInteger(n.negate());
return new Ratio((d.signum() < 0 ? n.negate() : n),
(d.signum() < 0 ? d.negate() : d));
}
static public int shiftLeftInt(int x, int n){
return x << n;
}
static public long shiftLeft(Object x, Object y){
return shiftLeft(bitOpsCast(x),bitOpsCast(y));
}
static public long shiftLeft(Object x, long y){
return shiftLeft(bitOpsCast(x),y);
}
static public long shiftLeft(long x, Object y){
return shiftLeft(x,bitOpsCast(y));
}
static public long shiftLeft(long x, long n){
return x << n;
}
static public int shiftRightInt(int x, int n){
return x >> n;
}
static public long shiftRight(Object x, Object y){
return shiftRight(bitOpsCast(x),bitOpsCast(y));
}
static public long shiftRight(Object x, long y){
return shiftRight(bitOpsCast(x),y);
}
static public long shiftRight(long x, Object y){
return shiftRight(x,bitOpsCast(y));
}
static public long shiftRight(long x, long n){
return x >> n;
}
final static class LongOps implements Ops{
public Ops combine(Ops y){
return y.opsWith(this);
}
final public Ops opsWith(LongOps x){
return this;
}
final public Ops opsWith(DoubleOps x){
return DOUBLE_OPS;
}
final public Ops opsWith(RatioOps x){
return RATIO_OPS;
}
final public Ops opsWith(BigIntOps x){
return BIGINT_OPS;
}
final public Ops opsWith(BigDecimalOps x){
return BIGDECIMAL_OPS;
}
public boolean isZero(Number x){
return x.longValue() == 0;
}
public boolean isPos(Number x){
return x.longValue() > 0;
}
public boolean isNeg(Number x){
return x.longValue() < 0;
}
final public Number add(Number x, Number y){
return num(Numbers.add(x.longValue(),y.longValue()));
}
final public Number addP(Number x, Number y){
long lx = x.longValue(), ly = y.longValue();
long ret = lx + ly;
if ((ret ^ lx) < 0 && (ret ^ ly) < 0)
return BIGINT_OPS.add(x, y);
return num(ret);
}
final public Number multiply(Number x, Number y){
return num(Numbers.multiply(x.longValue(), y.longValue()));
}
final public Number multiplyP(Number x, Number y){
long lx = x.longValue(), ly = y.longValue();
long ret = lx * ly;
if (ly != 0 && ret/ly != lx)
return BIGINT_OPS.multiply(x, y);
return num(ret);
}
static long gcd(long u, long v){
while(v != 0)
{
long r = u % v;
u = v;
v = r;
}
return u;
}
public Number divide(Number x, Number y){
long n = x.longValue();
long val = y.longValue();
long gcd = gcd(n, val);
if(gcd == 0)
return num(0);
n = n / gcd;
long d = val / gcd;
if(d == 1)
return num(n);
if(d < 0)
{
n = -n;
d = -d;
}
return new Ratio(BigInteger.valueOf(n), BigInteger.valueOf(d));
}
public Number quotient(Number x, Number y){
return num(x.longValue() / y.longValue());
}
public Number remainder(Number x, Number y){
return num(x.longValue() % y.longValue());
}
public boolean equiv(Number x, Number y){
return x.longValue() == y.longValue();
}
public boolean lt(Number x, Number y){
return x.longValue() < y.longValue();
}
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
long val = x.longValue();
return num(Numbers.minus(val));
}
final public Number negateP(Number x){
long val = x.longValue();
if(val > Long.MIN_VALUE)
return num(-val);
return BigInt.fromBigInteger(BigInteger.valueOf(val).negate());
}
public Number inc(Number x){
long val = x.longValue();
return num(Numbers.inc(val));
}
public Number incP(Number x){
long val = x.longValue();
if(val < Long.MAX_VALUE)
return num(val + 1);
return BIGINT_OPS.inc(x);
}
public Number dec(Number x){
long val = x.longValue();
return num(Numbers.dec(val));
}
public Number decP(Number x){
long val = x.longValue();
if(val > Long.MIN_VALUE)
return num(val - 1);
return BIGINT_OPS.dec(x);
}
}
final static class DoubleOps extends OpsP{
public Ops combine(Ops y){
return y.opsWith(this);
}
final public Ops opsWith(LongOps x){
return this;
}
final public Ops opsWith(DoubleOps x){
return this;
}
final public Ops opsWith(RatioOps x){
return this;
}
final public Ops opsWith(BigIntOps x){
return this;
}
final public Ops opsWith(BigDecimalOps x){
return this;
}
public boolean isZero(Number x){
return x.doubleValue() == 0;
}
public boolean isPos(Number x){
return x.doubleValue() > 0;
}
public boolean isNeg(Number x){
return x.doubleValue() < 0;
}
final public Number add(Number x, Number y){
return Double.valueOf(x.doubleValue() + y.doubleValue());
}
final public Number multiply(Number x, Number y){
return Double.valueOf(x.doubleValue() * y.doubleValue());
}
public Number divide(Number x, Number y){
return Double.valueOf(x.doubleValue() / y.doubleValue());
}
public Number quotient(Number x, Number y){
return Numbers.quotient(x.doubleValue(), y.doubleValue());
}
public Number remainder(Number x, Number y){
return Numbers.remainder(x.doubleValue(), y.doubleValue());
}
public boolean equiv(Number x, Number y){
return x.doubleValue() == y.doubleValue();
}
public boolean lt(Number x, Number y){
return x.doubleValue() < y.doubleValue();
}
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
return Double.valueOf(-x.doubleValue());
}
public Number inc(Number x){
return Double.valueOf(x.doubleValue() + 1);
}
public Number dec(Number x){
return Double.valueOf(x.doubleValue() - 1);
}
}
final static class RatioOps extends OpsP{
public Ops combine(Ops y){
return y.opsWith(this);
}
final public Ops opsWith(LongOps x){
return this;
}
final public Ops opsWith(DoubleOps x){
return DOUBLE_OPS;
}
final public Ops opsWith(RatioOps x){
return this;
}
final public Ops opsWith(BigIntOps x){
return this;
}
final public Ops opsWith(BigDecimalOps x){
return BIGDECIMAL_OPS;
}
public boolean isZero(Number x){
Ratio r = (Ratio) x;
return r.numerator.signum() == 0;
}
public boolean isPos(Number x){
Ratio r = (Ratio) x;
return r.numerator.signum() > 0;
}
public boolean isNeg(Number x){
Ratio r = (Ratio) x;
return r.numerator.signum() < 0;
}
static Number normalizeRet(Number ret, Number x, Number y){
// if(ret instanceof BigInteger && !(x instanceof BigInteger || y instanceof BigInteger))
// {
// return reduceBigInt((BigInteger) ret);
// }
return ret;
}
final public Number add(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
Number ret = divide(ry.numerator.multiply(rx.denominator)
.add(rx.numerator.multiply(ry.denominator))
, ry.denominator.multiply(rx.denominator));
return normalizeRet(ret, x, y);
}
final public Number multiply(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
Number ret = Numbers.divide(ry.numerator.multiply(rx.numerator)
, ry.denominator.multiply(rx.denominator));
return normalizeRet(ret, x, y);
}
public Number divide(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
Number ret = Numbers.divide(ry.denominator.multiply(rx.numerator)
, ry.numerator.multiply(rx.denominator));
return normalizeRet(ret, x, y);
}
public Number quotient(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
BigInteger q = rx.numerator.multiply(ry.denominator).divide(
rx.denominator.multiply(ry.numerator));
return normalizeRet(BigInt.fromBigInteger(q), x, y);
}
public Number remainder(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
BigInteger q = rx.numerator.multiply(ry.denominator).divide(
rx.denominator.multiply(ry.numerator));
Number ret = Numbers.minus(x, Numbers.multiply(q, y));
return normalizeRet(ret, x, y);
}
public boolean equiv(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
return rx.numerator.equals(ry.numerator)
&& rx.denominator.equals(ry.denominator);
}
public boolean lt(Number x, Number y){
Ratio rx = toRatio(x);
Ratio ry = toRatio(y);
return Numbers.lt(rx.numerator.multiply(ry.denominator), ry.numerator.multiply(rx.denominator));
}
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
Ratio r = (Ratio) x;
return new Ratio(r.numerator.negate(), r.denominator);
}
public Number inc(Number x){
return Numbers.add(x, 1);
}
public Number dec(Number x){
return Numbers.add(x, -1);
}
}
final static class BigIntOps extends OpsP{
public Ops combine(Ops y){
return y.opsWith(this);
}
final public Ops opsWith(LongOps x){
return this;
}
final public Ops opsWith(DoubleOps x){
return DOUBLE_OPS;
}
final public Ops opsWith(RatioOps x){
return RATIO_OPS;
}
final public Ops opsWith(BigIntOps x){
return this;
}
final public Ops opsWith(BigDecimalOps x){
return BIGDECIMAL_OPS;
}
public boolean isZero(Number x){
BigInt bx = toBigInt(x);
if(bx.bipart == null)
return bx.lpart == 0;
return bx.bipart.signum() == 0;
}
public boolean isPos(Number x){
BigInt bx = toBigInt(x);
if(bx.bipart == null)
return bx.lpart > 0;
return bx.bipart.signum() > 0;
}
public boolean isNeg(Number x){
BigInt bx = toBigInt(x);
if(bx.bipart == null)
return bx.lpart < 0;
return bx.bipart.signum() < 0;
}
final public Number add(Number x, Number y){
return toBigInt(x).add(toBigInt(y));
}
final public Number multiply(Number x, Number y){
return toBigInt(x).multiply(toBigInt(y));
}
public Number divide(Number x, Number y){
return Numbers.divide(toBigInteger(x), toBigInteger(y));
}
public Number quotient(Number x, Number y){
return toBigInt(x).quotient(toBigInt(y));
}
public Number remainder(Number x, Number y){
return toBigInt(x).remainder(toBigInt(y));
}
public boolean equiv(Number x, Number y){
return toBigInt(x).equals(toBigInt(y));
}
public boolean lt(Number x, Number y){
return toBigInt(x).lt(toBigInt(y));
}
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
return BigInt.fromBigInteger(toBigInteger(x).negate());
}
public Number inc(Number x){
BigInteger bx = toBigInteger(x);
return BigInt.fromBigInteger(bx.add(BigInteger.ONE));
}
public Number dec(Number x){
BigInteger bx = toBigInteger(x);
return BigInt.fromBigInteger(bx.subtract(BigInteger.ONE));
}
}
final static class BigDecimalOps extends OpsP{
final static Var MATH_CONTEXT = RT.MATH_CONTEXT;
public Ops combine(Ops y){
return y.opsWith(this);
}
final public Ops opsWith(LongOps x){
return this;
}
final public Ops opsWith(DoubleOps x){
return DOUBLE_OPS;
}
final public Ops opsWith(RatioOps x){
return this;
}
final public Ops opsWith(BigIntOps x){
return this;
}
final public Ops opsWith(BigDecimalOps x){
return this;
}
public boolean isZero(Number x){
BigDecimal bx = (BigDecimal) x;
return bx.signum() == 0;
}
public boolean isPos(Number x){
BigDecimal bx = (BigDecimal) x;
return bx.signum() > 0;
}
public boolean isNeg(Number x){
BigDecimal bx = (BigDecimal) x;
return bx.signum() < 0;
}
final public Number add(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? toBigDecimal(x).add(toBigDecimal(y))
: toBigDecimal(x).add(toBigDecimal(y), mc);
}
final public Number multiply(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? toBigDecimal(x).multiply(toBigDecimal(y))
: toBigDecimal(x).multiply(toBigDecimal(y), mc);
}
public Number divide(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? toBigDecimal(x).divide(toBigDecimal(y))
: toBigDecimal(x).divide(toBigDecimal(y), mc);
}
public Number quotient(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? toBigDecimal(x).divideToIntegralValue(toBigDecimal(y))
: toBigDecimal(x).divideToIntegralValue(toBigDecimal(y), mc);
}
public Number remainder(Number x, Number y){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? toBigDecimal(x).remainder(toBigDecimal(y))
: toBigDecimal(x).remainder(toBigDecimal(y), mc);
}
public boolean equiv(Number x, Number y){
return toBigDecimal(x).equals(toBigDecimal(y));
}
public boolean lt(Number x, Number y){
return toBigDecimal(x).compareTo(toBigDecimal(y)) < 0;
}
//public Number subtract(Number x, Number y);
final public Number negate(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
return mc == null
? ((BigDecimal) x).negate()
: ((BigDecimal) x).negate(mc);
}
public Number inc(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
BigDecimal bx = (BigDecimal) x;
return mc == null
? bx.add(BigDecimal.ONE)
: bx.add(BigDecimal.ONE, mc);
}
public Number dec(Number x){
MathContext mc = (MathContext) MATH_CONTEXT.deref();
BigDecimal bx = (BigDecimal) x;
return mc == null
? bx.subtract(BigDecimal.ONE)
: bx.subtract(BigDecimal.ONE, mc);
}
}
static final LongOps LONG_OPS = new LongOps();
static final DoubleOps DOUBLE_OPS = new DoubleOps();
static final RatioOps RATIO_OPS = new RatioOps();
static final BigIntOps BIGINT_OPS = new BigIntOps();
static final BigDecimalOps BIGDECIMAL_OPS = new BigDecimalOps();
static public enum Category {INTEGER, FLOATING, DECIMAL, RATIO};
static Ops ops(Object x){
Class xc = x.getClass();
if(xc == Long.class)
return LONG_OPS;
else if(xc == Double.class)
return DOUBLE_OPS;
else if(xc == Integer.class)
return LONG_OPS;
else if(xc == Float.class)
return DOUBLE_OPS;
else if(xc == BigInt.class)
return BIGINT_OPS;
else if(xc == BigInteger.class)
return BIGINT_OPS;
else if(xc == Ratio.class)
return RATIO_OPS;
else if(xc == BigDecimal.class)
return BIGDECIMAL_OPS;
else
return LONG_OPS;
}
static int hasheq(Number x){
Class xc = x.getClass();
if(xc == Long.class
|| xc == Integer.class
|| xc == Short.class
|| xc == Byte.class)
{
long lpart = x.longValue();
return (int) (lpart ^ (lpart >>> 32));
}
return x.hashCode();
}
static Category category(Object x){
Class xc = x.getClass();
if(xc == Integer.class)
return Category.INTEGER;
else if(xc == Double.class)
return Category.FLOATING;
else if(xc == Long.class)
return Category.INTEGER;
else if(xc == Float.class)
return Category.FLOATING;
else if(xc == BigInt.class)
return Category.INTEGER;
else if(xc == Ratio.class)
return Category.RATIO;
else if(xc == BigDecimal.class)
return Category.DECIMAL;
else
return Category.INTEGER;
}
static long bitOpsCast(Object x){
Class xc = x.getClass();
if(xc == Long.class
|| xc == Integer.class
|| xc == Short.class
|| xc == Byte.class)
return RT.longCast(x);
// no bignums, no decimals
throw new IllegalArgumentException("bit operation not supported for: " + xc);
}
static public float[] float_array(int size, Object init){
float[] ret = new float[size];
if(init instanceof Number)
{
float f = ((Number) init).floatValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).floatValue();
}
return ret;
}
static public float[] float_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new float[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
float[] ret = new float[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).floatValue();
return ret;
}
}
static public double[] double_array(int size, Object init){
double[] ret = new double[size];
if(init instanceof Number)
{
double f = ((Number) init).doubleValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).doubleValue();
}
return ret;
}
static public double[] double_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new double[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
double[] ret = new double[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).doubleValue();
return ret;
}
}
static public int[] int_array(int size, Object init){
int[] ret = new int[size];
if(init instanceof Number)
{
int f = ((Number) init).intValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).intValue();
}
return ret;
}
static public int[] int_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new int[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
int[] ret = new int[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).intValue();
return ret;
}
}
static public long[] long_array(int size, Object init){
long[] ret = new long[size];
if(init instanceof Number)
{
long f = ((Number) init).longValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).longValue();
}
return ret;
}
static public long[] long_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new long[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
long[] ret = new long[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = ((Number) s.first()).longValue();
return ret;
}
}
static public short[] short_array(int size, Object init){
short[] ret = new short[size];
if(init instanceof Short)
{
short s = (Short) init;
for(int i = 0; i < ret.length; i++)
ret[i] = s;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Short) s.first();
}
return ret;
}
static public short[] short_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new short[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
short[] ret = new short[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Short) s.first();
return ret;
}
}
static public char[] char_array(int size, Object init){
char[] ret = new char[size];
if(init instanceof Character)
{
char c = (Character) init;
for(int i = 0; i < ret.length; i++)
ret[i] = c;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Character) s.first();
}
return ret;
}
static public char[] char_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new char[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
char[] ret = new char[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Character) s.first();
return ret;
}
}
static public byte[] byte_array(int size, Object init){
byte[] ret = new byte[size];
if(init instanceof Byte)
{
byte b = (Byte) init;
for(int i = 0; i < ret.length; i++)
ret[i] = b;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Byte) s.first();
}
return ret;
}
static public byte[] byte_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new byte[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
byte[] ret = new byte[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Byte)s.first();
return ret;
}
}
static public boolean[] boolean_array(int size, Object init){
boolean[] ret = new boolean[size];
if(init instanceof Boolean)
{
boolean b = (Boolean) init;
for(int i = 0; i < ret.length; i++)
ret[i] = b;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Boolean)s.first();
}
return ret;
}
static public boolean[] boolean_array(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new boolean[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = RT.count(s);
boolean[] ret = new boolean[size];
for(int i = 0; i < size && s != null; i++, s = s.next())
ret[i] = (Boolean)s.first();
return ret;
}
}
static public boolean[] booleans(Object array){
return (boolean[]) array;
}
static public byte[] bytes(Object array){
return (byte[]) array;
}
static public char[] chars(Object array){
return (char[]) array;
}
static public short[] shorts(Object array){
return (short[]) array;
}
static public float[] floats(Object array){
return (float[]) array;
}
static public double[] doubles(Object array){
return (double[]) array;
}
static public int[] ints(Object array){
return (int[]) array;
}
static public long[] longs(Object array){
return (long[]) array;
}
static public Number num(Object x){
return (Number) x;
}
static public Number num(float x){
return Float.valueOf(x);
}
static public Number num(double x){
return Double.valueOf(x);
}
static public double add(double x, double y){
return x + y;
}
static public double addP(double x, double y){
return x + y;
}
static public double minus(double x, double y){
return x - y;
}
static public double minusP(double x, double y){
return x - y;
}
static public double minus(double x){
return -x;
}
static public double minusP(double x){
return -x;
}
static public double inc(double x){
return x + 1;
}
static public double incP(double x){
return x + 1;
}
static public double dec(double x){
return x - 1;
}
static public double decP(double x){
return x - 1;
}
static public double multiply(double x, double y){
return x * y;
}
static public double multiplyP(double x, double y){
return x * y;
}
static public double divide(double x, double y){
return x / y;
}
static public boolean equiv(double x, double y){
return x == y;
}
static public boolean lt(double x, double y){
return x < y;
}
static public boolean lte(double x, double y){
return x <= y;
}
static public boolean gt(double x, double y){
return x > y;
}
static public boolean gte(double x, double y){
return x >= y;
}
static public boolean isPos(double x){
return x > 0;
}
static public boolean isNeg(double x){
return x < 0;
}
static public boolean isZero(double x){
return x == 0;
}
static int throwIntOverflow(){
throw new ArithmeticException("integer overflow");
}
//static public Number num(int x){
// return Integer.valueOf(x);
//}
static public int unchecked_int_add(int x, int y){
return x + y;
}
static public int unchecked_int_subtract(int x, int y){
return x - y;
}
static public int unchecked_int_negate(int x){
return -x;
}
static public int unchecked_int_inc(int x){
return x + 1;
}
static public int unchecked_int_dec(int x){
return x - 1;
}
static public int unchecked_int_multiply(int x, int y){
return x * y;
}
//static public int add(int x, int y){
// int ret = x + y;
// if ((ret ^ x) < 0 && (ret ^ y) < 0)
// return throwIntOverflow();
// return ret;
//}
//static public int not(int x){
// return ~x;
//}
static public long not(Object x){
return not(bitOpsCast(x));
}
static public long not(long x){
return ~x;
}
//static public int and(int x, int y){
// return x & y;
//}
static public long and(Object x, Object y){
return and(bitOpsCast(x),bitOpsCast(y));
}
static public long and(Object x, long y){
return and(bitOpsCast(x),y);
}
static public long and(long x, Object y){
return and(x,bitOpsCast(y));
}
static public long and(long x, long y){
return x & y;
}
//static public int or(int x, int y){
// return x | y;
//}
static public long or(Object x, Object y){
return or(bitOpsCast(x),bitOpsCast(y));
}
static public long or(Object x, long y){
return or(bitOpsCast(x),y);
}
static public long or(long x, Object y){
return or(x,bitOpsCast(y));
}
static public long or(long x, long y){
return x | y;
}
//static public int xor(int x, int y){
// return x ^ y;
//}
static public long xor(Object x, Object y){
return xor(bitOpsCast(x),bitOpsCast(y));
}
static public long xor(Object x, long y){
return xor(bitOpsCast(x),y);
}
static public long xor(long x, Object y){
return xor(x,bitOpsCast(y));
}
static public long xor(long x, long y){
return x ^ y;
}
static public long andNot(Object x, Object y){
return andNot(bitOpsCast(x),bitOpsCast(y));
}
static public long andNot(Object x, long y){
return andNot(bitOpsCast(x),y);
}
static public long andNot(long x, Object y){
return andNot(x,bitOpsCast(y));
}
static public long andNot(long x, long y){
return x & ~y;
}
static public long clearBit(Object x, Object y){
return clearBit(bitOpsCast(x),bitOpsCast(y));
}
static public long clearBit(Object x, long y){
return clearBit(bitOpsCast(x),y);
}
static public long clearBit(long x, Object y){
return clearBit(x,bitOpsCast(y));
}
static public long clearBit(long x, long n){
return x & ~(1L << n);
}
static public long setBit(Object x, Object y){
return setBit(bitOpsCast(x),bitOpsCast(y));
}
static public long setBit(Object x, long y){
return setBit(bitOpsCast(x),y);
}
static public long setBit(long x, Object y){
return setBit(x,bitOpsCast(y));
}
static public long setBit(long x, long n){
return x | (1L << n);
}
static public long flipBit(Object x, Object y){
return flipBit(bitOpsCast(x),bitOpsCast(y));
}
static public long flipBit(Object x, long y){
return flipBit(bitOpsCast(x),y);
}
static public long flipBit(long x, Object y){
return flipBit(x,bitOpsCast(y));
}
static public long flipBit(long x, long n){
return x ^ (1L << n);
}
static public boolean testBit(Object x, Object y){
return testBit(bitOpsCast(x),bitOpsCast(y));
}
static public boolean testBit(Object x, long y){
return testBit(bitOpsCast(x),y);
}
static public boolean testBit(long x, Object y){
return testBit(x,bitOpsCast(y));
}
static public boolean testBit(long x, long n){
return (x & (1L << n)) != 0;
}
//static public int minus(int x, int y){
// int ret = x - y;
// if (((ret ^ x) < 0 && (ret ^ ~y) < 0))
// return throwIntOverflow();
// return ret;
//}
//static public int minus(int x){
// if(x == Integer.MIN_VALUE)
// return throwIntOverflow();
// return -x;
//}
//static public int inc(int x){
// if(x == Integer.MAX_VALUE)
// return throwIntOverflow();
// return x + 1;
//}
//static public int dec(int x){
// if(x == Integer.MIN_VALUE)
// return throwIntOverflow();
// return x - 1;
//}
//static public int multiply(int x, int y){
// int ret = x * y;
// if (y != 0 && ret/y != x)
// return throwIntOverflow();
// return ret;
//}
static public int unchecked_int_divide(int x, int y){
return x / y;
}
static public int unchecked_int_remainder(int x, int y){
return x % y;
}
//static public boolean equiv(int x, int y){
// return x == y;
//}
//static public boolean lt(int x, int y){
// return x < y;
//}
//static public boolean lte(int x, int y){
// return x <= y;
//}
//static public boolean gt(int x, int y){
// return x > y;
//}
//static public boolean gte(int x, int y){
// return x >= y;
//}
//static public boolean isPos(int x){
// return x > 0;
//}
//static public boolean isNeg(int x){
// return x < 0;
//}
//static public boolean isZero(int x){
// return x == 0;
//}
static public Number num(long x){
return Long.valueOf(x);
}
static public long unchecked_add(long x, long y){return x + y;}
static public long unchecked_minus(long x, long y){return x - y;}
static public long unchecked_multiply(long x, long y){return x * y;}
static public long unchecked_minus(long x){return -x;}
static public long unchecked_inc(long x){return x + 1;}
static public long unchecked_dec(long x){return x - 1;}
static public Number unchecked_add(Object x, Object y){return add(x,y);}
static public Number unchecked_minus(Object x, Object y){return minus(x,y);}
static public Number unchecked_multiply(Object x, Object y){return multiply(x,y);}
static public Number unchecked_minus(Object x){return minus(x);}
static public Number unchecked_inc(Object x){return inc(x);}
static public Number unchecked_dec(Object x){return dec(x);}
static public double unchecked_add(double x, double y){return add(x,y);}
static public double unchecked_minus(double x, double y){return minus(x,y);}
static public double unchecked_multiply(double x, double y){return multiply(x,y);}
static public double unchecked_minus(double x){return minus(x);}
static public double unchecked_inc(double x){return inc(x);}
static public double unchecked_dec(double x){return dec(x);}
static public double unchecked_add(double x, Object y){return add(x,y);}
static public double unchecked_minus(double x, Object y){return minus(x,y);}
static public double unchecked_multiply(double x, Object y){return multiply(x,y);}
static public double unchecked_add(Object x, double y){return add(x,y);}
static public double unchecked_minus(Object x, double y){return minus(x,y);}
static public double unchecked_multiply(Object x, double y){return multiply(x,y);}
static public double unchecked_add(double x, long y){return add(x,y);}
static public double unchecked_minus(double x, long y){return minus(x,y);}
static public double unchecked_multiply(double x, long y){return multiply(x,y);}
static public double unchecked_add(long x, double y){return add(x,y);}
static public double unchecked_minus(long x, double y){return minus(x,y);}
static public double unchecked_multiply(long x, double y){return multiply(x,y);}
static public Number unchecked_add(long x, Object y){return add(x,y);}
static public Number unchecked_minus(long x, Object y){return minus(x,y);}
static public Number unchecked_multiply(long x, Object y){return multiply(x,y);}
static public Number unchecked_add(Object x, long y){return add(x,y);}
static public Number unchecked_minus(Object x, long y){return minus(x,y);}
static public Number unchecked_multiply(Object x, long y){return multiply(x,y);}
static public Number quotient(double x, Object y){return quotient((Object)x,y);}
static public Number quotient(Object x, double y){return quotient(x,(Object)y);}
static public Number quotient(long x, Object y){return quotient((Object)x,y);}
static public Number quotient(Object x, long y){return quotient(x,(Object)y);}
static public double quotient(double x, long y){return quotient(x,(double)y);}
static public double quotient(long x, double y){return quotient((double)x,y);}
static public Number remainder(double x, Object y){return remainder((Object)x,y);}
static public Number remainder(Object x, double y){return remainder(x,(Object)y);}
static public Number remainder(long x, Object y){return remainder((Object)x,y);}
static public Number remainder(Object x, long y){return remainder(x,(Object)y);}
static public double remainder(double x, long y){return remainder(x,(double)y);}
static public double remainder(long x, double y){return remainder((double)x,y);}
static public long add(long x, long y){
long ret = x + y;
if ((ret ^ x) < 0 && (ret ^ y) < 0)
return throwIntOverflow();
return ret;
}
static public Number addP(long x, long y){
long ret = x + y;
if ((ret ^ x) < 0 && (ret ^ y) < 0)
return addP((Number)x,(Number)y);
return num(ret);
}
static public long minus(long x, long y){
long ret = x - y;
if (((ret ^ x) < 0 && (ret ^ ~y) < 0))
return throwIntOverflow();
return ret;
}
static public Number minusP(long x, long y){
long ret = x - y;
if (((ret ^ x) < 0 && (ret ^ ~y) < 0))
return minusP((Number)x,(Number)y);
return num(ret);
}
static public long minus(long x){
if(x == Long.MIN_VALUE)
return throwIntOverflow();
return -x;
}
static public Number minusP(long x){
if(x == Long.MIN_VALUE)
return BigInt.fromBigInteger(BigInteger.valueOf(x).negate());
return num(-x);
}
static public long inc(long x){
if(x == Long.MAX_VALUE)
return throwIntOverflow();
return x + 1;
}
static public Number incP(long x){
if(x == Long.MAX_VALUE)
return BIGINT_OPS.inc(x);
return num(x + 1);
}
static public long dec(long x){
if(x == Long.MIN_VALUE)
return throwIntOverflow();
return x - 1;
}
static public Number decP(long x){
if(x == Long.MIN_VALUE)
return BIGINT_OPS.dec(x);
return num(x - 1);
}
static public long multiply(long x, long y){
long ret = x * y;
if (y != 0 && ret/y != x)
return throwIntOverflow();
return ret;
}
static public Number multiplyP(long x, long y){
long ret = x * y;
if (y != 0 && ret/y != x)
return multiplyP((Number)x,(Number)y);
return num(ret);
}
static public long quotient(long x, long y){
return x / y;
}
static public long remainder(long x, long y){
return x % y;
}
static public boolean equiv(long x, long y){
return x == y;
}
static public boolean lt(long x, long y){
return x < y;
}
static public boolean lte(long x, long y){
return x <= y;
}
static public boolean gt(long x, long y){
return x > y;
}
static public boolean gte(long x, long y){
return x >= y;
}
static public boolean isPos(long x){
return x > 0;
}
static public boolean isNeg(long x){
return x < 0;
}
static public boolean isZero(long x){
return x == 0;
}
/*
static public class F{
static public float add(float x, float y){
return x + y;
}
static public float subtract(float x, float y){
return x - y;
}
static public float negate(float x){
return -x;
}
static public float inc(float x){
return x + 1;
}
static public float dec(float x){
return x - 1;
}
static public float multiply(float x, float y){
return x * y;
}
static public float divide(float x, float y){
return x / y;
}
static public boolean equiv(float x, float y){
return x == y;
}
static public boolean lt(float x, float y){
return x < y;
}
static public boolean lte(float x, float y){
return x <= y;
}
static public boolean gt(float x, float y){
return x > y;
}
static public boolean gte(float x, float y){
return x >= y;
}
static public boolean pos(float x){
return x > 0;
}
static public boolean neg(float x){
return x < 0;
}
static public boolean zero(float x){
return x == 0;
}
static public float aget(float[] xs, int i){
return xs[i];
}
static public float aset(float[] xs, int i, float v){
xs[i] = v;
return v;
}
static public int alength(float[] xs){
return xs.length;
}
static public float[] aclone(float[] xs){
return xs.clone();
}
static public float[] vec(int size, Object init){
float[] ret = new float[size];
if(init instanceof Number)
{
float f = ((Number) init).floatValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).floatValue();
}
return ret;
}
static public float[] vec(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new float[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = s.count();
float[] ret = new float[size];
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).intValue();
return ret;
}
}
static public float[] vsadd(float[] x, float y){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += y;
return xs;
}
static public float[] vssub(float[] x, float y){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= y;
return xs;
}
static public float[] vsdiv(float[] x, float y){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= y;
return xs;
}
static public float[] vsmul(float[] x, float y){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= y;
return xs;
}
static public float[] svdiv(float y, float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = y / xs[i];
return xs;
}
static public float[] vsmuladd(float[] x, float y, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + zs[i];
return xs;
}
static public float[] vsmulsub(float[] x, float y, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - zs[i];
return xs;
}
static public float[] vsmulsadd(float[] x, float y, float z){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + z;
return xs;
}
static public float[] vsmulssub(float[] x, float y, float z){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - z;
return xs;
}
static public float[] vabs(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.abs(xs[i]);
return xs;
}
static public float[] vnegabs(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -Math.abs(xs[i]);
return xs;
}
static public float[] vneg(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -xs[i];
return xs;
}
static public float[] vsqr(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= xs[i];
return xs;
}
static public float[] vsignedsqr(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= Math.abs(xs[i]);
return xs;
}
static public float[] vclip(float[] x, float low, float high){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
xs[i] = low;
else if(xs[i] > high)
xs[i] = high;
}
return xs;
}
static public IPersistentVector vclipcounts(float[] x, float low, float high){
final float[] xs = x.clone();
int lowc = 0;
int highc = 0;
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
{
++lowc;
xs[i] = low;
}
else if(xs[i] > high)
{
++highc;
xs[i] = high;
}
}
return RT.vector(xs, lowc, highc);
}
static public float[] vthresh(float[] x, float thresh, float otherwise){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < thresh)
xs[i] = otherwise;
}
return xs;
}
static public float[] vreverse(float[] x){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[xs.length - i - 1];
return xs;
}
static public float[] vrunningsum(float[] x){
final float[] xs = x.clone();
for(int i = 1; i < xs.length; i++)
xs[i] = xs[i - 1] + xs[i];
return xs;
}
static public float[] vsort(float[] x){
final float[] xs = x.clone();
Arrays.sort(xs);
return xs;
}
static public float vdot(float[] xs, float[] ys){
float ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * ys[i];
return ret;
}
static public float vmax(float[] xs){
if(xs.length == 0)
return 0;
float ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.max(ret, xs[i]);
return ret;
}
static public float vmin(float[] xs){
if(xs.length == 0)
return 0;
float ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.min(ret, xs[i]);
return ret;
}
static public float vmean(float[] xs){
if(xs.length == 0)
return 0;
return vsum(xs) / xs.length;
}
static public double vrms(float[] xs){
if(xs.length == 0)
return 0;
float ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * xs[i];
return Math.sqrt(ret / xs.length);
}
static public float vsum(float[] xs){
float ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i];
return ret;
}
static public boolean vequiv(float[] xs, float[] ys){
return Arrays.equals(xs, ys);
}
static public float[] vadd(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += ys[i];
return xs;
}
static public float[] vsub(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= ys[i];
return xs;
}
static public float[] vaddmul(float[] x, float[] ys, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * zs[i];
return xs;
}
static public float[] vsubmul(float[] x, float[] ys, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * zs[i];
return xs;
}
static public float[] vaddsmul(float[] x, float[] ys, float z){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * z;
return xs;
}
static public float[] vsubsmul(float[] x, float[] ys, float z){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * z;
return xs;
}
static public float[] vmulsadd(float[] x, float[] ys, float z){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + z;
return xs;
}
static public float[] vdiv(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= ys[i];
return xs;
}
static public float[] vmul(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= ys[i];
return xs;
}
static public float[] vmuladd(float[] x, float[] ys, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + zs[i];
return xs;
}
static public float[] vmulsub(float[] x, float[] ys, float[] zs){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) - zs[i];
return xs;
}
static public float[] vmax(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.max(xs[i], ys[i]);
return xs;
}
static public float[] vmin(float[] x, float[] ys){
final float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.min(xs[i], ys[i]);
return xs;
}
static public float[] vmap(IFn fn, float[] x) {
float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i])).floatValue();
return xs;
}
static public float[] vmap(IFn fn, float[] x, float[] ys) {
float[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i], ys[i])).floatValue();
return xs;
}
}
static public class D{
static public double add(double x, double y){
return x + y;
}
static public double subtract(double x, double y){
return x - y;
}
static public double negate(double x){
return -x;
}
static public double inc(double x){
return x + 1;
}
static public double dec(double x){
return x - 1;
}
static public double multiply(double x, double y){
return x * y;
}
static public double divide(double x, double y){
return x / y;
}
static public boolean equiv(double x, double y){
return x == y;
}
static public boolean lt(double x, double y){
return x < y;
}
static public boolean lte(double x, double y){
return x <= y;
}
static public boolean gt(double x, double y){
return x > y;
}
static public boolean gte(double x, double y){
return x >= y;
}
static public boolean pos(double x){
return x > 0;
}
static public boolean neg(double x){
return x < 0;
}
static public boolean zero(double x){
return x == 0;
}
static public double aget(double[] xs, int i){
return xs[i];
}
static public double aset(double[] xs, int i, double v){
xs[i] = v;
return v;
}
static public int alength(double[] xs){
return xs.length;
}
static public double[] aclone(double[] xs){
return xs.clone();
}
static public double[] vec(int size, Object init){
double[] ret = new double[size];
if(init instanceof Number)
{
double f = ((Number) init).doubleValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).doubleValue();
}
return ret;
}
static public double[] vec(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new double[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = s.count();
double[] ret = new double[size];
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).intValue();
return ret;
}
}
static public double[] vsadd(double[] x, double y){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += y;
return xs;
}
static public double[] vssub(double[] x, double y){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= y;
return xs;
}
static public double[] vsdiv(double[] x, double y){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= y;
return xs;
}
static public double[] vsmul(double[] x, double y){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= y;
return xs;
}
static public double[] svdiv(double y, double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = y / xs[i];
return xs;
}
static public double[] vsmuladd(double[] x, double y, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + zs[i];
return xs;
}
static public double[] vsmulsub(double[] x, double y, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - zs[i];
return xs;
}
static public double[] vsmulsadd(double[] x, double y, double z){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + z;
return xs;
}
static public double[] vsmulssub(double[] x, double y, double z){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - z;
return xs;
}
static public double[] vabs(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.abs(xs[i]);
return xs;
}
static public double[] vnegabs(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -Math.abs(xs[i]);
return xs;
}
static public double[] vneg(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -xs[i];
return xs;
}
static public double[] vsqr(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= xs[i];
return xs;
}
static public double[] vsignedsqr(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= Math.abs(xs[i]);
return xs;
}
static public double[] vclip(double[] x, double low, double high){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
xs[i] = low;
else if(xs[i] > high)
xs[i] = high;
}
return xs;
}
static public IPersistentVector vclipcounts(double[] x, double low, double high){
final double[] xs = x.clone();
int lowc = 0;
int highc = 0;
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
{
++lowc;
xs[i] = low;
}
else if(xs[i] > high)
{
++highc;
xs[i] = high;
}
}
return RT.vector(xs, lowc, highc);
}
static public double[] vthresh(double[] x, double thresh, double otherwise){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < thresh)
xs[i] = otherwise;
}
return xs;
}
static public double[] vreverse(double[] x){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[xs.length - i - 1];
return xs;
}
static public double[] vrunningsum(double[] x){
final double[] xs = x.clone();
for(int i = 1; i < xs.length; i++)
xs[i] = xs[i - 1] + xs[i];
return xs;
}
static public double[] vsort(double[] x){
final double[] xs = x.clone();
Arrays.sort(xs);
return xs;
}
static public double vdot(double[] xs, double[] ys){
double ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * ys[i];
return ret;
}
static public double vmax(double[] xs){
if(xs.length == 0)
return 0;
double ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.max(ret, xs[i]);
return ret;
}
static public double vmin(double[] xs){
if(xs.length == 0)
return 0;
double ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.min(ret, xs[i]);
return ret;
}
static public double vmean(double[] xs){
if(xs.length == 0)
return 0;
return vsum(xs) / xs.length;
}
static public double vrms(double[] xs){
if(xs.length == 0)
return 0;
double ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * xs[i];
return Math.sqrt(ret / xs.length);
}
static public double vsum(double[] xs){
double ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i];
return ret;
}
static public boolean vequiv(double[] xs, double[] ys){
return Arrays.equals(xs, ys);
}
static public double[] vadd(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += ys[i];
return xs;
}
static public double[] vsub(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= ys[i];
return xs;
}
static public double[] vaddmul(double[] x, double[] ys, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * zs[i];
return xs;
}
static public double[] vsubmul(double[] x, double[] ys, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * zs[i];
return xs;
}
static public double[] vaddsmul(double[] x, double[] ys, double z){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * z;
return xs;
}
static public double[] vsubsmul(double[] x, double[] ys, double z){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * z;
return xs;
}
static public double[] vmulsadd(double[] x, double[] ys, double z){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + z;
return xs;
}
static public double[] vdiv(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= ys[i];
return xs;
}
static public double[] vmul(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= ys[i];
return xs;
}
static public double[] vmuladd(double[] x, double[] ys, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + zs[i];
return xs;
}
static public double[] vmulsub(double[] x, double[] ys, double[] zs){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) - zs[i];
return xs;
}
static public double[] vmax(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.max(xs[i], ys[i]);
return xs;
}
static public double[] vmin(double[] x, double[] ys){
final double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.min(xs[i], ys[i]);
return xs;
}
static public double[] vmap(IFn fn, double[] x) {
double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i])).doubleValue();
return xs;
}
static public double[] vmap(IFn fn, double[] x, double[] ys) {
double[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i], ys[i])).doubleValue();
return xs;
}
}
static public class I{
static public int add(int x, int y){
return x + y;
}
static public int subtract(int x, int y){
return x - y;
}
static public int negate(int x){
return -x;
}
static public int inc(int x){
return x + 1;
}
static public int dec(int x){
return x - 1;
}
static public int multiply(int x, int y){
return x * y;
}
static public int divide(int x, int y){
return x / y;
}
static public boolean equiv(int x, int y){
return x == y;
}
static public boolean lt(int x, int y){
return x < y;
}
static public boolean lte(int x, int y){
return x <= y;
}
static public boolean gt(int x, int y){
return x > y;
}
static public boolean gte(int x, int y){
return x >= y;
}
static public boolean pos(int x){
return x > 0;
}
static public boolean neg(int x){
return x < 0;
}
static public boolean zero(int x){
return x == 0;
}
static public int aget(int[] xs, int i){
return xs[i];
}
static public int aset(int[] xs, int i, int v){
xs[i] = v;
return v;
}
static public int alength(int[] xs){
return xs.length;
}
static public int[] aclone(int[] xs){
return xs.clone();
}
static public int[] vec(int size, Object init){
int[] ret = new int[size];
if(init instanceof Number)
{
int f = ((Number) init).intValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).intValue();
}
return ret;
}
static public int[] vec(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new int[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = s.count();
int[] ret = new int[size];
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).intValue();
return ret;
}
}
static public int[] vsadd(int[] x, int y){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += y;
return xs;
}
static public int[] vssub(int[] x, int y){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= y;
return xs;
}
static public int[] vsdiv(int[] x, int y){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= y;
return xs;
}
static public int[] vsmul(int[] x, int y){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= y;
return xs;
}
static public int[] svdiv(int y, int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = y / xs[i];
return xs;
}
static public int[] vsmuladd(int[] x, int y, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + zs[i];
return xs;
}
static public int[] vsmulsub(int[] x, int y, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - zs[i];
return xs;
}
static public int[] vsmulsadd(int[] x, int y, int z){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + z;
return xs;
}
static public int[] vsmulssub(int[] x, int y, int z){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - z;
return xs;
}
static public int[] vabs(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.abs(xs[i]);
return xs;
}
static public int[] vnegabs(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -Math.abs(xs[i]);
return xs;
}
static public int[] vneg(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -xs[i];
return xs;
}
static public int[] vsqr(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= xs[i];
return xs;
}
static public int[] vsignedsqr(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= Math.abs(xs[i]);
return xs;
}
static public int[] vclip(int[] x, int low, int high){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
xs[i] = low;
else if(xs[i] > high)
xs[i] = high;
}
return xs;
}
static public IPersistentVector vclipcounts(int[] x, int low, int high){
final int[] xs = x.clone();
int lowc = 0;
int highc = 0;
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
{
++lowc;
xs[i] = low;
}
else if(xs[i] > high)
{
++highc;
xs[i] = high;
}
}
return RT.vector(xs, lowc, highc);
}
static public int[] vthresh(int[] x, int thresh, int otherwise){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < thresh)
xs[i] = otherwise;
}
return xs;
}
static public int[] vreverse(int[] x){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[xs.length - i - 1];
return xs;
}
static public int[] vrunningsum(int[] x){
final int[] xs = x.clone();
for(int i = 1; i < xs.length; i++)
xs[i] = xs[i - 1] + xs[i];
return xs;
}
static public int[] vsort(int[] x){
final int[] xs = x.clone();
Arrays.sort(xs);
return xs;
}
static public int vdot(int[] xs, int[] ys){
int ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * ys[i];
return ret;
}
static public int vmax(int[] xs){
if(xs.length == 0)
return 0;
int ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.max(ret, xs[i]);
return ret;
}
static public int vmin(int[] xs){
if(xs.length == 0)
return 0;
int ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.min(ret, xs[i]);
return ret;
}
static public double vmean(int[] xs){
if(xs.length == 0)
return 0;
return vsum(xs) / (double) xs.length;
}
static public double vrms(int[] xs){
if(xs.length == 0)
return 0;
int ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * xs[i];
return Math.sqrt(ret / (double) xs.length);
}
static public int vsum(int[] xs){
int ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i];
return ret;
}
static public boolean vequiv(int[] xs, int[] ys){
return Arrays.equals(xs, ys);
}
static public int[] vadd(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += ys[i];
return xs;
}
static public int[] vsub(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= ys[i];
return xs;
}
static public int[] vaddmul(int[] x, int[] ys, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * zs[i];
return xs;
}
static public int[] vsubmul(int[] x, int[] ys, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * zs[i];
return xs;
}
static public int[] vaddsmul(int[] x, int[] ys, int z){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * z;
return xs;
}
static public int[] vsubsmul(int[] x, int[] ys, int z){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * z;
return xs;
}
static public int[] vmulsadd(int[] x, int[] ys, int z){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + z;
return xs;
}
static public int[] vdiv(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= ys[i];
return xs;
}
static public int[] vmul(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= ys[i];
return xs;
}
static public int[] vmuladd(int[] x, int[] ys, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + zs[i];
return xs;
}
static public int[] vmulsub(int[] x, int[] ys, int[] zs){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) - zs[i];
return xs;
}
static public int[] vmax(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.max(xs[i], ys[i]);
return xs;
}
static public int[] vmin(int[] x, int[] ys){
final int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.min(xs[i], ys[i]);
return xs;
}
static public int[] vmap(IFn fn, int[] x) {
int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i])).intValue();
return xs;
}
static public int[] vmap(IFn fn, int[] x, int[] ys) {
int[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i], ys[i])).intValue();
return xs;
}
}
static public class L{
static public long add(long x, long y){
return x + y;
}
static public long subtract(long x, long y){
return x - y;
}
static public long negate(long x){
return -x;
}
static public long inc(long x){
return x + 1;
}
static public long dec(long x){
return x - 1;
}
static public long multiply(long x, long y){
return x * y;
}
static public long divide(long x, long y){
return x / y;
}
static public boolean equiv(long x, long y){
return x == y;
}
static public boolean lt(long x, long y){
return x < y;
}
static public boolean lte(long x, long y){
return x <= y;
}
static public boolean gt(long x, long y){
return x > y;
}
static public boolean gte(long x, long y){
return x >= y;
}
static public boolean pos(long x){
return x > 0;
}
static public boolean neg(long x){
return x < 0;
}
static public boolean zero(long x){
return x == 0;
}
static public long aget(long[] xs, int i){
return xs[i];
}
static public long aset(long[] xs, int i, long v){
xs[i] = v;
return v;
}
static public int alength(long[] xs){
return xs.length;
}
static public long[] aclone(long[] xs){
return xs.clone();
}
static public long[] vec(int size, Object init){
long[] ret = new long[size];
if(init instanceof Number)
{
long f = ((Number) init).longValue();
for(int i = 0; i < ret.length; i++)
ret[i] = f;
}
else
{
ISeq s = RT.seq(init);
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).longValue();
}
return ret;
}
static public long[] vec(Object sizeOrSeq){
if(sizeOrSeq instanceof Number)
return new long[((Number) sizeOrSeq).intValue()];
else
{
ISeq s = RT.seq(sizeOrSeq);
int size = s.count();
long[] ret = new long[size];
for(int i = 0; i < size && s != null; i++, s = s.rest())
ret[i] = ((Number) s.first()).intValue();
return ret;
}
}
static public long[] vsadd(long[] x, long y){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += y;
return xs;
}
static public long[] vssub(long[] x, long y){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= y;
return xs;
}
static public long[] vsdiv(long[] x, long y){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= y;
return xs;
}
static public long[] vsmul(long[] x, long y){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= y;
return xs;
}
static public long[] svdiv(long y, long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = y / xs[i];
return xs;
}
static public long[] vsmuladd(long[] x, long y, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + zs[i];
return xs;
}
static public long[] vsmulsub(long[] x, long y, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - zs[i];
return xs;
}
static public long[] vsmulsadd(long[] x, long y, long z){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y + z;
return xs;
}
static public long[] vsmulssub(long[] x, long y, long z){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[i] * y - z;
return xs;
}
static public long[] vabs(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.abs(xs[i]);
return xs;
}
static public long[] vnegabs(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -Math.abs(xs[i]);
return xs;
}
static public long[] vneg(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = -xs[i];
return xs;
}
static public long[] vsqr(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= xs[i];
return xs;
}
static public long[] vsignedsqr(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= Math.abs(xs[i]);
return xs;
}
static public long[] vclip(long[] x, long low, long high){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
xs[i] = low;
else if(xs[i] > high)
xs[i] = high;
}
return xs;
}
static public IPersistentVector vclipcounts(long[] x, long low, long high){
final long[] xs = x.clone();
int lowc = 0;
int highc = 0;
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < low)
{
++lowc;
xs[i] = low;
}
else if(xs[i] > high)
{
++highc;
xs[i] = high;
}
}
return RT.vector(xs, lowc, highc);
}
static public long[] vthresh(long[] x, long thresh, long otherwise){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
{
if(xs[i] < thresh)
xs[i] = otherwise;
}
return xs;
}
static public long[] vreverse(long[] x){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = xs[xs.length - i - 1];
return xs;
}
static public long[] vrunningsum(long[] x){
final long[] xs = x.clone();
for(int i = 1; i < xs.length; i++)
xs[i] = xs[i - 1] + xs[i];
return xs;
}
static public long[] vsort(long[] x){
final long[] xs = x.clone();
Arrays.sort(xs);
return xs;
}
static public long vdot(long[] xs, long[] ys){
long ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * ys[i];
return ret;
}
static public long vmax(long[] xs){
if(xs.length == 0)
return 0;
long ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.max(ret, xs[i]);
return ret;
}
static public long vmin(long[] xs){
if(xs.length == 0)
return 0;
long ret = xs[0];
for(int i = 0; i < xs.length; i++)
ret = Math.min(ret, xs[i]);
return ret;
}
static public double vmean(long[] xs){
if(xs.length == 0)
return 0;
return vsum(xs) / (double) xs.length;
}
static public double vrms(long[] xs){
if(xs.length == 0)
return 0;
long ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i] * xs[i];
return Math.sqrt(ret / (double) xs.length);
}
static public long vsum(long[] xs){
long ret = 0;
for(int i = 0; i < xs.length; i++)
ret += xs[i];
return ret;
}
static public boolean vequiv(long[] xs, long[] ys){
return Arrays.equals(xs, ys);
}
static public long[] vadd(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] += ys[i];
return xs;
}
static public long[] vsub(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] -= ys[i];
return xs;
}
static public long[] vaddmul(long[] x, long[] ys, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * zs[i];
return xs;
}
static public long[] vsubmul(long[] x, long[] ys, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * zs[i];
return xs;
}
static public long[] vaddsmul(long[] x, long[] ys, long z){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] + ys[i]) * z;
return xs;
}
static public long[] vsubsmul(long[] x, long[] ys, long z){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] - ys[i]) * z;
return xs;
}
static public long[] vmulsadd(long[] x, long[] ys, long z){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + z;
return xs;
}
static public long[] vdiv(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] /= ys[i];
return xs;
}
static public long[] vmul(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] *= ys[i];
return xs;
}
static public long[] vmuladd(long[] x, long[] ys, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) + zs[i];
return xs;
}
static public long[] vmulsub(long[] x, long[] ys, long[] zs){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = (xs[i] * ys[i]) - zs[i];
return xs;
}
static public long[] vmax(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.max(xs[i], ys[i]);
return xs;
}
static public long[] vmin(long[] x, long[] ys){
final long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = Math.min(xs[i], ys[i]);
return xs;
}
static public long[] vmap(IFn fn, long[] x) {
long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i])).longValue();
return xs;
}
static public long[] vmap(IFn fn, long[] x, long[] ys) {
long[] xs = x.clone();
for(int i = 0; i < xs.length; i++)
xs[i] = ((Number) fn.invoke(xs[i], ys[i])).longValue();
return xs;
}
}
*/
//overload resolution
//*
static public Number add(long x, Object y){
return add((Object)x,y);
}
static public Number add(Object x, long y){
return add(x,(Object)y);
}
static public Number addP(long x, Object y){
return addP((Object)x,y);
}
static public Number addP(Object x, long y){
return addP(x,(Object)y);
}
static public double add(double x, Object y){
return add(x,((Number)y).doubleValue());
}
static public double add(Object x, double y){
return add(((Number)x).doubleValue(),y);
}
static public double add(double x, long y){
return x + y;
}
static public double add(long x, double y){
return x + y;
}
static public double addP(double x, Object y){
return addP(x,((Number)y).doubleValue());
}
static public double addP(Object x, double y){
return addP(((Number)x).doubleValue(),y);
}
static public double addP(double x, long y){
return x + y;
}
static public double addP(long x, double y){
return x + y;
}
static public Number minus(long x, Object y){
return minus((Object)x,y);
}
static public Number minus(Object x, long y){
return minus(x,(Object)y);
}
static public Number minusP(long x, Object y){
return minusP((Object)x,y);
}
static public Number minusP(Object x, long y){
return minusP(x,(Object)y);
}
static public double minus(double x, Object y){
return minus(x,((Number)y).doubleValue());
}
static public double minus(Object x, double y){
return minus(((Number)x).doubleValue(),y);
}
static public double minus(double x, long y){
return x - y;
}
static public double minus(long x, double y){
return x - y;
}
static public double minusP(double x, Object y){
return minus(x,((Number)y).doubleValue());
}
static public double minusP(Object x, double y){
return minus(((Number)x).doubleValue(),y);
}
static public double minusP(double x, long y){
return x - y;
}
static public double minusP(long x, double y){
return x - y;
}
static public Number multiply(long x, Object y){
return multiply((Object)x,y);
}
static public Number multiply(Object x, long y){
return multiply(x,(Object)y);
}
static public Number multiplyP(long x, Object y){
return multiplyP((Object)x,y);
}
static public Number multiplyP(Object x, long y){
return multiplyP(x,(Object)y);
}
static public double multiply(double x, Object y){
return multiply(x,((Number)y).doubleValue());
}
static public double multiply(Object x, double y){
return multiply(((Number)x).doubleValue(),y);
}
static public double multiply(double x, long y){
return x * y;
}
static public double multiply(long x, double y){
return x * y;
}
static public double multiplyP(double x, Object y){
return multiplyP(x,((Number)y).doubleValue());
}
static public double multiplyP(Object x, double y){
return multiplyP(((Number)x).doubleValue(),y);
}
static public double multiplyP(double x, long y){
return x * y;
}
static public double multiplyP(long x, double y){
return x * y;
}
static public Number divide(long x, Object y){
return divide((Object)x,y);
}
static public Number divide(Object x, long y){
return divide(x,(Object)y);
}
static public double divide(double x, Object y){
return x / ((Number)y).doubleValue();
}
static public double divide(Object x, double y){
return ((Number)x).doubleValue() / y;
}
static public double divide(double x, long y){
return x / y;
}
static public double divide(long x, double y){
return x / y;
}
static public Number divide(long x, long y){
return divide((Number)x, (Number)y);
}
static public boolean lt(long x, Object y){
return lt((Object)x,y);
}
static public boolean lt(Object x, long y){
return lt(x,(Object)y);
}
static public boolean lt(double x, Object y){
return x < ((Number)y).doubleValue();
}
static public boolean lt(Object x, double y){
return ((Number)x).doubleValue() < y;
}
static public boolean lt(double x, long y){
return x < y;
}
static public boolean lt(long x, double y){
return x < y;
}
static public boolean lte(long x, Object y){
return lte((Object)x,y);
}
static public boolean lte(Object x, long y){
return lte(x,(Object)y);
}
static public boolean lte(double x, Object y){
return x <= ((Number)y).doubleValue();
}
static public boolean lte(Object x, double y){
return ((Number)x).doubleValue() <= y;
}
static public boolean lte(double x, long y){
return x <= y;
}
static public boolean lte(long x, double y){
return x <= y;
}
static public boolean gt(long x, Object y){
return gt((Object)x,y);
}
static public boolean gt(Object x, long y){
return gt(x,(Object)y);
}
static public boolean gt(double x, Object y){
return x > ((Number)y).doubleValue();
}
static public boolean gt(Object x, double y){
return ((Number)x).doubleValue() > y;
}
static public boolean gt(double x, long y){
return x > y;
}
static public boolean gt(long x, double y){
return x > y;
}
static public boolean gte(long x, Object y){
return gte((Object)x,y);
}
static public boolean gte(Object x, long y){
return gte(x,(Object)y);
}
static public boolean gte(double x, Object y){
return x >= ((Number)y).doubleValue();
}
static public boolean gte(Object x, double y){
return ((Number)x).doubleValue() >= y;
}
static public boolean gte(double x, long y){
return x >= y;
}
static public boolean gte(long x, double y){
return x >= y;
}
static public boolean equiv(long x, Object y){
return equiv((Object)x,y);
}
static public boolean equiv(Object x, long y){
return equiv(x,(Object)y);
}
static public boolean equiv(double x, Object y){
return x == ((Number)y).doubleValue();
}
static public boolean equiv(Object x, double y){
return ((Number)x).doubleValue() == y;
}
static public boolean equiv(double x, long y){
return x == y;
}
static public boolean equiv(long x, double y){
return x == y;
}
static boolean isNaN(Object x){
return (x instanceof Double) && ((Double)x).isNaN()
|| (x instanceof Float) && ((Float)x).isNaN();
}
static public double max(double x, double y){
return Math.max(x, y);
}
static public Object max(double x, long y){
if(Double.isNaN(x)){
return x;
}
if(x > y){
return x;
} else {
return y;
}
}
static public Object max(double x, Object y){
if(Double.isNaN(x)){
return x;
} else if(isNaN(y)){
return y;
}
if(x > ((Number)y).doubleValue()){
return x;
} else {
return y;
}
}
static public Object max(long x, double y){
if(Double.isNaN(y)){
return y;
}
if(x > y){
return x;
} else {
return y;
}
}
static public long max(long x, long y){
if(x > y) {
return x;
} else {
return y;
}
}
static public Object max(long x, Object y){
if(isNaN(y)){
return y;
}
if(gt(x,y)){
return x;
} else {
return y;
}
}
static public Object max(Object x, long y){
if(isNaN(x)){
return x;
}
if(gt(x,y)){
return x;
} else {
return y;
}
}
static public Object max(Object x, double y){
if (isNaN(x)){
return x;
} else if(Double.isNaN(y)){
return y;
}
if(((Number)x).doubleValue() > y){
return x;
} else {
return y;
}
}
static public Object max(Object x, Object y){
if(isNaN(x)){
return x;
} else if(isNaN(y)){
return y;
}
if(gt(x, y)) {
return x;
} else {
return y;
}
}
static public double min(double x, double y){
return Math.min(x, y);
}
static public Object min(double x, long y){
if (Double.isNaN(x)){
return x;
}
if(x < y){
return x;
} else {
return y;
}
}
static public Object min(double x, Object y){
if(Double.isNaN(x)){
return x;
} else if(isNaN(y)){
return y;
}
if(x < ((Number)y).doubleValue()){
return x;
} else {
return y;
}
}
static public Object min(long x, double y){
if(Double.isNaN(y)){
return y;
}
if(x < y){
return x;
} else {
return y;
}
}
static public long min(long x, long y){
if(x < y) {
return x;
} else {
return y;
}
}
static public Object min(long x, Object y){
if(isNaN(y)){
return y;
}
if(lt(x,y)){
return x;
} else {
return y;
}
}
static public Object min(Object x, long y){
if(isNaN(x)){
return x;
}
if(lt(x,y)){
return x;
} else {
return y;
}
}
static public Object min(Object x, double y){
if(isNaN(x)){
return x;
} else if(Double.isNaN(y)){
return y;
}
if(((Number)x).doubleValue() < y){
return x;
} else {
return y;
}
}
static public Object min(Object x, Object y){
if (isNaN(x)){
return x;
} else if(isNaN(y)){
return y;
}
if(lt(x,y)) {
return x;
} else {
return y;
}
}
}