use of org.hipparchus.complex.Complex in project symja_android_library by axkr.
the class ZetaJS method complexAverage.
public static Complex complexAverage(java.util.function.DoubleFunction<Complex> f, double x) {
double offset = 1e-5;
Complex arg1 = f.apply(x + offset);
Complex arg2 = f.apply(x - offset);
return arg1.add(arg2).divide(2.0);
}
use of org.hipparchus.complex.Complex in project symja_android_library by axkr.
the class ZetaJS method summation.
public static Complex summation(java.util.function.Function<Complex, Complex> f, double a, double b, int iterationLimit) {
Complex s = Complex.ZERO;
int counter = 0;
for (double i = a; i <= b; i++) {
if (counter++ > iterationLimit && iterationLimit > 0) {
IterationLimitExceeded.throwIt(counter, S.Sum);
}
s = s.add(f.apply(new Complex(i)));
}
return s;
}
use of org.hipparchus.complex.Complex in project symja_android_library by axkr.
the class ZetaJS method polyLog.
public static Complex polyLog(final double n, final double x) {
if (F.isEqual(x, 1.0)) {
return new Complex(zeta(n));
}
if (F.isEqual(x, -1.0)) {
return dirichletEta(n).negate();
}
double oneMinusX = 1.0 - x;
if (F.isEqual(n, 1.0)) {
return new Complex(-Math.log(oneMinusX));
}
if (F.isEqual(n, 0.0)) {
return new Complex(x / oneMinusX);
}
if (F.isEqual(n, -1.0)) {
return new Complex(x / (oneMinusX * oneMinusX));
}
if (Math.abs(x) >= 1.0) {
if (F.isNumIntValue(n) && n > 0.0) {
final int nInt = NumberUtil.toInt(n);
Complex twoPiI = new Complex(0, 2 * Math.PI);
// Crandall, Note on Fast Polylogarithm Computation
Complex t1 = polyLog(n, 1 / x).multiply(Math.pow(-1.0, nInt));
Complex t2 = twoPiI.pow(nInt).divide(GammaJS.factorialInt(n)).multiply(bernoulli(nInt, new Complex(x).log().divide(twoPiI)));
// just for test
Complex y = new Complex(x);
Complex t3 = y.getImaginary() < 0.0 || (F.isZero(y.getImaginary()) && y.getReal() >= 1.0) ? twoPiI.multiply(Math.pow(Math.log(x), n - 1) / GammaJS.factorialInt(n - 1)) : Complex.ZERO;
Complex result = t1.add(t2).add(t3).negate();
// real on negative real axis
if (x < 0) {
return new Complex(result.getReal());
}
return result;
}
return polyLog(new Complex(n), new Complex(x));
}
double s = x;
double p = 1;
int i = 1;
int iterationLimit = EvalEngine.get().getIterationLimit();
while (Math.abs(p) > Config.SPECIAL_FUNCTIONS_TOLERANCE) {
if (i++ > iterationLimit && iterationLimit > 0) {
IterationLimitExceeded.throwIt(i, S.PolyLog);
}
p = Math.pow(x, i) / Math.pow(i, n);
s += p;
}
return new Complex(s);
}
use of org.hipparchus.complex.Complex in project symja_android_library by axkr.
the class ZetaJS method polyLog.
public static Complex polyLog(final Complex n, final Complex x) {
if (x.equals(Complex.ONE)) {
return zeta(n);
}
if (x.equals(Complex.MINUS_ONE)) {
return dirichletEta(n).negate();
}
if (n.equals(Complex.ONE)) {
return Complex.ONE.subtract(x).log().negate();
}
if (n.equals(Complex.ZERO)) {
return x.divide(Complex.ONE.subtract(x));
}
if (n.equals(Complex.MINUS_ONE)) {
return x.divide(Complex.ONE.subtract(x).multiply(Complex.ONE.subtract(x)));
}
if (x.norm() >= 1.0) {
if (F.isZero(n.getImaginary()) && F.isNumIntValue(n.getReal()) && n.getReal() > 0.0) {
final int nInt = NumberUtil.toInt(n.getReal());
Complex twoPiI = new Complex(0, 2 * Math.PI);
// Crandall, Note on Fast Polylogarithm Computation
Complex t1 = polyLog(n, x.reciprocal()).multiply(Math.pow(-1.0, nInt));
Complex t2 = twoPiI.pow(nInt).divide(GammaJS.factorialInt(nInt)).multiply(bernoulli(nInt, x.log().divide(twoPiI)));
// Complex y = x; // just for test
Complex t3 = x.getImaginary() < 0.0 || (F.isZero(x.getImaginary()) && x.getReal() >= 1.0) ? twoPiI.multiply(x.log().pow(nInt - 1).divide(GammaJS.factorialInt(nInt - 1))) : Complex.ZERO;
return t1.add(t2).add(t3).negate();
// return complexAverage(nInt -> polyLog(nInt, x), n);
}
Complex v = Complex.ONE.subtract(n);
Complex I = Complex.I;
Complex L = x.negate().log().divide(new Complex(0, 2.0 * Math.PI));
Complex z1 = I.pow(v).multiply(hurwitzZeta(v, L.add(0.5)));
Complex z2 = I.pow(v.negate()).multiply(hurwitzZeta(v, new Complex(0.5).subtract(L)));
return GammaJS.gamma(v).multiply(new Complex(2.0 * Math.PI).pow(v.negate())).multiply(z1.add(z2));
}
Complex s = x;
// complex(1);
Complex p = Complex.ONE;
int i = 1;
int iterationLimit = EvalEngine.get().getIterationLimit();
while (Math.abs(p.getReal()) > Config.SPECIAL_FUNCTIONS_TOLERANCE || Math.abs(p.getImaginary()) > Config.SPECIAL_FUNCTIONS_TOLERANCE) {
if (i++ > iterationLimit && iterationLimit > 0) {
IterationLimitExceeded.throwIt(i, S.PolyLog);
}
p = x.pow(i).divide(new Complex(i).pow(n));
s = s.add(p);
}
return s;
}
Aggregations