@Override
public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
/* polylogarithm by dark-beam */
// approx (very good) of Li[n](z) for n > 1
double vv = pAmount;
Complex z = new Complex(pAffineTP.x, pAffineTP.y);
z.Pow(zpow);
z.Save();
if (z.Mag2() > 250000.0 || N >= 20) { // no convergence, or N too big... When N is big then Li tends to z
pVarTP.x += vv * z.re;
pVarTP.y += vv * z.im;
return;
}
Complex LiN = new Complex();
int i;
Complex T = new Complex();
Complex zPl1 = new Complex(z);
if (z.Mag2() < 0.07) { // normal series. Li = sum((z^k)/(k^n))
for (i = 1; i < 20; i++) {
T.Copy(new Complex(pow(i, N)));
T.DivR(z);
LiN.Add(T);
z.NextPow();
}
pVarTP.x += vv * LiN.re;
pVarTP.y += vv * LiN.im;
return;
}
// Crandall method (very simple and fast!) that uses Erdelyi series
// from now on we will use ln(z) only so switch to it
z.Log();
z.Save();
z.One();
for (i = 0; i < 20; i++) {
double zee = Riem.Z((int) N - i);
if (zee != 0.0) {
T.Copy(z);
T.Scale(zee / (cern.jet.math.Arithmetic.longFactorial(i)));
LiN.Add(T);
}
if (i == N - 1) {
zPl1.Copy(z);
}
z.NextPow();
}
z.Restore(); // back to log(z) again...
z.Neg();