Package r.builtins

Source Code of r.builtins.Fft

package r.builtins;

import r.data.*;
import r.data.RComplex.*;
import r.errors.*;
import r.ext.*;
import r.nodes.ast.*;
import r.nodes.exec.*;
import r.runtime.*;

// main/fourier.c
// appl/fft.c
final class Fft extends CallFactory {

    static final CallFactory _ = new Fft("fft", new String[]{"z", "inverse"}, new String[] {"z"});

    private Fft(String name, String[] params, String[] required) {
        super(name, params, required);
    }

    public static boolean parseInverse(RAny arg) {
        RLogical l = arg.asLogical();
        if (l.getLogical(0) == RLogical.TRUE) {
            return true;
        }
        return false;
    }

    @Override public RNode create(ASTNode call, RSymbol[] names, RNode[] exprs) {
        ArgumentInfo ia = check(call, names, exprs);
        final int zPosition = ia.position("z");
        final int inversePosition = ia.position("inverse");

        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) {
                        nspn *= n;
                        n = d;
                        nseg /= n;
                        GNUR.fft_factor(d, ap_maxf, ap_maxp); // this has a necessary side effect, see comments in appl/fft.c
                        GNUR.fft_work(z, nseg, n, nspn, ap_inv, ap_work, ap_iwork);
                    }
                }
                return res;
            }
        };
    }

}
TOP

Related Classes of r.builtins.Fft

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.