//
// FFT.java
//
/*
VisAD system for interactive analysis and visualization of numerical
data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/
package visad.math;
import visad.*;
import java.rmi.*;
/**
FFT is the VisAD class for Fourier Transforms, using
the Fast Fourier Transform when the domain length is
a power of two.
*/
public class FFT {
/**
* for use by SpreadSheet only - ordinary applications
* should use other method signatures;
* invoke in SpreadSheet by:
* link(visad.math.FFT.forwardFT(A1))
*/
public static FlatField forwardFT(Data[] datums) {
FlatField result = null;
try {
result = fourierTransform((Field) datums[0], true);
}
catch (VisADException e) {
e.printStackTrace();
}
catch (RemoteException e) {
e.printStackTrace();
}
if (result == null) {
System.out.println("result == null");
}
return result;
}
/**
* for use by SpreadSheet only - ordinary applications
* should use other method signatures;
* invoke in SpreadSheet by:
* link(visad.math.FFT.backwardFT(A1))
*/
public static FlatField backwardFT(Data[] datums) {
FlatField result = null;
try {
result = fourierTransform((Field) datums[0], false);
}
catch (VisADException e) {
e.printStackTrace();
}
catch (RemoteException e) {
e.printStackTrace();
}
if (result == null) {
System.out.println("result == null");
}
return result;
}
/**
* return Fourier Transform of field, use FFT if domain dimension(s)
* are powers of 2
* @param field Field with domain dimension = 1 (1-D FT) or 2 (2-D FT)
* and 1 (real part) or 2 (real & imaginary) range RealTypes
* @param forward true for forward and false for backward
* @return Fourier transform of field
* @throws VisADException a VisAD error occurred
* @throws RemoteException an RMI error occurred
*/
public static FlatField fourierTransform(Field field, boolean forward)
throws VisADException, RemoteException {
return fourierTransform(field, forward, null, null, null, null, null);
}
/**
* return Fourier Transform of field, use FFT if domain dimension(s)
* are powers of 2
* @param field Field with domain dimension = 1 (1-D FT) or 2 (2-D FT)
* and 1 (real part) or 2 (real & imaginary) range RealTypes
* @param forward true for forward and false for backward
* @param ftype use for return Field (may be null)
* @param domain_set use for return Field (may be null)
* @param range_coord_sys use for return Field (may be null)
* @param range_sets use for return Field (may be null)
* @param units use for return Field (may be null)
* @return Fourier transform of field
* @throws VisADException a VisAD error occurred
* @throws RemoteException an RMI error occurred
*/
public static FlatField fourierTransform(Field field, boolean forward,
FunctionType ftype, GriddedSet domain_set,
CoordinateSystem range_coord_sys,
Set[] range_sets, Unit[] units)
throws VisADException, RemoteException {
if (field == null) return null;
FunctionType type = (FunctionType) field.getType();
RealTupleType dtype = type.getDomain();
int ddim = dtype.getDimension();
MathType rtype = type.getRange();
RealType[] realComponents = null;
int rdim = 0;
if (rtype instanceof RealType) {
realComponents = new RealType[] {(RealType) rtype};
rdim = 1;
}
else if (rtype instanceof RealTupleType) {
realComponents = ((RealTupleType) rtype).getRealComponents();
rdim = realComponents.length;
}
else {
throw new FieldException("bad range type " + rtype);
}
if (ddim != 1 && ddim != 2) {
throw new FieldException("bad domain dimension " + dtype);
}
if (rdim != 1 && rdim != 2) {
throw new FieldException("bad range dimension " + rtype);
}
if (units == null || units.length == 0) {
units = new Unit[] {null, null};
}
else if (units.length == 1) {
units = new Unit[] {units[0], null};
}
if (ftype == null) {
RealType[] newReals = new RealType[2];
if (rdim == 2) {
if (forward) {
String name = realComponents[0].getName() + "_FT";
newReals[0] = RealType.getRealType(name, units[0], null);
name = realComponents[1].getName() + "_FT";
newReals[1] = RealType.getRealType(name, units[1], null);
}
else {
String name = realComponents[0].getName();
if (name.endsWith("_FT")) {
name = name.substring(0, name.length() - 3);
}
else if (name.endsWith("_FT_real")) {
name = name.substring(0, name.length() - 8);
}
else if (name.endsWith("_RFT_real")) {
name = name.substring(0, name.length() - 9);
}
newReals[0] = RealType.getRealType(name, units[0], null);
name = realComponents[1].getName();
if (name.endsWith("_FT")) {
name = name.substring(0, name.length() - 3);
}
else if (name.endsWith("_FT_imag")) {
name = name.substring(0, name.length() - 8) + "_imag";
}
else if (name.endsWith("_RFT_imag")) {
name = name.substring(0, name.length() - 9) + "_imag";
}
newReals[1] = RealType.getRealType(name, units[1], null);
}
}
else { // rdim == 1
if (forward) {
String name = realComponents[0].getName() + "_FT";
newReals[0] = RealType.getRealType(name + "_real", units[0], null);
newReals[1] = RealType.getRealType(name + "_imag", units[1], null);
}
else {
String name = realComponents[0].getName() + "_RFT";
newReals[0] = RealType.getRealType(name + "_real", units[0], null);
newReals[1] = RealType.getRealType(name + "_imag", units[1], null);
}
}
RealTupleType rftype = new RealTupleType(newReals, range_coord_sys, null);
ftype = new FunctionType(dtype, rftype);
}
else { // ftype != null
RealTupleType dftype = ftype.getDomain();
if (dftype.getDimension() != ddim) {
throw new FieldException("bad domain dimension " + dftype);
}
MathType rftype = ftype.getRange();
if (!(rftype instanceof RealTupleType) ||
((RealTupleType) rftype).getDimension() != 2) {
throw new FieldException("bad range type " + rftype);
}
}
Set field_set = field.getDomainSet();
if (!(field_set instanceof GriddedSet)) {
throw new FieldException("field domain set must be Gridded2DSet " + field_set);
}
int[] field_lens = ((GriddedSet) field_set).getLengths();
if (domain_set == null) {
domain_set = (GriddedSet) field_set;
}
else {
if (domain_set.getDimension() != ddim) {
throw new FieldException("domain_set bad dimension " + domain_set);
}
int[] domain_lens = domain_set.getLengths();
for (int i=0; i n) {
fft = false;
}
}
if (fft) return FFT1D(x, forward);
float[][] temp = new float[2][n];
float angle = (float) (-2.0 * Math.PI / n);
if (!forward) angle = -angle;
for (int i=0; i n) {
throw new FieldException("x length must be power of 2");
}
}
n2 = n/2;
float[][] temp = new float[2][n2];
float angle = (float) (-2.0 * Math.PI / n);
if (!forward) angle = -angle;
for (int i=0; i n) {
fft = false;
}
}
if (fft) return FFT1D(x, forward);
double[][] temp = new double[2][n];
double angle = -2.0 * Math.PI / n;
if (!forward) angle = -angle;
for (int i=0; i n) {
throw new FieldException("x length must be power of 2");
}
}
n2 = n/2;
double[][] temp = new double[2][n2];
double angle = (double) (-2.0 * Math.PI / n);
if (!forward) angle = -angle;
for (int i=0; i 0 && args[0].startsWith("AREA")) {
DisplayImpl display1 = new DisplayImplJ3D("display");
DisplayImpl display1 = new DisplayImplJ3D("display");
AreaAdapter areaAdapter = new AreaAdapter(args[0]);
Data image = areaAdapter.getData();
FunctionType imageFunctionType = (FunctionType) image.getType();
RealType radianceType = (RealType)
((RealTupleType) imageFunctionType.getRange()).getComponent(0);
display.addMap(new ScalarMap(RealType.Latitude, Display.Latitude));
display.addMap(new ScalarMap(RealType.Longitude, Display.Longitude));
ScalarMap rgbMap = new ScalarMap(radianceType, Display.RGB);
display.addMap(rgbMap);
}
*/
if (args.length > 0) n = Integer.valueOf(args[0]).intValue();
if (args.length > 1) {
rows = Integer.valueOf(args[0]).intValue();
cols = Integer.valueOf(args[1]).intValue();
n = rows * cols;
twod = true;
}
float[][] x = new float[2][n];
// double[][] x = new double[2][n];
System.out.println(" initial values");
if (twod) {
int i = 0;
for (int c=0; c
Ads help maintain this website.