return new Builtin(call, names, exprs) {
@Override public RAny doBuiltIn(Frame frame, RAny[] args) {
// LICENSE: transcribed code from GNU R, which is licensed under GPL
RAny zarg = args[zPosition];
RComplex res;
if (zarg instanceof RDouble || zarg instanceof RInt || zarg instanceof RLogical) {
res = zarg.asComplex().materialize(); // this will always copy
} else if (zarg instanceof RComplex) {
if (zarg.isTemporary()) {
res = (RComplex) zarg;
} else {
res = RComplexFactory.copy((RComplex) zarg);
}
} else {
throw RError.getNonNumericArgument(ast);
}
if (res.size() <= 1) {
return res;
}
double[] z = res.getContent();
boolean inverse = inversePosition == -1 ? false : parseInverse(args[inversePosition]);
int ap_inv = inverse ? 2 : -2;
int[] ap_maxf = new int[1];
int[] ap_maxp = new int[1];
int[] dims = res.dimensions();
if (dims == null) {
int n = res.size();
GNUR.fft_factor(n, ap_maxf, ap_maxp);
int maxp = ap_maxp[0];
int maxf = ap_maxf[0];
if (maxf == 0) {
throw RError.getFFTFactorization(ast);
}
double[] ap_work = new double[4 * maxf];
int[] ap_iwork = new int[maxp];
GNUR.fft_work(z, 1, n, 1, ap_inv, ap_work, ap_iwork);
return res;
}
int maxmaxf = 1;
int maxmaxp = 1;
int ndims = dims.length;
for (int i = 0; i < ndims; i++) {
int d = dims[i];
if (d > 1) {
GNUR.fft_factor(d, ap_maxf, ap_maxp);
int maxp = ap_maxp[0];
int maxf = ap_maxf[0];
if (maxf == 0) {
throw RError.getFFTFactorization(ast);
}
if (maxf > maxmaxf) {
maxmaxf = maxf;
}
if (maxp > maxmaxp) {
maxmaxp = maxp;
}
}
}
double[] ap_work = new double[4 * maxmaxf];
int[] ap_iwork = new int[maxmaxp];
int nseg = res.size();
int n = 1;
int nspn = 1;
for (int i = 0; i < ndims; i++) {
int d = dims[i];
if (d > 1) {