diff --git a/.gitignore b/.gitignore
index a6f89c2..a1c5b32 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,5 @@
-/target/
\ No newline at end of file
+/target/
+/org/fairsim/extern/jtransforms/*.class
+/external/*.jar
+/*.jar
+/org/fairsim/git-version-jtransforms.txt
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..913d23c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,45 @@
+#
+# fairSIM JTransforms make file
+#
+JC = javac
+JAR = jar
+
+# Options for the java compiler
+EXTDIR="./external"
+
+JFLAGS = -g -Xlint:unchecked -Xlint:deprecation -extdirs ./external -d ./
+JFLAGS+= -target 1.6 -source 1.6 -bootclasspath ./external/rt-1.6.jar
+
+# remove command to clean up
+RM = rm -vf
+
+.PHONY: all
+
+all:
+ $(JC) $(JFLAGS) org/fairsim/extern/jtransforms/*.java
+
+
+# misc rules
+git-version :
+ git rev-parse HEAD > org/fairsim/git-version-jtransforms.txt ; \
+ git tag --contains >> org/fairsim/git-version-jtransforms.txt ; \
+ echo "n/a" >> org/fairsim/git-version-jtransforms.txt
+
+jar: git-version
+ $(JAR) -cvf jtransforms_fairSIM_fork_$(shell head -c 10 org/fairsim/git-version-jtransforms.txt).jar \
+ org/fairsim/extern/*/*.class \
+ org/fairsim/git-version-jtransforms.txt
+
+doc: doc/index.html
+
+doc/index.html : $(wildcard org/fairsim/*/*.java)
+ javadoc -d doc/ -classpath ./ -extdirs ${EXTDIR} \
+ -subpackages org.fairsim -exclude org.fairsim.extern.jtransforms
+
+clean :
+ $(RM) jtransforms_fairSIM_*.jar jtransforms_fairSIM_*.tar.bz2
+ $(RM) org/fairsim/extern/jtransforms/*.class org/fairsim/git-version-jtransforms.txt
+ $(RM) -r doc/*
+ $(RM) -rf target
+
+
diff --git a/external/get-dependencies.sh b/external/get-dependencies.sh
new file mode 100755
index 0000000..a612e4c
--- /dev/null
+++ b/external/get-dependencies.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+fileMissing=0
+
+# Get the ImageJ base library (in version 1.47, which is the lowest we currently support)
+if [ ! -e ij147v.jar ] ; then
+ fileMissing=1
+ wget https://imagej.nih.gov/ij/download/jars/ij147v.jar
+fi
+
+
+# This fetches the java 1.6 runtime, needed for backwards-compatible
+# compilation to Java 6 with newer compilers
+# unfortunately, Java 6's rt.jar does not seem to be on Maven, so
+# fetch it by extracting it from Ubuntu's openjdk deb.
+# Java 9 will make it much more easier with the "-release" option
+if [ ! -e rt-1.6.jar ] ; then
+ fileMissing=1
+
+ mkdir tmp-rt-jar
+ cd tmp-rt-jar
+
+ # download the 'openjdk-6-jre-headless' deb file
+ wget http://security.ubuntu.com/ubuntu/pool/universe/o/openjdk-6/openjdk-6-jre-headless_6b41-1.13.13-0ubuntu0.14.04.1_amd64.deb -O openjdk.deb
+
+
+ # extract the deb
+ echo "Extracting rt.jar from the .deb file"
+ echo "This might take a few moments... "
+ ar -x openjdk.deb
+
+ # extract the rt.jar from the data.tar
+ tar -xf data.tar.xz ./usr/lib/jvm/java-6-openjdk-amd64/jre/lib/rt.jar
+ mv ./usr/lib/jvm/java-6-openjdk-amd64/jre/lib/rt.jar ../rt-1.6.jar
+ cd ..
+
+ rm -rf tmp-rt-jar
+ echo "Done."
+
+fi
+
+if [ $fileMissing -eq 0 ] ; then
+ echo "All files found, fairSIM should compile"
+fi
+
diff --git a/src/main/java/org/jtransforms/utils/CommonUtils.java b/org/fairsim/extern/jtransforms/CommonUtils.java
similarity index 99%
rename from src/main/java/org/jtransforms/utils/CommonUtils.java
rename to org/fairsim/extern/jtransforms/CommonUtils.java
index 799e480..fac67a2 100644
--- a/src/main/java/org/jtransforms/utils/CommonUtils.java
+++ b/org/fairsim/extern/jtransforms/CommonUtils.java
@@ -24,12 +24,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
-package org.jtransforms.utils;
+
+// Code modified for inclusion with fairSIM:
+// - changed package name
+// - Commented out all dependence on ...LargeArray
+// - based on JTransforms 3.1, git ede249c9824262bd9b5f571e56f7a0fa596f6f20
+
+package org.fairsim.extern.jtransforms;
import java.util.concurrent.Future;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-import pl.edu.icm.jlargearrays.LongLargeArray;
+//import pl.edu.icm.jlargearrays.DoubleLargeArray;
+//import pl.edu.icm.jlargearrays.FloatLargeArray;
+//import pl.edu.icm.jlargearrays.LongLargeArray;
/**
* Static methods used internally in FFT and DCT code.
@@ -78,7 +84,7 @@ public static void makeipt(int nw, int[] ip)
m = m2;
}
}
-
+/*
public static void makeipt(long nw, LongLargeArray ipl)
{
long j, l, m, m2, p, q;
@@ -97,7 +103,7 @@ public static void makeipt(long nw, LongLargeArray ipl)
m = m2;
}
}
-
+*/
public static void makewt(int nw, int[] ip, double[] w)
{
int j, nwh, nw0, nw1;
@@ -163,6 +169,7 @@ public static void makewt(int nw, int[] ip, double[] w)
}
}
+/*
public static void makewt(long nw, LongLargeArray ipl, DoubleLargeArray wl)
{
long j, nwh, nw0, nw1;
@@ -227,7 +234,7 @@ public static void makewt(long nw, LongLargeArray ipl, DoubleLargeArray wl)
}
}
}
-
+*/
public static void makect(int nc, double[] c, int startc, int[] ip)
{
int j, nch;
@@ -246,7 +253,7 @@ public static void makect(int nc, double[] c, int startc, int[] ip)
}
}
}
-
+/*
public static void makect(long nc, DoubleLargeArray c, long startc, LongLargeArray ipl)
{
long j, nch;
@@ -265,7 +272,7 @@ public static void makect(long nc, DoubleLargeArray c, long startc, LongLargeArr
}
}
}
-
+*/
public static void makect(int nc, float[] c, int startc, int[] ip)
{
int j, nch;
@@ -284,7 +291,7 @@ public static void makect(int nc, float[] c, int startc, int[] ip)
}
}
}
-
+/*
public static void makect(long nc, FloatLargeArray c, long startc, LongLargeArray ipl)
{
long j, nch;
@@ -303,7 +310,7 @@ public static void makect(long nc, FloatLargeArray c, long startc, LongLargeArra
}
}
}
-
+*/
public static void makewt(int nw, int[] ip, float[] w)
{
int j, nwh, nw0, nw1;
@@ -368,7 +375,7 @@ public static void makewt(int nw, int[] ip, float[] w)
}
}
}
-
+/*
public static void makewt(long nw, LongLargeArray ipl, FloatLargeArray wl)
{
long j, nwh, nw0, nw1;
@@ -433,7 +440,7 @@ public static void makewt(long nw, LongLargeArray ipl, FloatLargeArray wl)
}
}
}
-
+*/
public static void cftfsub(int n, double[] a, int offa, int[] ip, int nw, double[] w)
{
if (n > 8) {
@@ -462,7 +469,7 @@ public static void cftfsub(int n, double[] a, int offa, int[] ip, int nw, double
cftxb020(a, offa);
}
}
-
+/*
public static void cftfsub(long n, DoubleLargeArray a, long offa, LongLargeArray ip, long nw, DoubleLargeArray w)
{
if (n > 8) {
@@ -491,7 +498,7 @@ public static void cftfsub(long n, DoubleLargeArray a, long offa, LongLargeArray
cftxb020(a, offa);
}
}
-
+*/
public static void cftbsub(int n, double[] a, int offa, int[] ip, int nw, double[] w)
{
if (n > 8) {
@@ -520,7 +527,7 @@ public static void cftbsub(int n, double[] a, int offa, int[] ip, int nw, double
cftxb020(a, offa);
}
}
-
+/*
public static void cftbsub(long n, DoubleLargeArray a, long offa, LongLargeArray ip, long nw, DoubleLargeArray w)
{
if (n > 8) {
@@ -549,7 +556,7 @@ public static void cftbsub(long n, DoubleLargeArray a, long offa, LongLargeArray
cftxb020(a, offa);
}
}
-
+*/
public static void bitrv2(int n, int[] ip, double[] a, int offa)
{
int j1, k1, l, m, nh, nm;
@@ -962,7 +969,7 @@ public static void bitrv2(int n, int[] ip, double[] a, int offa)
}
}
}
-
+/*
public static void bitrv2l(long n, LongLargeArray ip, DoubleLargeArray a, long offa)
{
long j1, k1, l, m, nh, nm;
@@ -1375,7 +1382,7 @@ public static void bitrv2l(long n, LongLargeArray ip, DoubleLargeArray a, long o
}
}
}
-
+*/
public static void bitrv2conj(int n, int[] ip, double[] a, int offa)
{
int j1, k1, l, m, nh, nm;
@@ -1796,7 +1803,7 @@ public static void bitrv2conj(int n, int[] ip, double[] a, int offa)
}
}
}
-
+/*
public static void bitrv2conj(long n, LongLargeArray ip, DoubleLargeArray a, long offa)
{
long j1, k1, l, m, nh, nm;
@@ -2217,7 +2224,7 @@ public static void bitrv2conj(long n, LongLargeArray ip, DoubleLargeArray a, lon
}
}
}
-
+*/
public static void bitrv216(double[] a, int offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
@@ -2271,7 +2278,7 @@ public static void bitrv216(double[] a, int offa)
a[offa + 28] = x7r;
a[offa + 29] = x7i;
}
-
+/*
public static void bitrv216(DoubleLargeArray a, long offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
@@ -2325,7 +2332,7 @@ public static void bitrv216(DoubleLargeArray a, long offa)
a.setDouble(offa + 28, x7r);
a.setDouble(offa + 29, x7i);
}
-
+*/
public static void bitrv216neg(double[] a, int offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i;
@@ -2391,7 +2398,7 @@ public static void bitrv216neg(double[] a, int offa)
a[offa + 30] = x8r;
a[offa + 31] = x8i;
}
-
+/*
public static void bitrv216neg(DoubleLargeArray a, long offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i;
@@ -2457,7 +2464,7 @@ public static void bitrv216neg(DoubleLargeArray a, long offa)
a.setDouble(offa + 30, x8r);
a.setDouble(offa + 31, x8i);
}
-
+*/
public static void bitrv208(double[] a, int offa)
{
double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
@@ -2479,7 +2486,7 @@ public static void bitrv208(double[] a, int offa)
a[offa + 12] = x3r;
a[offa + 13] = x3i;
}
-
+/*
public static void bitrv208(DoubleLargeArray a, long offa)
{
double x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
@@ -2501,7 +2508,7 @@ public static void bitrv208(DoubleLargeArray a, long offa)
a.setDouble(offa + 12, x3r);
a.setDouble(offa + 13, x3i);
}
-
+*/
public static void bitrv208neg(double[] a, int offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
@@ -2535,7 +2542,7 @@ public static void bitrv208neg(double[] a, int offa)
a[offa + 14] = x4r;
a[offa + 15] = x4i;
}
-
+/*
public static void bitrv208neg(DoubleLargeArray a, long offa)
{
double x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
@@ -2569,7 +2576,7 @@ public static void bitrv208neg(DoubleLargeArray a, long offa)
a.setDouble(offa + 14, x4r);
a.setDouble(offa + 15, x4i);
}
-
+*/
public static void cftf1st(int n, double[] a, int offa, double[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -2788,7 +2795,7 @@ public static void cftf1st(int n, double[] a, int offa, double[] w, int startw)
a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
}
-
+/*
public static void cftf1st(long n, DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -3007,7 +3014,7 @@ public static void cftf1st(long n, DoubleLargeArray a, long offa, DoubleLargeArr
a.setDouble(idx3 + 2, wk3i * x0r + wk3r * x0i);
a.setDouble(idx3 + 3, wk3i * x0i - wk3r * x0r);
}
-
+*/
public static void cftb1st(int n, double[] a, int offa, double[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -3227,7 +3234,7 @@ public static void cftb1st(int n, double[] a, int offa, double[] w, int startw)
a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
}
-
+/*
public static void cftb1st(long n, DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -3447,7 +3454,7 @@ public static void cftb1st(long n, DoubleLargeArray a, long offa, DoubleLargeArr
a.setDouble(idx3 + 2, wk3i * x0r + wk3r * x0i);
a.setDouble(idx3 + 3, wk3i * x0i - wk3r * x0r);
}
-
+*/
public static void cftrec4_th(final int n, final double[] a, final int offa, final int nw, final double[] w)
{
int i;
@@ -3515,7 +3522,7 @@ public void run()
}
ConcurrencyUtils.waitForCompletion(futures);
}
-
+/*
public static void cftrec4_th(final long n, final DoubleLargeArray a, final long offa, final long nw, final DoubleLargeArray w)
{
int i, idx = 0;
@@ -3583,7 +3590,7 @@ public void run()
}
ConcurrencyUtils.waitForCompletion(futures);
}
-
+*/
public static void cftrec4(int n, double[] a, int offa, int nw, double[] w)
{
int isplt, j, k, m;
@@ -3603,7 +3610,7 @@ public static void cftrec4(int n, double[] a, int offa, int nw, double[] w)
cftleaf(m, isplt, a, idx2 + j, nw, w);
}
}
-
+/*
public static void cftrec4(long n, DoubleLargeArray a, long offa, long nw, DoubleLargeArray w)
{
long isplt, j, k, m;
@@ -3623,7 +3630,7 @@ public static void cftrec4(long n, DoubleLargeArray a, long offa, long nw, Doubl
cftleaf(m, isplt, a, idx2 + j, nw, w);
}
}
-
+*/
public static int cfttree(int n, int j, int k, double[] a, int offa, int nw, double[] w)
{
int i, isplt, m;
@@ -3656,7 +3663,7 @@ public static int cfttree(int n, int j, int k, double[] a, int offa, int nw, dou
}
return isplt;
}
-
+/*
public static long cfttree(long n, long j, long k, DoubleLargeArray a, long offa, long nw, DoubleLargeArray w)
{
long i, isplt, m;
@@ -3689,7 +3696,7 @@ public static long cfttree(long n, long j, long k, DoubleLargeArray a, long offa
}
return isplt;
}
-
+*/
public static void cftleaf(int n, int isplt, double[] a, int offa, int nw, double[] w)
{
if (n == 512) {
@@ -3746,7 +3753,7 @@ public static void cftleaf(int n, int isplt, double[] a, int offa, int nw, doubl
cftf081(a, offa + 224, w, nw - 8);
}
}
-
+/*
public static void cftleaf(long n, long isplt, DoubleLargeArray a, long offa, long nw, DoubleLargeArray w)
{
if (n == 512) {
@@ -3803,7 +3810,7 @@ public static void cftleaf(long n, long isplt, DoubleLargeArray a, long offa, lo
cftf081(a, offa + 224, w, nw - 8);
}
}
-
+*/
public static void cftmdl1(int n, double[] a, int offa, double[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -3929,7 +3936,7 @@ public static void cftmdl1(int n, double[] a, int offa, double[] w, int startw)
a[idx3] = -wn4r * (x0r + x0i);
a[idx3 + 1] = -wn4r * (x0i - x0r);
}
-
+/*
public static void cftmdl1(long n, DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -4055,7 +4062,7 @@ public static void cftmdl1(long n, DoubleLargeArray a, long offa, DoubleLargeArr
a.setDouble(idx3, -wn4r * (x0r + x0i));
a.setDouble(idx3 + 1, -wn4r * (x0i - x0r));
}
-
+*/
public static void cftmdl2(int n, double[] a, int offa, double[] w, int startw)
{
int j0, j1, j2, j3, k, kr, m, mh;
@@ -4206,7 +4213,7 @@ public static void cftmdl2(int n, double[] a, int offa, double[] w, int startw)
a[idx3] = y0r + y2r;
a[idx3 + 1] = y0i + y2i;
}
-
+/*
public static void cftmdl2(long n, DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
long j0, j1, j2, j3, k, kr, m, mh;
@@ -4357,7 +4364,7 @@ public static void cftmdl2(long n, DoubleLargeArray a, long offa, DoubleLargeArr
a.setDouble(idx3, y0r + y2r);
a.setDouble(idx3 + 1, y0i + y2i);
}
-
+*/
public static void cftfx41(int n, double[] a, int offa, int nw, double[] w)
{
if (n == 128) {
@@ -4372,7 +4379,7 @@ public static void cftfx41(int n, double[] a, int offa, int nw, double[] w)
cftf081(a, offa + 48, w, nw - 8);
}
}
-
+/*
public static void cftfx41(long n, DoubleLargeArray a, long offa, long nw, DoubleLargeArray w)
{
if (n == 128) {
@@ -4387,7 +4394,7 @@ public static void cftfx41(long n, DoubleLargeArray a, long offa, long nw, Doubl
cftf081(a, offa + 48, w, nw - 8);
}
}
-
+*/
public static void cftf161(double[] a, int offa, double[] w, int startw)
{
double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -4541,7 +4548,7 @@ public static void cftf161(double[] a, int offa, double[] w, int startw)
a[offa + 6] = x1r + x3i;
a[offa + 7] = x1i - x3r;
}
-
+/*
public static void cftf161(DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -4695,7 +4702,7 @@ public static void cftf161(DoubleLargeArray a, long offa, DoubleLargeArray w, lo
a.setDouble(offa + 6, x1r + x3i);
a.setDouble(offa + 7, x1i - x3r);
}
-
+*/
public static void cftf162(double[] a, int offa, double[] w, int startw)
{
double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -4872,7 +4879,7 @@ public static void cftf162(double[] a, int offa, double[] w, int startw)
a[offa + 30] = x1r + x2i;
a[offa + 31] = x1i - x2r;
}
-
+/*
public static void cftf162(DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
double wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -5049,7 +5056,7 @@ public static void cftf162(DoubleLargeArray a, long offa, DoubleLargeArray w, lo
a.setDouble(offa + 30, x1r + x2i);
a.setDouble(offa + 31, x1i - x2r);
}
-
+*/
public static void cftf081(double[] a, int offa, double[] w, int startw)
{
double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -5108,7 +5115,7 @@ public static void cftf081(double[] a, int offa, double[] w, int startw)
a[offa + 6] = y2r + y6i;
a[offa + 7] = y2i - y6r;
}
-
+/*
public static void cftf081(DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
double wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -5167,7 +5174,7 @@ public static void cftf081(DoubleLargeArray a, long offa, DoubleLargeArray w, lo
a.setDouble(offa + 6, y2r + y6i);
a.setDouble(offa + 7, y2i - y6r);
}
-
+*/
public static void cftf082(double[] a, int offa, double[] w, int startw)
{
double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -5236,7 +5243,7 @@ public static void cftf082(double[] a, int offa, double[] w, int startw)
a[offa + 14] = x0r + x1i;
a[offa + 15] = x0i - x1r;
}
-
+/*
public static void cftf082(DoubleLargeArray a, long offa, DoubleLargeArray w, long startw)
{
double wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -5305,7 +5312,7 @@ public static void cftf082(DoubleLargeArray a, long offa, DoubleLargeArray w, lo
a.setDouble(offa + 14, x0r + x1i);
a.setDouble(offa + 15, x0i - x1r);
}
-
+*/
public static void cftf040(double[] a, int offa)
{
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -5327,7 +5334,7 @@ public static void cftf040(double[] a, int offa)
a[offa + 6] = x1r + x3i;
a[offa + 7] = x1i - x3r;
}
-
+/*
public static void cftf040(DoubleLargeArray a, long offa)
{
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -5349,7 +5356,7 @@ public static void cftf040(DoubleLargeArray a, long offa)
a.setDouble(offa + 6, x1r + x3i);
a.setDouble(offa + 7, x1i - x3r);
}
-
+*/
public static void cftb040(double[] a, int offa)
{
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -5371,7 +5378,7 @@ public static void cftb040(double[] a, int offa)
a[offa + 6] = x1r - x3i;
a[offa + 7] = x1i + x3r;
}
-
+/*
public static void cftb040(DoubleLargeArray a, long offa)
{
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -5393,7 +5400,7 @@ public static void cftb040(DoubleLargeArray a, long offa)
a.setDouble(offa + 6, x1r - x3i);
a.setDouble(offa + 7, x1i + x3r);
}
-
+*/
public static void cftx020(double[] a, int offa)
{
double x0r, x0i;
@@ -5404,7 +5411,7 @@ public static void cftx020(double[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftx020(DoubleLargeArray a, long offa)
{
double x0r, x0i;
@@ -5415,7 +5422,7 @@ public static void cftx020(DoubleLargeArray a, long offa)
a.setDouble(offa + 2, x0r);
a.setDouble(offa + 3, x0i);
}
-
+*/
public static void cftxb020(double[] a, int offa)
{
double x0r, x0i;
@@ -5427,7 +5434,7 @@ public static void cftxb020(double[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftxb020(DoubleLargeArray a, long offa)
{
double x0r, x0i;
@@ -5439,7 +5446,7 @@ public static void cftxb020(DoubleLargeArray a, long offa)
a.setDouble(offa + 2, x0r);
a.setDouble(offa + 3, x0i);
}
-
+*/
public static void cftxc020(double[] a, int offa)
{
double x0r, x0i;
@@ -5450,7 +5457,7 @@ public static void cftxc020(double[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftxc020(DoubleLargeArray a, long offa)
{
double x0r, x0i;
@@ -5461,7 +5468,7 @@ public static void cftxc020(DoubleLargeArray a, long offa)
a.setDouble(offa + 2, x0r);
a.setDouble(offa + 3, x0i);
}
-
+*/
public static void rftfsub(int n, double[] a, int offa, int nc, double[] c, int startc)
{
int k, kk, ks, m;
@@ -5489,7 +5496,7 @@ public static void rftfsub(int n, double[] a, int offa, int nc, double[] c, int
}
a[offa + m + 1] = -a[offa + m + 1];
}
-
+/*
public static void rftfsub(long n, DoubleLargeArray a, long offa, long nc, DoubleLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -5517,7 +5524,7 @@ public static void rftfsub(long n, DoubleLargeArray a, long offa, long nc, Doubl
}
a.setDouble(offa + m + 1, -a.getDouble(offa + m + 1));
}
-
+*/
public static void rftbsub(int n, double[] a, int offa, int nc, double[] c, int startc)
{
int k, kk, ks, m;
@@ -5544,7 +5551,7 @@ public static void rftbsub(int n, double[] a, int offa, int nc, double[] c, int
a[idx2 + 1] -= yi;
}
}
-
+/*
public static void rftbsub(long n, DoubleLargeArray a, long offa, long nc, DoubleLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -5571,7 +5578,7 @@ public static void rftbsub(long n, DoubleLargeArray a, long offa, long nc, Doubl
a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - yi);
}
}
-
+*/
public static void dctsub(int n, double[] a, int offa, int nc, double[] c, int startc)
{
int k, kk, ks, m;
@@ -5595,7 +5602,7 @@ public static void dctsub(int n, double[] a, int offa, int nc, double[] c, int s
}
a[offa + m] *= c[startc];
}
-
+/*
public static void dctsub(long n, DoubleLargeArray a, long offa, long nc, DoubleLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -5619,7 +5626,7 @@ public static void dctsub(long n, DoubleLargeArray a, long offa, long nc, Double
}
a.setDouble(offa + m, a.getDouble(offa + m) * c.getDouble(startc));
}
-
+*/
public static void cftfsub(int n, float[] a, int offa, int[] ip, int nw, float[] w)
{
if (n > 8) {
@@ -5648,7 +5655,7 @@ public static void cftfsub(int n, float[] a, int offa, int[] ip, int nw, float[]
cftxb020(a, offa);
}
}
-
+/*
public static void cftfsub(long n, FloatLargeArray a, long offa, LongLargeArray ip, long nw, FloatLargeArray w)
{
if (n > 8) {
@@ -5677,7 +5684,7 @@ public static void cftfsub(long n, FloatLargeArray a, long offa, LongLargeArray
cftxb020(a, offa);
}
}
-
+*/
public static void cftbsub(int n, float[] a, int offa, int[] ip, int nw, float[] w)
{
if (n > 8) {
@@ -5706,7 +5713,7 @@ public static void cftbsub(int n, float[] a, int offa, int[] ip, int nw, float[]
cftxb020(a, offa);
}
}
-
+/*
public static void cftbsub(long n, FloatLargeArray a, long offa, LongLargeArray ip, long nw, FloatLargeArray w)
{
if (n > 8) {
@@ -5735,7 +5742,7 @@ public static void cftbsub(long n, FloatLargeArray a, long offa, LongLargeArray
cftxb020(a, offa);
}
}
-
+*/
public static void bitrv2(int n, int[] ip, float[] a, int offa)
{
int j1, k1, l, m, nh, nm;
@@ -6148,7 +6155,7 @@ public static void bitrv2(int n, int[] ip, float[] a, int offa)
}
}
}
-
+/*
public static void bitrv2l(long n, LongLargeArray ip, FloatLargeArray a, long offa)
{
long j1, k1, l, m, nh, nm;
@@ -6561,7 +6568,7 @@ public static void bitrv2l(long n, LongLargeArray ip, FloatLargeArray a, long of
}
}
}
-
+*/
public static void bitrv2conj(int n, int[] ip, float[] a, int offa)
{
int j1, k1, l, m, nh, nm;
@@ -6982,7 +6989,7 @@ public static void bitrv2conj(int n, int[] ip, float[] a, int offa)
}
}
}
-
+/*
public static void bitrv2conj(long n, LongLargeArray ip, FloatLargeArray a, long offa)
{
long j1, k1, l, m, nh, nm;
@@ -7403,7 +7410,7 @@ public static void bitrv2conj(long n, LongLargeArray ip, FloatLargeArray a, long
}
}
}
-
+*/
public static void bitrv216(float[] a, int offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
@@ -7457,7 +7464,7 @@ public static void bitrv216(float[] a, int offa)
a[offa + 28] = x7r;
a[offa + 29] = x7i;
}
-
+/*
public static void bitrv216(FloatLargeArray a, long offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x7r, x7i, x8r, x8i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i;
@@ -7511,7 +7518,7 @@ public static void bitrv216(FloatLargeArray a, long offa)
a.setFloat(offa + 28, x7r);
a.setFloat(offa + 29, x7i);
}
-
+*/
public static void bitrv216neg(float[] a, int offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i;
@@ -7577,7 +7584,7 @@ public static void bitrv216neg(float[] a, int offa)
a[offa + 30] = x8r;
a[offa + 31] = x8i;
}
-
+/*
public static void bitrv216neg(FloatLargeArray a, long offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i, x8r, x8i, x9r, x9i, x10r, x10i, x11r, x11i, x12r, x12i, x13r, x13i, x14r, x14i, x15r, x15i;
@@ -7643,7 +7650,7 @@ public static void bitrv216neg(FloatLargeArray a, long offa)
a.setFloat(offa + 30, x8r);
a.setFloat(offa + 31, x8i);
}
-
+*/
public static void bitrv208(float[] a, int offa)
{
float x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
@@ -7665,7 +7672,7 @@ public static void bitrv208(float[] a, int offa)
a[offa + 12] = x3r;
a[offa + 13] = x3i;
}
-
+/*
public static void bitrv208(FloatLargeArray a, long offa)
{
float x1r, x1i, x3r, x3i, x4r, x4i, x6r, x6i;
@@ -7687,7 +7694,7 @@ public static void bitrv208(FloatLargeArray a, long offa)
a.setFloat(offa + 12, x3r);
a.setFloat(offa + 13, x3i);
}
-
+*/
public static void bitrv208neg(float[] a, int offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
@@ -7721,7 +7728,7 @@ public static void bitrv208neg(float[] a, int offa)
a[offa + 14] = x4r;
a[offa + 15] = x4i;
}
-
+/*
public static void bitrv208neg(FloatLargeArray a, long offa)
{
float x1r, x1i, x2r, x2i, x3r, x3i, x4r, x4i, x5r, x5i, x6r, x6i, x7r, x7i;
@@ -7755,7 +7762,7 @@ public static void bitrv208neg(FloatLargeArray a, long offa)
a.setFloat(offa + 14, x4r);
a.setFloat(offa + 15, x4i);
}
-
+*/
public static void cftf1st(int n, float[] a, int offa, float[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -7974,7 +7981,7 @@ public static void cftf1st(int n, float[] a, int offa, float[] w, int startw)
a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
}
-
+/*
public static void cftf1st(long n, FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -8193,7 +8200,7 @@ public static void cftf1st(long n, FloatLargeArray a, long offa, FloatLargeArray
a.setFloat(idx3 + 2, wk3i * x0r + wk3r * x0i);
a.setFloat(idx3 + 3, wk3i * x0i - wk3r * x0r);
}
-
+*/
public static void cftb1st(int n, float[] a, int offa, float[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -8413,7 +8420,7 @@ public static void cftb1st(int n, float[] a, int offa, float[] w, int startw)
a[idx3 + 2] = wk3i * x0r + wk3r * x0i;
a[idx3 + 3] = wk3i * x0i - wk3r * x0r;
}
-
+/*
public static void cftb1st(long n, FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -8633,7 +8640,7 @@ public static void cftb1st(long n, FloatLargeArray a, long offa, FloatLargeArray
a.setFloat(idx3 + 2, wk3i * x0r + wk3r * x0i);
a.setFloat(idx3 + 3, wk3i * x0i - wk3r * x0r);
}
-
+*/
public static void cftrec4_th(final int n, final float[] a, final int offa, final int nw, final float[] w)
{
int i;
@@ -8701,7 +8708,7 @@ public void run()
}
ConcurrencyUtils.waitForCompletion(futures);
}
-
+/*
public static void cftrec4_th(final long n, final FloatLargeArray a, final long offa, final long nw, final FloatLargeArray w)
{
int i, idx = 0;
@@ -8769,7 +8776,7 @@ public void run()
}
ConcurrencyUtils.waitForCompletion(futures);
}
-
+*/
public static void cftrec4(int n, float[] a, int offa, int nw, float[] w)
{
int isplt, j, k, m;
@@ -8789,7 +8796,7 @@ public static void cftrec4(int n, float[] a, int offa, int nw, float[] w)
cftleaf(m, isplt, a, idx2 + j, nw, w);
}
}
-
+/*
public static void cftrec4(long n, FloatLargeArray a, long offa, long nw, FloatLargeArray w)
{
long isplt, j, k, m;
@@ -8809,7 +8816,7 @@ public static void cftrec4(long n, FloatLargeArray a, long offa, long nw, FloatL
cftleaf(m, isplt, a, idx2 + j, nw, w);
}
}
-
+*/
public static int cfttree(int n, int j, int k, float[] a, int offa, int nw, float[] w)
{
int i, isplt, m;
@@ -8842,7 +8849,7 @@ public static int cfttree(int n, int j, int k, float[] a, int offa, int nw, floa
}
return isplt;
}
-
+/*
public static long cfttree(long n, long j, long k, FloatLargeArray a, long offa, long nw, FloatLargeArray w)
{
long i, isplt, m;
@@ -8875,7 +8882,7 @@ public static long cfttree(long n, long j, long k, FloatLargeArray a, long offa,
}
return isplt;
}
-
+*/
public static void cftleaf(int n, int isplt, float[] a, int offa, int nw, float[] w)
{
if (n == 512) {
@@ -8932,7 +8939,7 @@ public static void cftleaf(int n, int isplt, float[] a, int offa, int nw, float[
cftf081(a, offa + 224, w, nw - 8);
}
}
-
+/*
public static void cftleaf(long n, long isplt, FloatLargeArray a, long offa, long nw, FloatLargeArray w)
{
if (n == 512) {
@@ -8989,7 +8996,7 @@ public static void cftleaf(long n, long isplt, FloatLargeArray a, long offa, lon
cftf081(a, offa + 224, w, nw - 8);
}
}
-
+*/
public static void cftmdl1(int n, float[] a, int offa, float[] w, int startw)
{
int j0, j1, j2, j3, k, m, mh;
@@ -9115,7 +9122,7 @@ public static void cftmdl1(int n, float[] a, int offa, float[] w, int startw)
a[idx3] = -wn4r * (x0r + x0i);
a[idx3 + 1] = -wn4r * (x0i - x0r);
}
-
+/*
public static void cftmdl1(long n, FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
long j0, j1, j2, j3, k, m, mh;
@@ -9241,7 +9248,7 @@ public static void cftmdl1(long n, FloatLargeArray a, long offa, FloatLargeArray
a.setFloat(idx3, -wn4r * (x0r + x0i));
a.setFloat(idx3 + 1, -wn4r * (x0i - x0r));
}
-
+*/
public static void cftmdl2(int n, float[] a, int offa, float[] w, int startw)
{
int j0, j1, j2, j3, k, kr, m, mh;
@@ -9392,7 +9399,7 @@ public static void cftmdl2(int n, float[] a, int offa, float[] w, int startw)
a[idx3] = y0r + y2r;
a[idx3 + 1] = y0i + y2i;
}
-
+/*
public static void cftmdl2(long n, FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
long j0, j1, j2, j3, k, kr, m, mh;
@@ -9543,7 +9550,7 @@ public static void cftmdl2(long n, FloatLargeArray a, long offa, FloatLargeArray
a.setFloat(idx3, y0r + y2r);
a.setFloat(idx3 + 1, y0i + y2i);
}
-
+*/
public static void cftfx41(int n, float[] a, int offa, int nw, float[] w)
{
if (n == 128) {
@@ -9558,7 +9565,7 @@ public static void cftfx41(int n, float[] a, int offa, int nw, float[] w)
cftf081(a, offa + 48, w, nw - 8);
}
}
-
+/*
public static void cftfx41(long n, FloatLargeArray a, long offa, long nw, FloatLargeArray w)
{
if (n == 128) {
@@ -9573,7 +9580,7 @@ public static void cftfx41(long n, FloatLargeArray a, long offa, long nw, FloatL
cftf081(a, offa + 48, w, nw - 8);
}
}
-
+*/
public static void cftf161(float[] a, int offa, float[] w, int startw)
{
float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -9727,7 +9734,7 @@ public static void cftf161(float[] a, int offa, float[] w, int startw)
a[offa + 6] = x1r + x3i;
a[offa + 7] = x1i - x3r;
}
-
+/*
public static void cftf161(FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -9881,7 +9888,7 @@ public static void cftf161(FloatLargeArray a, long offa, FloatLargeArray w, long
a.setFloat(offa + 6, x1r + x3i);
a.setFloat(offa + 7, x1i - x3r);
}
-
+*/
public static void cftf162(float[] a, int offa, float[] w, int startw)
{
float wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -10058,7 +10065,7 @@ public static void cftf162(float[] a, int offa, float[] w, int startw)
a[offa + 30] = x1r + x2i;
a[offa + 31] = x1i - x2r;
}
-
+/*
public static void cftf162(FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
float wn4r, wk1r, wk1i, wk2r, wk2i, wk3r, wk3i, x0r, x0i, x1r, x1i, x2r, x2i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i, y8r, y8i, y9r, y9i, y10r, y10i, y11r, y11i, y12r, y12i, y13r, y13i, y14r, y14i, y15r, y15i;
@@ -10235,7 +10242,7 @@ public static void cftf162(FloatLargeArray a, long offa, FloatLargeArray w, long
a.setFloat(offa + 30, x1r + x2i);
a.setFloat(offa + 31, x1i - x2r);
}
-
+*/
public static void cftf081(float[] a, int offa, float[] w, int startw)
{
float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -10294,7 +10301,7 @@ public static void cftf081(float[] a, int offa, float[] w, int startw)
a[offa + 6] = y2r + y6i;
a[offa + 7] = y2i - y6r;
}
-
+/*
public static void cftf081(FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
float wn4r, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -10353,7 +10360,7 @@ public static void cftf081(FloatLargeArray a, long offa, FloatLargeArray w, long
a.setFloat(offa + 6, y2r + y6i);
a.setFloat(offa + 7, y2i - y6r);
}
-
+*/
public static void cftf082(float[] a, int offa, float[] w, int startw)
{
float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -10422,7 +10429,7 @@ public static void cftf082(float[] a, int offa, float[] w, int startw)
a[offa + 14] = x0r + x1i;
a[offa + 15] = x0i - x1r;
}
-
+/*
public static void cftf082(FloatLargeArray a, long offa, FloatLargeArray w, long startw)
{
float wn4r, wk1r, wk1i, x0r, x0i, x1r, x1i, y0r, y0i, y1r, y1i, y2r, y2i, y3r, y3i, y4r, y4i, y5r, y5i, y6r, y6i, y7r, y7i;
@@ -10491,7 +10498,7 @@ public static void cftf082(FloatLargeArray a, long offa, FloatLargeArray w, long
a.setFloat(offa + 14, x0r + x1i);
a.setFloat(offa + 15, x0i - x1r);
}
-
+*/
public static void cftf040(float[] a, int offa)
{
float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -10513,7 +10520,7 @@ public static void cftf040(float[] a, int offa)
a[offa + 6] = x1r + x3i;
a[offa + 7] = x1i - x3r;
}
-
+/*
public static void cftf040(FloatLargeArray a, long offa)
{
float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -10535,7 +10542,7 @@ public static void cftf040(FloatLargeArray a, long offa)
a.setFloat(offa + 6, x1r + x3i);
a.setFloat(offa + 7, x1i - x3r);
}
-
+*/
public static void cftb040(float[] a, int offa)
{
float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -10557,7 +10564,7 @@ public static void cftb040(float[] a, int offa)
a[offa + 6] = x1r - x3i;
a[offa + 7] = x1i + x3r;
}
-
+/*
public static void cftb040(FloatLargeArray a, long offa)
{
float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
@@ -10579,7 +10586,7 @@ public static void cftb040(FloatLargeArray a, long offa)
a.setFloat(offa + 6, x1r - x3i);
a.setFloat(offa + 7, x1i + x3r);
}
-
+*/
public static void cftx020(float[] a, int offa)
{
float x0r, x0i;
@@ -10590,7 +10597,7 @@ public static void cftx020(float[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftx020(FloatLargeArray a, long offa)
{
float x0r, x0i;
@@ -10601,7 +10608,7 @@ public static void cftx020(FloatLargeArray a, long offa)
a.setFloat(offa + 2, x0r);
a.setFloat(offa + 3, x0i);
}
-
+*/
public static void cftxb020(float[] a, int offa)
{
float x0r, x0i;
@@ -10613,7 +10620,7 @@ public static void cftxb020(float[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftxb020(FloatLargeArray a, long offa)
{
float x0r, x0i;
@@ -10625,7 +10632,7 @@ public static void cftxb020(FloatLargeArray a, long offa)
a.setFloat(offa + 2, x0r);
a.setFloat(offa + 3, x0i);
}
-
+*/
public static void cftxc020(float[] a, int offa)
{
float x0r, x0i;
@@ -10636,7 +10643,7 @@ public static void cftxc020(float[] a, int offa)
a[offa + 2] = x0r;
a[offa + 3] = x0i;
}
-
+/*
public static void cftxc020(FloatLargeArray a, long offa)
{
float x0r, x0i;
@@ -10647,7 +10654,7 @@ public static void cftxc020(FloatLargeArray a, long offa)
a.setFloat(offa + 2, x0r);
a.setFloat(offa + 3, x0i);
}
-
+*/
public static void rftfsub(int n, float[] a, int offa, int nc, float[] c, int startc)
{
int k, kk, ks, m;
@@ -10675,7 +10682,7 @@ public static void rftfsub(int n, float[] a, int offa, int nc, float[] c, int st
}
a[offa + m + 1] = -a[offa + m + 1];
}
-
+/*
public static void rftfsub(long n, FloatLargeArray a, long offa, long nc, FloatLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -10703,7 +10710,7 @@ public static void rftfsub(long n, FloatLargeArray a, long offa, long nc, FloatL
}
a.setFloat(offa + m + 1, -a.getFloat(offa + m + 1));
}
-
+*/
public static void rftbsub(int n, float[] a, int offa, int nc, float[] c, int startc)
{
int k, kk, ks, m;
@@ -10730,7 +10737,7 @@ public static void rftbsub(int n, float[] a, int offa, int nc, float[] c, int st
a[idx2 + 1] -= yi;
}
}
-
+/*
public static void rftbsub(long n, FloatLargeArray a, long offa, long nc, FloatLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -10757,7 +10764,7 @@ public static void rftbsub(long n, FloatLargeArray a, long offa, long nc, FloatL
a.setFloat(idx2 + 1, a.getFloat(idx2 + 1) - yi);
}
}
-
+*/
public static void dctsub(int n, float[] a, int offa, int nc, float[] c, int startc)
{
int k, kk, ks, m;
@@ -10781,7 +10788,7 @@ public static void dctsub(int n, float[] a, int offa, int nc, float[] c, int sta
}
a[offa + m] *= c[startc];
}
-
+/*
public static void dctsub(long n, FloatLargeArray a, long offa, long nc, FloatLargeArray c, long startc)
{
long k, kk, ks, m;
@@ -10805,7 +10812,7 @@ public static void dctsub(long n, FloatLargeArray a, long offa, long nc, FloatLa
}
a.setFloat(offa + m, a.getFloat(offa + m) * c.getFloat(startc));
}
-
+*/
public static void scale(final int n, final double m, final double[] a, final int offa, boolean complex)
{
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -10842,7 +10849,7 @@ public void run()
}
}
}
-
+/*
public static void scale(final long nl, final double m, final DoubleLargeArray a, long offa, boolean complex)
{
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -10877,7 +10884,7 @@ public void run()
}
}
-
+*/
public static void scale(final int n, final float m, final float[] a, final int offa, boolean complex)
{
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -10914,7 +10921,7 @@ public void run()
}
}
}
-
+/*
public static void scale(final long nl, final float m, final FloatLargeArray a, long offa, boolean complex)
{
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -10949,5 +10956,5 @@ public void run()
}
}
-
+*/
}
diff --git a/src/main/java/org/jtransforms/utils/ConcurrencyUtils.java b/org/fairsim/extern/jtransforms/ConcurrencyUtils.java
similarity index 96%
rename from src/main/java/org/jtransforms/utils/ConcurrencyUtils.java
rename to org/fairsim/extern/jtransforms/ConcurrencyUtils.java
index 920be80..adcf934 100644
--- a/src/main/java/org/jtransforms/utils/ConcurrencyUtils.java
+++ b/org/fairsim/extern/jtransforms/ConcurrencyUtils.java
@@ -1,444 +1,448 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.utils;
-
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Concurrency utilities.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class ConcurrencyUtils
-{
-
- /**
- * Thread pool.
- */
- private static ExecutorService THREAD_POOL = Executors.newCachedThreadPool(new CustomThreadFactory(new CustomExceptionHandler()));
-
- private static long THREADS_BEGIN_N_1D_FFT_2THREADS = 8192;
-
- private static long THREADS_BEGIN_N_1D_FFT_4THREADS = 65536;
-
- private static long THREADS_BEGIN_N_2D = 65536;
-
- private static long LARGE_ARAYS_BEGIN_N = (1 << 28);
-
- private static long THREADS_BEGIN_N_3D = 65536;
-
- private static int NTHREADS = prevPow2(getNumberOfProcessors());
-
- private ConcurrencyUtils()
- {
-
- }
-
- private static class CustomExceptionHandler implements Thread.UncaughtExceptionHandler
- {
-
- public void uncaughtException(Thread t, Throwable e)
- {
- e.printStackTrace();
- }
-
- }
-
- private static class CustomThreadFactory implements ThreadFactory
- {
-
- private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
-
- private final Thread.UncaughtExceptionHandler handler;
-
- CustomThreadFactory(Thread.UncaughtExceptionHandler handler)
- {
- this.handler = handler;
- }
-
- public Thread newThread(Runnable r)
- {
- Thread t = defaultFactory.newThread(r);
- t.setUncaughtExceptionHandler(handler);
- return t;
- }
- };
-
- /**
- * Returns the number of available processors.
- *
- * @return number of available processors
- */
- public static int getNumberOfProcessors()
- {
- return Runtime.getRuntime().availableProcessors();
- }
-
- /**
- * Returns the current number of threads.
- *
- * @return the current number of threads.
- */
- public static int getNumberOfThreads()
- {
- return NTHREADS;
- }
-
- /**
- * Sets the number of threads. If n is not a power-of-two number, then the
- * number of threads is set to the closest power-of-two number less than n.
- *
- * @param n number of threads
- */
- public static void setNumberOfThreads(int n)
- {
- NTHREADS = prevPow2(n);
- }
-
- /**
- * Returns the minimal size of 1D data for which two threads are used.
- *
- * @return the minimal size of 1D data for which two threads are used
- */
- public static long getThreadsBeginN_1D_FFT_2Threads()
- {
- return THREADS_BEGIN_N_1D_FFT_2THREADS;
- }
-
- /**
- * Returns the minimal size of 1D data for which four threads are used.
- *
- * @return the minimal size of 1D data for which four threads are used
- */
- public static long getThreadsBeginN_1D_FFT_4Threads()
- {
- return THREADS_BEGIN_N_1D_FFT_4THREADS;
- }
-
- /**
- * Returns the minimal size of 2D data for which threads are used.
- *
- * @return the minimal size of 2D data for which threads are used
- */
- public static long getThreadsBeginN_2D()
- {
- return THREADS_BEGIN_N_2D;
- }
-
- /**
- * Returns the minimal size of 3D data for which threads are used.
- *
- * @return the minimal size of 3D data for which threads are used
- */
- public static long getThreadsBeginN_3D()
- {
- return THREADS_BEGIN_N_3D;
- }
-
- /**
- * Returns the minimal size for which JLargeArrays are used.
- *
- * @return the minimal size for which JLargeArrays are used
- */
- public static long getLargeArraysBeginN()
- {
- return LARGE_ARAYS_BEGIN_N;
- }
-
- /**
- * Sets the minimal size of 1D data for which two threads are used.
- *
- * @param n the minimal size of 1D data for which two threads are used
- */
- public static void setThreadsBeginN_1D_FFT_2Threads(long n)
- {
- if (n < 1024) {
- THREADS_BEGIN_N_1D_FFT_2THREADS = 1024;
- } else {
- THREADS_BEGIN_N_1D_FFT_2THREADS = n;
- }
- }
-
- /**
- * Sets the minimal size of 1D data for which four threads are used.
- *
- * @param n the minimal size of 1D data for which four threads are used
- */
- public static void setThreadsBeginN_1D_FFT_4Threads(long n)
- {
- if (n < 1024) {
- THREADS_BEGIN_N_1D_FFT_4THREADS = 1024;
- } else {
- THREADS_BEGIN_N_1D_FFT_4THREADS = n;
- }
- }
-
- /**
- * Sets the minimal size of 2D data for which threads are used.
- *
- * @param n the minimal size of 2D data for which threads are used
- */
- public static void setThreadsBeginN_2D(long n)
- {
- if (n < 4096) {
- THREADS_BEGIN_N_2D = 4096;
- } else {
- THREADS_BEGIN_N_2D = n;
- }
- }
-
- /**
- * Sets the minimal size of 3D data for which threads are used.
- *
- * @param n the minimal size of 3D data for which threads are used
- */
- public static void setThreadsBeginN_3D(long n)
- {
- THREADS_BEGIN_N_3D = n;
- }
-
- /**
- * Resets the minimal size of 1D data for which two and four threads are
- * used.
- */
- public static void resetThreadsBeginN_FFT()
- {
- THREADS_BEGIN_N_1D_FFT_2THREADS = 8192;
- THREADS_BEGIN_N_1D_FFT_4THREADS = 65536;
- }
-
- /**
- * Resets the minimal size of 2D and 3D data for which threads are used.
- */
- public static void resetThreadsBeginN()
- {
- THREADS_BEGIN_N_2D = 65536;
- THREADS_BEGIN_N_3D = 65536;
- }
-
- /**
- * Sets the minimal size for which JLargeArrays are used.
- *
- * @param n the maximal size for which JLargeArrays are used
- */
- public static void setLargeArraysBeginN(long n)
- {
- if (n < 1) {
- LARGE_ARAYS_BEGIN_N = 1;
- } else if (n > (1 << 28)) {
- LARGE_ARAYS_BEGIN_N = (1 << 28);
- } else {
- LARGE_ARAYS_BEGIN_N = n;
- }
- }
-
- /**
- * Returns the closest power-of-two number greater than or equal to x.
- *
- * @param x input value
- *
- * @return the closest power-of-two number greater than or equal to x
- */
- public static int nextPow2(int x)
- {
- if (x < 1) {
- throw new IllegalArgumentException("x must be greater or equal 1");
- }
- if ((x & (x - 1)) == 0) {
- return x; // x is already a power-of-two number
- }
- x |= (x >>> 1);
- x |= (x >>> 2);
- x |= (x >>> 4);
- x |= (x >>> 8);
- x |= (x >>> 16);
- return x + 1;
- }
-
- /**
- * Returns the closest power-of-two number greater than or equal to x.
- *
- * @param x input value
- *
- * @return the closest power-of-two number greater than or equal to x
- */
- public static long nextPow2(long x)
- {
- if (x < 1) {
- throw new IllegalArgumentException("x must be greater or equal 1");
- }
- if ((x & (x - 1l)) == 0) {
- return x; // x is already a power-of-two number
- }
- x |= (x >>> 1l);
- x |= (x >>> 2l);
- x |= (x >>> 4l);
- x |= (x >>> 8l);
- x |= (x >>> 16l);
- x |= (x >>> 32l);
- return x + 1l;
- }
-
- /**
- * Returns the closest power-of-two number less than or equal to x.
- *
- * @param x input value
- *
- * @return the closest power-of-two number less then or equal to x
- */
- public static int prevPow2(int x)
- {
- if (x < 1) {
- throw new IllegalArgumentException("x must be greater or equal 1");
- }
- return (int) Math.pow(2, Math.floor(Math.log(x) / Math.log(2)));
- }
-
- /**
- * Returns the closest power-of-two number less than or equal to x.
- *
- * @param x input value
- *
- * @return the closest power-of-two number less then or equal to x
- */
- public static long prevPow2(long x)
- {
- if (x < 1) {
- throw new IllegalArgumentException("x must be greater or equal 1");
- }
- return (long) Math.pow(2, Math.floor(Math.log(x) / Math.log(2)));
- }
-
- /**
- * Checks if x is a power-of-two number.
- *
- * @param x input value
- *
- * @return true if x is a power-of-two number
- */
- public static boolean isPowerOf2(int x)
- {
- if (x <= 0) {
- return false;
- } else {
- return (x & (x - 1)) == 0;
- }
- }
-
- /**
- * Checks if x is a power-of-two number.
- *
- * @param x input value
- *
- * @return true if x is a power-of-two number
- */
- public static boolean isPowerOf2(long x)
- {
- if (x <= 0) {
- return false;
- } else {
- return (x & (x - 1l)) == 0;
- }
- }
-
- /**
- * Causes the currently executing thread to sleep (temporarily cease
- * execution) for the specified number of milliseconds.
- *
- * @param millis the length of time to sleep in milliseconds
- */
- public static void sleep(long millis)
- {
- try {
- Thread.sleep(5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Submits a Runnable task for execution and returns a Future representing
- * that task.
- *
- * @param task a Runnable task for execution
- *
- * @return a Future representing the task
- */
- public static Future> submit(Runnable task)
- {
- if (THREAD_POOL.isShutdown() || THREAD_POOL.isTerminated()) {
- THREAD_POOL = Executors.newCachedThreadPool(new CustomThreadFactory(new CustomExceptionHandler()));
- }
- return THREAD_POOL.submit(task);
- }
-
- /**
- * Shutdowns all submitted tasks.
- */
- public static void shutdownAndAwaitTermination()
- {
- THREAD_POOL.shutdown(); // Disable new tasks from being submitted
- try {
- // Wait a while for existing tasks to terminate
- if (!THREAD_POOL.awaitTermination(60, TimeUnit.SECONDS)) {
- THREAD_POOL.shutdownNow(); // Cancel currently executing tasks
- // Wait a while for tasks to respond to being cancelled
- if (!THREAD_POOL.awaitTermination(60, TimeUnit.SECONDS))
- System.err.println("Pool did not terminate");
- }
- } catch (InterruptedException ie) {
- // (Re-)Cancel if current thread also interrupted
- THREAD_POOL.shutdownNow();
- // Preserve interrupt status
- Thread.currentThread().interrupt();
- }
- }
-
- /**
- * Waits for all threads to complete computation.
- *
- * @param futures array of Future objects
- */
- public static void waitForCompletion(Future>[] futures)
- {
- int size = futures.length;
- try {
- for (int j = 0; j < size; j++) {
- futures[j].get();
- }
- } catch (ExecutionException ex) {
- ex.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * JTransforms
+ * Copyright (c) 2007 onward, Piotr Wendykier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Code modified for inclusion with fairSIM:
+// - changed package name
+
+package org.fairsim.extern.jtransforms;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Concurrency utilities.
+ *
+ * @author Piotr Wendykier (piotr.wendykier@gmail.com)
+ */
+public class ConcurrencyUtils
+{
+
+ /**
+ * Thread pool.
+ */
+ private static ExecutorService THREAD_POOL = Executors.newCachedThreadPool(new CustomThreadFactory(new CustomExceptionHandler()));
+
+ private static long THREADS_BEGIN_N_1D_FFT_2THREADS = 8192;
+
+ private static long THREADS_BEGIN_N_1D_FFT_4THREADS = 65536;
+
+ private static long THREADS_BEGIN_N_2D = 65536;
+
+ private static long LARGE_ARAYS_BEGIN_N = (1 << 28);
+
+ private static long THREADS_BEGIN_N_3D = 65536;
+
+ private static int NTHREADS = prevPow2(getNumberOfProcessors());
+
+ private ConcurrencyUtils()
+ {
+
+ }
+
+ private static class CustomExceptionHandler implements Thread.UncaughtExceptionHandler
+ {
+
+ public void uncaughtException(Thread t, Throwable e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ private static class CustomThreadFactory implements ThreadFactory
+ {
+
+ private static final ThreadFactory defaultFactory = Executors.defaultThreadFactory();
+
+ private final Thread.UncaughtExceptionHandler handler;
+
+ CustomThreadFactory(Thread.UncaughtExceptionHandler handler)
+ {
+ this.handler = handler;
+ }
+
+ public Thread newThread(Runnable r)
+ {
+ Thread t = defaultFactory.newThread(r);
+ t.setUncaughtExceptionHandler(handler);
+ return t;
+ }
+ };
+
+ /**
+ * Returns the number of available processors.
+ *
+ * @return number of available processors
+ */
+ public static int getNumberOfProcessors()
+ {
+ return Runtime.getRuntime().availableProcessors();
+ }
+
+ /**
+ * Returns the current number of threads.
+ *
+ * @return the current number of threads.
+ */
+ public static int getNumberOfThreads()
+ {
+ return NTHREADS;
+ }
+
+ /**
+ * Sets the number of threads. If n is not a power-of-two number, then the
+ * number of threads is set to the closest power-of-two number less than n.
+ *
+ * @param n number of threads
+ */
+ public static void setNumberOfThreads(int n)
+ {
+ NTHREADS = prevPow2(n);
+ }
+
+ /**
+ * Returns the minimal size of 1D data for which two threads are used.
+ *
+ * @return the minimal size of 1D data for which two threads are used
+ */
+ public static long getThreadsBeginN_1D_FFT_2Threads()
+ {
+ return THREADS_BEGIN_N_1D_FFT_2THREADS;
+ }
+
+ /**
+ * Returns the minimal size of 1D data for which four threads are used.
+ *
+ * @return the minimal size of 1D data for which four threads are used
+ */
+ public static long getThreadsBeginN_1D_FFT_4Threads()
+ {
+ return THREADS_BEGIN_N_1D_FFT_4THREADS;
+ }
+
+ /**
+ * Returns the minimal size of 2D data for which threads are used.
+ *
+ * @return the minimal size of 2D data for which threads are used
+ */
+ public static long getThreadsBeginN_2D()
+ {
+ return THREADS_BEGIN_N_2D;
+ }
+
+ /**
+ * Returns the minimal size of 3D data for which threads are used.
+ *
+ * @return the minimal size of 3D data for which threads are used
+ */
+ public static long getThreadsBeginN_3D()
+ {
+ return THREADS_BEGIN_N_3D;
+ }
+
+ /**
+ * Returns the minimal size for which JLargeArrays are used.
+ *
+ * @return the minimal size for which JLargeArrays are used
+ */
+ public static long getLargeArraysBeginN()
+ {
+ return LARGE_ARAYS_BEGIN_N;
+ }
+
+ /**
+ * Sets the minimal size of 1D data for which two threads are used.
+ *
+ * @param n the minimal size of 1D data for which two threads are used
+ */
+ public static void setThreadsBeginN_1D_FFT_2Threads(long n)
+ {
+ if (n < 1024) {
+ THREADS_BEGIN_N_1D_FFT_2THREADS = 1024;
+ } else {
+ THREADS_BEGIN_N_1D_FFT_2THREADS = n;
+ }
+ }
+
+ /**
+ * Sets the minimal size of 1D data for which four threads are used.
+ *
+ * @param n the minimal size of 1D data for which four threads are used
+ */
+ public static void setThreadsBeginN_1D_FFT_4Threads(long n)
+ {
+ if (n < 1024) {
+ THREADS_BEGIN_N_1D_FFT_4THREADS = 1024;
+ } else {
+ THREADS_BEGIN_N_1D_FFT_4THREADS = n;
+ }
+ }
+
+ /**
+ * Sets the minimal size of 2D data for which threads are used.
+ *
+ * @param n the minimal size of 2D data for which threads are used
+ */
+ public static void setThreadsBeginN_2D(long n)
+ {
+ if (n < 4096) {
+ THREADS_BEGIN_N_2D = 4096;
+ } else {
+ THREADS_BEGIN_N_2D = n;
+ }
+ }
+
+ /**
+ * Sets the minimal size of 3D data for which threads are used.
+ *
+ * @param n the minimal size of 3D data for which threads are used
+ */
+ public static void setThreadsBeginN_3D(long n)
+ {
+ THREADS_BEGIN_N_3D = n;
+ }
+
+ /**
+ * Resets the minimal size of 1D data for which two and four threads are
+ * used.
+ */
+ public static void resetThreadsBeginN_FFT()
+ {
+ THREADS_BEGIN_N_1D_FFT_2THREADS = 8192;
+ THREADS_BEGIN_N_1D_FFT_4THREADS = 65536;
+ }
+
+ /**
+ * Resets the minimal size of 2D and 3D data for which threads are used.
+ */
+ public static void resetThreadsBeginN()
+ {
+ THREADS_BEGIN_N_2D = 65536;
+ THREADS_BEGIN_N_3D = 65536;
+ }
+
+ /**
+ * Sets the minimal size for which JLargeArrays are used.
+ *
+ * @param n the maximal size for which JLargeArrays are used
+ */
+ public static void setLargeArraysBeginN(long n)
+ {
+ if (n < 1) {
+ LARGE_ARAYS_BEGIN_N = 1;
+ } else if (n > (1 << 28)) {
+ LARGE_ARAYS_BEGIN_N = (1 << 28);
+ } else {
+ LARGE_ARAYS_BEGIN_N = n;
+ }
+ }
+
+ /**
+ * Returns the closest power-of-two number greater than or equal to x.
+ *
+ * @param x input value
+ *
+ * @return the closest power-of-two number greater than or equal to x
+ */
+ public static int nextPow2(int x)
+ {
+ if (x < 1) {
+ throw new IllegalArgumentException("x must be greater or equal 1");
+ }
+ if ((x & (x - 1)) == 0) {
+ return x; // x is already a power-of-two number
+ }
+ x |= (x >>> 1);
+ x |= (x >>> 2);
+ x |= (x >>> 4);
+ x |= (x >>> 8);
+ x |= (x >>> 16);
+ return x + 1;
+ }
+
+ /**
+ * Returns the closest power-of-two number greater than or equal to x.
+ *
+ * @param x input value
+ *
+ * @return the closest power-of-two number greater than or equal to x
+ */
+ public static long nextPow2(long x)
+ {
+ if (x < 1) {
+ throw new IllegalArgumentException("x must be greater or equal 1");
+ }
+ if ((x & (x - 1l)) == 0) {
+ return x; // x is already a power-of-two number
+ }
+ x |= (x >>> 1l);
+ x |= (x >>> 2l);
+ x |= (x >>> 4l);
+ x |= (x >>> 8l);
+ x |= (x >>> 16l);
+ x |= (x >>> 32l);
+ return x + 1l;
+ }
+
+ /**
+ * Returns the closest power-of-two number less than or equal to x.
+ *
+ * @param x input value
+ *
+ * @return the closest power-of-two number less then or equal to x
+ */
+ public static int prevPow2(int x)
+ {
+ if (x < 1) {
+ throw new IllegalArgumentException("x must be greater or equal 1");
+ }
+ return (int) Math.pow(2, Math.floor(Math.log(x) / Math.log(2)));
+ }
+
+ /**
+ * Returns the closest power-of-two number less than or equal to x.
+ *
+ * @param x input value
+ *
+ * @return the closest power-of-two number less then or equal to x
+ */
+ public static long prevPow2(long x)
+ {
+ if (x < 1) {
+ throw new IllegalArgumentException("x must be greater or equal 1");
+ }
+ return (long) Math.pow(2, Math.floor(Math.log(x) / Math.log(2)));
+ }
+
+ /**
+ * Checks if x is a power-of-two number.
+ *
+ * @param x input value
+ *
+ * @return true if x is a power-of-two number
+ */
+ public static boolean isPowerOf2(int x)
+ {
+ if (x <= 0) {
+ return false;
+ } else {
+ return (x & (x - 1)) == 0;
+ }
+ }
+
+ /**
+ * Checks if x is a power-of-two number.
+ *
+ * @param x input value
+ *
+ * @return true if x is a power-of-two number
+ */
+ public static boolean isPowerOf2(long x)
+ {
+ if (x <= 0) {
+ return false;
+ } else {
+ return (x & (x - 1l)) == 0;
+ }
+ }
+
+ /**
+ * Causes the currently executing thread to sleep (temporarily cease
+ * execution) for the specified number of milliseconds.
+ *
+ * @param millis the length of time to sleep in milliseconds
+ */
+ public static void sleep(long millis)
+ {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Submits a Runnable task for execution and returns a Future representing
+ * that task.
+ *
+ * @param task a Runnable task for execution
+ *
+ * @return a Future representing the task
+ */
+ public static Future> submit(Runnable task)
+ {
+ if (THREAD_POOL.isShutdown() || THREAD_POOL.isTerminated()) {
+ THREAD_POOL = Executors.newCachedThreadPool(new CustomThreadFactory(new CustomExceptionHandler()));
+ }
+ return THREAD_POOL.submit(task);
+ }
+
+ /**
+ * Shutdowns all submitted tasks.
+ */
+ public static void shutdownAndAwaitTermination()
+ {
+ THREAD_POOL.shutdown(); // Disable new tasks from being submitted
+ try {
+ // Wait a while for existing tasks to terminate
+ if (!THREAD_POOL.awaitTermination(60, TimeUnit.SECONDS)) {
+ THREAD_POOL.shutdownNow(); // Cancel currently executing tasks
+ // Wait a while for tasks to respond to being cancelled
+ if (!THREAD_POOL.awaitTermination(60, TimeUnit.SECONDS))
+ System.err.println("Pool did not terminate");
+ }
+ } catch (InterruptedException ie) {
+ // (Re-)Cancel if current thread also interrupted
+ THREAD_POOL.shutdownNow();
+ // Preserve interrupt status
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ /**
+ * Waits for all threads to complete computation.
+ *
+ * @param futures array of Future objects
+ */
+ public static void waitForCompletion(Future>[] futures)
+ {
+ int size = futures.length;
+ try {
+ for (int j = 0; j < size; j++) {
+ futures[j].get();
+ }
+ } catch (ExecutionException ex) {
+ ex.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/org/jtransforms/fft/FloatFFT_1D.java b/org/fairsim/extern/jtransforms/FloatFFT_1D.java
similarity index 97%
rename from src/main/java/org/jtransforms/fft/FloatFFT_1D.java
rename to org/fairsim/extern/jtransforms/FloatFFT_1D.java
index a6e7971..e13b0dd 100644
--- a/src/main/java/org/jtransforms/fft/FloatFFT_1D.java
+++ b/org/fairsim/extern/jtransforms/FloatFFT_1D.java
@@ -1,7682 +1,7724 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.CommonUtils;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-import pl.edu.icm.jlargearrays.LongLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 1D Discrete Fourier Transform (DFT) of complex and real, single
- * precision data. The size of the data can be an arbitrary number. This is a
- * parallel implementation of split-radix and mixed-radix algorithms optimized
- * for SMP systems.
- *
- * This code is derived from General Purpose FFT Package written by Takuya Ooura
- * (http://www.kurims.kyoto-u.ac.jp/~ooura/fft.html) and from JFFTPack written
- * by Baoshe Zhang (http://jfftpack.sourceforge.net/)
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public final class FloatFFT_1D {
-
- private static enum Plans {
-
- SPLIT_RADIX, MIXED_RADIX, BLUESTEIN
- }
-
- private int n;
-
- private long nl;
-
- private int nBluestein;
-
- private long nBluesteinl;
-
- private int[] ip;
-
- private LongLargeArray ipl;
-
- private float[] w;
-
- private FloatLargeArray wl;
-
- private int nw;
-
- private long nwl;
-
- private int nc;
-
- private long ncl;
-
- private float[] wtable;
-
- private FloatLargeArray wtablel;
-
- private float[] wtable_r;
-
- private FloatLargeArray wtable_rl;
-
- private float[] bk1;
-
- private FloatLargeArray bk1l;
-
- private float[] bk2;
-
- private FloatLargeArray bk2l;
-
- private Plans plan;
-
- private boolean useLargeArrays;
-
- private static final int[] factors = {4, 2, 3, 5};
-
- private static final float PI = 3.14159265358979311599796346854418516f;
-
- private static final float TWO_PI = 6.28318530717958623199592693708837032f;
-
- /**
- * Creates new instance of FloatFFT_1D.
- *
- * @param n size of data
- */
- public FloatFFT_1D(long n) {
- if (n < 1) {
- throw new IllegalArgumentException("n must be greater than 0");
- }
- this.useLargeArrays = n >= ConcurrencyUtils.getLargeArraysBeginN();
- if(this.useLargeArrays == false) {
- this.n = (int) n;
- if (!ConcurrencyUtils.isPowerOf2(n)) {
- if (CommonUtils.getReminder(n, factors) >= 211) {
- plan = Plans.BLUESTEIN;
- nBluestein = ConcurrencyUtils.nextPow2(this.n * 2 - 1);
- bk1 = new float[2 * nBluestein];
- bk2 = new float[2 * nBluestein];
- this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(nBluestein + 0.5f) / Math.log(2)) / 2))];
- this.w = new float[nBluestein];
- int twon = 2 * nBluestein;
- nw = twon >> 2;
- CommonUtils.makewt(nw, ip, w);
- nc = nBluestein >> 2;
- CommonUtils.makect(nc, w, nw, ip);
- bluesteini();
- } else {
- plan = Plans.MIXED_RADIX;
- wtable = new float[4 * this.n + 15];
- wtable_r = new float[2 * this.n + 15];
- cffti();
- rffti();
- }
- } else {
- plan = Plans.SPLIT_RADIX;
- this.ip = new int[2 + (int) Math.ceil(2 + (1 << (int) (Math.log(n + 0.5f) / Math.log(2)) / 2))];
- this.w = new float[this.n];
- int twon = 2 * this.n;
- nw = twon >> 2;
- CommonUtils.makewt(nw, ip, w);
- nc = this.n >> 2;
- CommonUtils.makect(nc, w, nw, ip);
- }
- } else {
- this.nl = n;
- if (!ConcurrencyUtils.isPowerOf2(nl)) {
- if (CommonUtils.getReminder(nl, factors) >= 211) {
- plan = Plans.BLUESTEIN;
- nBluesteinl = ConcurrencyUtils.nextPow2(nl * 2 - 1);
- bk1l = new FloatLargeArray(2l * nBluesteinl, false);
- bk2l = new FloatLargeArray(2l * nBluesteinl, false);
- this.ipl = new LongLargeArray(2l + (long) Math.ceil(2l + (1l << (long) (Math.log(nBluesteinl + 0.5f) / Math.log(2.)) / 2)), false);
- this.wl = new FloatLargeArray(nBluesteinl, false);
- long twon = 2 * nBluesteinl;
- nwl = twon >> 2l;
- CommonUtils.makewt(nwl, ipl, wl);
- ncl = nBluesteinl >> 2l;
- CommonUtils.makect(ncl, wl, nwl, ipl);
- bluesteinil();
- } else {
- plan = Plans.MIXED_RADIX;
- wtablel = new FloatLargeArray(4 * nl + 15, false);
- wtable_rl = new FloatLargeArray(2 * nl + 15, false);
- cfftil();
- rfftil();
- }
- } else {
- plan = Plans.SPLIT_RADIX;
- this.ipl = new LongLargeArray(2l + (long) Math.ceil(2 + (1l << (long) (Math.log(nl + 0.5f) / Math.log(2)) / 2)), false);
- this.wl = new FloatLargeArray(nl, false);
- long twon = 2 * nl;
- nwl = twon >> 2l;
- CommonUtils.makewt(nwl, ipl, wl);
- ncl = nl >> 2l;
- CommonUtils.makect(ncl, wl, nwl, ipl);
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of complex data leaving the result in
- * a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:
- *
- * *
- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - */ - public void complexForward(float[] a) { - complexForward(a, 0); - } - - /** - * Computes 1D forward DFT of complex data leaving the result in - *
a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - */ - public void complexForward(FloatLargeArray a) { - complexForward(a, 0); - } - - /** - * Computes 1D forward DFT of complex data leaving the result in - *
a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- */
- public void complexForward(float[] a, int offa) {
- if (useLargeArrays) {
- complexForward(new FloatLargeArray(a), offa);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftbsub(2 * n, a, offa, ip, nw, w);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, -1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of complex data leaving the result in
- * a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- */
- public void complexForward(FloatLargeArray a, long offa) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- complexForward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftbsub(2 * nl, a, offa, ipl, nwl, wl);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, -1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of complex data leaving the result in
- * a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(float[] a, boolean scale) { - complexInverse(a, 0, scale); - } - - /** - * Computes 1D inverse DFT of complex data leaving the result in - *
a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(FloatLargeArray a, boolean scale) { - complexInverse(a, 0, scale); - } - - /** - * Computes 1D inverse DFT of complex data leaving the result in - *
a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- * @param scale if true then scaling is performed
- */
- public void complexInverse(float[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- complexInverse(new FloatLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftfsub(2 * n, a, offa, ip, nw, w);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, +1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, 1);
- break;
- }
- if (scale) {
- CommonUtils.scale(n, 1.0f / (float) n, a, offa, true);
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of complex data leaving the result in
- * a. Complex number is stored as two float values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- * @param scale if true then scaling is performed
- */
- public void complexInverse(FloatLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- complexInverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftfsub(2 * nl, a, offa, ipl, nwl, wl);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, +1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, 1);
- break;
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0f / (float) nl, a, offa, true);
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(float[] a) {
- realForward(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(FloatLargeArray a) {
- realForward(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForward(float[] a, int offa) {
- if (useLargeArrays) {
- realForward(new FloatLargeArray(a), offa);
- } else {
- if (n == 1) {
- return;
- }
-
- switch (plan) {
- case SPLIT_RADIX:
- float xi;
-
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- CommonUtils.rftfsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftx020(a, offa);
- }
- xi = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- a[offa + 1] = xi;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (int k = n - 1; k >= 2; k--) {
- int idx = offa + k;
- float tmp = a[idx];
- a[idx] = a[idx - 1];
- a[idx - 1] = tmp;
- }
- break;
- case BLUESTEIN:
- bluestein_real_forward(a, offa);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForward(FloatLargeArray a, long offa) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realForward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
-
- switch (plan) {
- case SPLIT_RADIX:
- float xi;
-
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftx020(a, offa);
- }
- xi = a.getFloat(offa) - a.getFloat(offa + 1);
- a.setFloat(offa, a.getFloat(offa) + a.getFloat(offa + 1));
- a.setFloat(offa + 1, xi);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (long k = nl - 1; k >= 2; k--) {
- long idx = offa + k;
- float tmp = a.getFloat(idx);
- a.setFloat(idx, a.getFloat(idx - 1));
- a.setFloat(idx - 1, tmp);
- }
- break;
- case BLUESTEIN:
- bluestein_real_forward(a, offa);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary parts equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(float[] a) {
- realForwardFull(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary parts equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(FloatLargeArray a) {
- realForwardFull(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForwardFull(final float[] a, final int offa) {
-
- if (useLargeArrays) {
- realForwardFull(new FloatLargeArray(a), offa);
- } else {
- final int twon = 2 * n;
- switch (plan) {
- case SPLIT_RADIX:
- realForward(a, offa);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- int k = n / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- for (int k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int k = 0; k < n / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- a[offa + n] = -a[offa + 1];
- a[offa + 1] = 0;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- } else {
- m = (n + 1) / 2;
- }
- for (int k = 1; k < m; k++) {
- int idx1 = offa + twon - 2 * k;
- int idx2 = offa + 2 * k;
- a[idx1 + 1] = -a[idx2];
- a[idx1] = a[idx2 - 1];
- }
- for (int k = 1; k < n; k++) {
- int idx = offa + n - k;
- float tmp = a[idx + 1];
- a[idx + 1] = a[idx];
- a[idx] = tmp;
- }
- a[offa + 1] = 0;
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForwardFull(final FloatLargeArray a, final long offa) {
-
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realForwardFull(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- final long twon = 2 * nl;
- switch (plan) {
- case SPLIT_RADIX:
- realForward(a, offa);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- long k = nl / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- for (long k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setFloat(idx2, a.getFloat(offa + idx1));
- a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long k = 0; k < nl / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setFloat(idx2, a.getFloat(offa + idx1));
- a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
- }
- }
- a.setFloat(offa + nl, -a.getFloat(offa + 1));
- a.setFloat(offa + 1, 0);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- } else {
- m = (nl + 1) / 2;
- }
- for (long k = 1; k < m; k++) {
- long idx1 = offa + twon - 2 * k;
- long idx2 = offa + 2 * k;
- a.setFloat(idx1 + 1, -a.getFloat(idx2));
- a.setFloat(idx1, a.getFloat(idx2 - 1));
- }
- for (long k = 1; k < nl; k++) {
- long idx = offa + nl - k;
- float tmp = a.getFloat(idx + 1);
- a.setFloat(idx + 1, a.getFloat(idx));
- a.setFloat(idx, tmp);
- }
- a.setFloat(offa + 1, 0);
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(float[] a, boolean scale) {
- realInverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(FloatLargeArray a, boolean scale) {
- realInverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(float[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- realInverse(new FloatLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- a[offa + 1] = 0.5f * (a[offa] - a[offa + 1]);
- a[offa] -= a[offa + 1];
- if (n > 4) {
- CommonUtils.rftfsub(n, a, offa, nc, w, nw);
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- } else if (n == 4) {
- CommonUtils.cftxc020(a, offa);
- }
- if (scale) {
- CommonUtils.scale(n, 1.0f / (n / 2.0f), a, offa, false);
- }
- break;
- case MIXED_RADIX:
- for (int k = 2; k < n; k++) {
- int idx = offa + k;
- float tmp = a[idx - 1];
- a[idx - 1] = a[idx];
- a[idx] = tmp;
- }
- rfftb(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- break;
- }
- }
-
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(FloatLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- a.setFloat(offa + 1, 0.5f * (a.getFloat(offa) - a.getFloat(offa + 1)));
- a.setFloat(offa, a.getFloat(offa) - a.getFloat(offa + 1));
- if (nl > 4) {
- CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- } else if (nl == 4) {
- CommonUtils.cftxc020(a, offa);
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0f / (nl / 2.0f), a, offa, false);
- }
- break;
- case MIXED_RADIX:
- for (long k = 2; k < nl; k++) {
- long idx = offa + k;
- float tmp = a.getFloat(idx - 1);
- a.setFloat(idx - 1, a.getFloat(idx));
- a.setFloat(idx, tmp);
- }
- rfftb(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- break;
- }
- }
-
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(float[] a, boolean scale) {
- realInverseFull(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(FloatLargeArray a, boolean scale) {
- realInverseFull(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(final float[] a, final int offa, boolean scale) {
- if (useLargeArrays) {
- realInverseFull(new FloatLargeArray(a), offa, scale);
- } else {
- final int twon = 2 * n;
- switch (plan) {
- case SPLIT_RADIX:
- realInverse2(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- int k = n / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- for (int k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int k = 0; k < n / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- a[offa + n] = -a[offa + 1];
- a[offa + 1] = 0;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- } else {
- m = (n + 1) / 2;
- }
- for (int k = 1; k < m; k++) {
- int idx1 = offa + 2 * k;
- int idx2 = offa + twon - 2 * k;
- a[idx1] = -a[idx1];
- a[idx2 + 1] = -a[idx1];
- a[idx2] = a[idx1 - 1];
- }
- for (int k = 1; k < n; k++) {
- int idx = offa + n - k;
- float tmp = a[idx + 1];
- a[idx + 1] = a[idx];
- a[idx] = tmp;
- }
- a[offa + 1] = 0;
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, 1);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, true);
- }
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(final FloatLargeArray a, final long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverseFull(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- final long twon = 2 * nl;
- switch (plan) {
- case SPLIT_RADIX:
- realInverse2(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- long k = nl / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- for (long k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setFloat(idx2, a.getFloat(offa + idx1));
- a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long k = 0; k < nl / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setFloat(idx2, a.getFloat(offa + idx1));
- a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
- }
- }
- a.setFloat(offa + nl, -a.getFloat(offa + 1));
- a.setFloat(offa + 1, 0);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- } else {
- m = (nl + 1) / 2;
- }
- for (long k = 1; k < m; k++) {
- long idx1 = offa + 2 * k;
- long idx2 = offa + twon - 2 * k;
- a.setFloat(idx1, -a.getFloat(idx1));
- a.setFloat(idx2 + 1, -a.getFloat(idx1));
- a.setFloat(idx2, a.getFloat(idx1 - 1));
- }
- for (long k = 1; k < nl; k++) {
- long idx = offa + nl - k;
- float tmp = a.getFloat(idx + 1);
- a.setFloat(idx + 1, a.getFloat(idx));
- a.setFloat(idx, tmp);
- }
- a.setFloat(offa + 1, 0);
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, 1);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, true);
- }
- break;
- }
- }
- }
-
- protected void realInverse2(float[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- realInverse2(new FloatLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- float xi;
-
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- CommonUtils.rftbsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- }
- xi = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- a[offa + 1] = xi;
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (int k = n - 1; k >= 2; k--) {
- int idx = offa + k;
- float tmp = a[idx];
- a[idx] = a[idx - 1];
- a[idx - 1] = tmp;
- }
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- for (int i = 1; i < m; i++) {
- int idx = offa + 2 * i + 1;
- a[idx] = -a[idx];
- }
- } else {
- m = (n - 1) / 2;
- for (int i = 0; i < m; i++) {
- int idx = offa + 2 * i + 1;
- a[idx] = -a[idx];
- }
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse2(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- break;
- }
- }
- }
-
- protected void realInverse2(FloatLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverse2(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- float xi;
-
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- CommonUtils.rftbsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- }
- xi = a.getFloat(offa) - a.getFloat(offa + 1);
- a.setFloat(offa, a.getFloat(offa) + a.getFloat(offa + 1));
- a.setFloat(offa + 1, xi);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (long k = nl - 1; k >= 2; k--) {
- long idx = offa + k;
- float tmp = a.getFloat(idx);
- a.setFloat(idx, a.getFloat(idx - 1));
- a.setFloat(idx - 1, tmp);
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- for (long i = 1; i < m; i++) {
- long idx = offa + 2 * i + 1;
- a.setFloat(idx, -a.getFloat(idx));
- }
- } else {
- m = (nl - 1) / 2;
- for (long i = 0; i < m; i++) {
- long idx = offa + 2 * i + 1;
- a.setFloat(idx, -a.getFloat(idx));
- }
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse2(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
- }
- break;
- }
- }
- }
-
-
- /* -------- initializing routines -------- */
-
- /*---------------------------------------------------------
- cffti: initialization of Complex FFT
- --------------------------------------------------------*/
- void cffti(int n, int offw) {
- if (n == 1) {
- return;
- }
-
- final int twon = 2 * n;
- final int fourn = 4 * n;
- float argh;
- int idot, ntry = 0, i, j;
- float argld;
- int i1, k1, l1, l2, ib;
- float fi;
- int ld, ii, nf, ipll, nll, nq, nr;
- float arg;
- int ido, ipm;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtable[offw + nf + 1 + fourn] = ntry;
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + fourn;
- wtable[offw + idx + 1] = wtable[offw + idx];
- }
- wtable[offw + 2 + fourn] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable[offw + fourn] = n;
- wtable[offw + 1 + fourn] = nf;
- argh = TWO_PI / (float) n;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable[offw + k1 + 1 + fourn];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtable[offw + i - 1 + twon] = 1;
- wtable[offw + i + twon] = 0;
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + twon;
- wtable[offw + idx - 1] = (float)Math.cos(arg);
- wtable[offw + idx] = (float)Math.sin(arg);
- }
- if (ipll > 5) {
- int idx1 = i1 + twon;
- int idx2 = i + twon;
- wtable[offw + idx1 - 1] = wtable[offw + idx2 - 1];
- wtable[offw + idx1] = wtable[offw + idx2];
- }
- }
- l1 = l2;
- }
-
- }
-
- final void cffti() {
- if (n == 1) {
- return;
- }
-
- final int twon = 2 * n;
- final int fourn = 4 * n;
- float argh;
- int idot, ntry = 0, i, j;
- float argld;
- int i1, k1, l1, l2, ib;
- float fi;
- int ld, ii, nf, ipll, nll, nq, nr;
- float arg;
- int ido, ipm;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtable[nf + 1 + fourn] = ntry;
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + fourn;
- wtable[idx + 1] = wtable[idx];
- }
- wtable[2 + fourn] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable[fourn] = n;
- wtable[1 + fourn] = nf;
- argh = TWO_PI / (float) n;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable[k1 + 1 + fourn];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtable[i - 1 + twon] = 1;
- wtable[i + twon] = 0;
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + twon;
- wtable[idx - 1] = (float)Math.cos(arg);
- wtable[idx] = (float)Math.sin(arg);
- }
- if (ipll > 5) {
- int idx1 = i1 + twon;
- int idx2 = i + twon;
- wtable[idx1 - 1] = wtable[idx2 - 1];
- wtable[idx1] = wtable[idx2];
- }
- }
- l1 = l2;
- }
-
- }
-
- final void cfftil() {
- if (nl == 1) {
- return;
- }
-
- final long twon = 2 * nl;
- final long fourn = 4 * nl;
- float argh;
- long idot, ntry = 0, i, j;
- float argld;
- long i1, k1, l1, l2, ib;
- float fi;
- long ld, ii, nf, ipll, nl2, nq, nr;
- float arg;
- long ido, ipm;
-
- nl2 = nl;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[(int) (j - 1)];
- } else {
- ntry += 2;
- }
- do {
- nq = nl2 / ntry;
- nr = nl2 - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtablel.setFloat(nf + 1 + fourn, ntry);
- nl2 = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- long idx = ib + fourn;
- wtablel.setFloat(idx + 1, wtablel.getFloat(idx));
- }
- wtablel.setFloat(2 + fourn, 2);
- }
- } while (nl2 != 1);
- break;
- }
- wtablel.setFloat(fourn, nl);
- wtablel.setFloat(1 + fourn, nf);
- argh = TWO_PI / (float) nl;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (long) wtablel.getFloat(k1 + 1 + fourn);
- ld = 0;
- l2 = l1 * ipll;
- ido = nl / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtablel.setFloat(i - 1 + twon, 1);
- wtablel.setFloat(i + twon, 0);
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- long idx = i + twon;
- wtablel.setFloat(idx - 1, (float)Math.cos(arg));
- wtablel.setFloat(idx, (float)Math.sin(arg));
- }
- if (ipll > 5) {
- long idx1 = i1 + twon;
- long idx2 = i + twon;
- wtablel.setFloat(idx1 - 1, wtablel.getFloat(idx2 - 1));
- wtablel.setFloat(idx1, wtablel.getFloat(idx2));
- }
- }
- l1 = l2;
- }
-
- }
-
- void rffti() {
-
- if (n == 1) {
- return;
- }
- final int twon = 2 * n;
- float argh;
- int ntry = 0, i, j;
- float argld;
- int k1, l1, l2, ib;
- float fi;
- int ld, ii, nf, ipll, nll, is, nq, nr;
- float arg;
- int ido, ipm;
- int nfm1;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- ++j;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- ++nf;
- wtable_r[nf + 1 + twon] = ntry;
-
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + twon;
- wtable_r[idx + 1] = wtable_r[idx];
- }
- wtable_r[2 + twon] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable_r[twon] = n;
- wtable_r[1 + twon] = nf;
- argh = TWO_PI / (float) (n);
- is = 0;
- nfm1 = nf - 1;
- l1 = 1;
- if (nfm1 == 0) {
- return;
- }
- for (k1 = 1; k1 <= nfm1; k1++) {
- ipll = (int) wtable_r[k1 + 1 + twon];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; ++j) {
- ld += l1;
- i = is;
- argld = (float) ld * argh;
-
- fi = 0;
- for (ii = 3; ii <= ido; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + n;
- wtable_r[idx - 2] = (float)Math.cos(arg);
- wtable_r[idx - 1] = (float)Math.sin(arg);
- }
- is += ido;
- }
- l1 = l2;
- }
- }
-
- void rfftil() {
-
- if (nl == 1) {
- return;
- }
- final long twon = 2 * nl;
- float argh;
- long ntry = 0, i, j;
- float argld;
- long k1, l1, l2, ib;
- float fi;
- long ld, ii, nf, ipll, nl2, is, nq, nr;
- float arg;
- long ido, ipm;
- long nfm1;
-
- nl2 = nl;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- ++j;
- if (j <= 4) {
- ntry = factors[(int) (j - 1)];
- } else {
- ntry += 2;
- }
- do {
- nq = nl2 / ntry;
- nr = nl2 - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- ++nf;
- wtable_rl.setFloat(nf + 1 + twon, ntry);
-
- nl2 = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- long idx = ib + twon;
- wtable_rl.setFloat(idx + 1, wtable_rl.getFloat(idx));
- }
- wtable_rl.setFloat(2 + twon, 2);
- }
- } while (nl2 != 1);
- break;
- }
- wtable_rl.setFloat(twon, nl);
- wtable_rl.setFloat(1 + twon, nf);
- argh = TWO_PI / (float) (nl);
- is = 0;
- nfm1 = nf - 1;
- l1 = 1;
- if (nfm1 == 0) {
- return;
- }
- for (k1 = 1; k1 <= nfm1; k1++) {
- ipll = (long) wtable_rl.getFloat(k1 + 1 + twon);
- ld = 0;
- l2 = l1 * ipll;
- ido = nl / l2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; ++j) {
- ld += l1;
- i = is;
- argld = (float) ld * argh;
-
- fi = 0;
- for (ii = 3; ii <= ido; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- long idx = i + nl;
- wtable_rl.setFloat(idx - 2, (float)Math.cos(arg));
- wtable_rl.setFloat(idx - 1, (float)Math.sin(arg));
- }
- is += ido;
- }
- l1 = l2;
- }
- }
-
- private void bluesteini() {
- int k = 0;
- float arg;
- float pi_n = PI / n;
- bk1[0] = 1;
- bk1[1] = 0;
- for (int i = 1; i < n; i++) {
- k += 2 * i - 1;
- if (k >= 2 * n) {
- k -= 2 * n;
- }
- arg = pi_n * k;
- bk1[2 * i] = (float)Math.cos(arg);
- bk1[2 * i + 1] = (float)Math.sin(arg);
- }
- float scale = 1.0f / nBluestein;
- bk2[0] = bk1[0] * scale;
- bk2[1] = bk1[1] * scale;
- for (int i = 2; i < 2 * n; i += 2) {
- bk2[i] = bk1[i] * scale;
- bk2[i + 1] = bk1[i + 1] * scale;
- bk2[2 * nBluestein - i] = bk2[i];
- bk2[2 * nBluestein - i + 1] = bk2[i + 1];
- }
- CommonUtils.cftbsub(2 * nBluestein, bk2, 0, ip, nw, w);
- }
-
- private void bluesteinil() {
- long k = 0;
- float arg;
- float pi_n = PI / nl;
- bk1l.setFloat(0, 1);
- bk1l.setFloat(1, 0);
- for (int i = 1; i < nl; i++) {
- k += 2 * i - 1;
- if (k >= 2 * nl) {
- k -= 2 * nl;
- }
- arg = pi_n * k;
- bk1l.setFloat(2 * i, (float)Math.cos(arg));
- bk1l.setFloat(2 * i + 1, (float)Math.sin(arg));
- }
- float scale = 1.0f / nBluesteinl;
- bk2l.setFloat(0, bk1l.getFloat(0) * scale);
- bk2l.setFloat(1, bk1l.getFloat(1) * scale);
- for (int i = 2; i < 2 * nl; i += 2) {
- bk2l.setFloat(i, bk1l.getFloat(i) * scale);
- bk2l.setFloat(i + 1, bk1l.getFloat(i + 1) * scale);
- bk2l.setFloat(2 * nBluesteinl - i, bk2l.getFloat(i));
- bk2l.setFloat(2 * nBluesteinl - i + 1, bk2l.getFloat(i + 1));
- }
- CommonUtils.cftbsub(2 * nBluesteinl, bk2l, 0, ipl, nwl, wl);
- }
-
- private void bluestein_complex(final float[] a, final int offa, final int isign) {
- final float[] ak = new float[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- }
-
- private void bluestein_complex(final FloatLargeArray a, final long offa, final int isign) {
- final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(idx4, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(idx4, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- } else {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(idx4, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(idx4, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- }
- }
- }
-
- private void bluestein_real_full(final float[] a, final int offa, final int isign) {
- final float[] ak = new float[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- }
-
- private void bluestein_real_full(final FloatLargeArray a, final long offa, final long isign) {
- final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- } else {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- }
- }
- }
-
- private void bluestein_real_forward(final float[] a, final int offa) {
- final float[] ak = new float[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (n % 2 == 0) {
- a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n] + bk1[n + 1] * ak[n + 1];
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
- a[offa + 1] = -bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- a[offa + n - 1] = bk1[n - 1] * ak[n - 1] + bk1[n] * ak[n];
- }
-
- }
-
- private void bluestein_real_forward(final FloatLargeArray a, final long offa) {
- final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (nl % 2 == 0) {
- a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) + bk1l.getFloat(1) * ak.getFloat(1));
- a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl) + bk1l.getFloat(nl + 1) * ak.getFloat(nl + 1));
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) + bk1l.getFloat(1) * ak.getFloat(1));
- a.setFloat(offa + 1, -bk1l.getFloat(nl) * ak.getFloat(nl - 1) + bk1l.getFloat(nl - 1) * ak.getFloat(nl));
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- a.setFloat(offa + nl - 1, bk1l.getFloat(nl - 1) * ak.getFloat(nl - 1) + bk1l.getFloat(nl) * ak.getFloat(nl));
- }
-
- }
-
- private void bluestein_real_inverse(final float[] a, final int offa) {
- final float[] ak = new float[2 * nBluestein];
- if (n % 2 == 0) {
- ak[0] = a[offa] * bk1[0];
- ak[1] = a[offa] * bk1[1];
-
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
-
- ak[n] = a[offa + 1] * bk1[n];
- ak[n + 1] = a[offa + 1] * bk1[n + 1];
-
- for (int i = n / 2 + 1; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + 2 * n - idx1;
- int idx4 = idx3 + 1;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
- }
-
- } else {
- ak[0] = a[offa] * bk1[0];
- ak[1] = a[offa] * bk1[1];
-
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
-
- ak[n - 1] = a[offa + n - 1] * bk1[n - 1] - a[offa + 1] * bk1[n];
- ak[n] = a[offa + n - 1] * bk1[n] + a[offa + 1] * bk1[n - 1];
-
- ak[n + 1] = a[offa + n - 1] * bk1[n + 1] + a[offa + 1] * bk1[n + 2];
- ak[n + 2] = a[offa + n - 1] * bk1[n + 2] - a[offa + 1] * bk1[n + 1];
-
- for (int i = (n - 1) / 2 + 2; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + 2 * n - idx1;
- int idx4 = idx3 + 1;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- }
- }
- }
-
- private void bluestein_real_inverse(final FloatLargeArray a, final long offa) {
- final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
- if (nl % 2 == 0) {
- ak.setFloat(0, a.getFloat(offa) * bk1l.getFloat(0));
- ak.setFloat(1, a.getFloat(offa) * bk1l.getFloat(1));
-
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
-
- ak.setFloat(nl, a.getFloat(offa + 1) * bk1l.getFloat(nl));
- ak.setFloat(nl + 1, a.getFloat(offa + 1) * bk1l.getFloat(nl + 1));
-
- for (long i = nl / 2 + 1; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + 2 * nl - idx1;
- long idx4 = idx3 + 1;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) - a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
-
- } else {
- ak.setFloat(0, a.getFloat(offa) * bk1l.getFloat(0));
- ak.setFloat(1, a.getFloat(offa) * bk1l.getFloat(1));
-
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
-
- ak.setFloat(nl - 1, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl - 1) - a.getFloat(offa + 1) * bk1l.getFloat(nl));
- ak.setFloat(nl, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl) + a.getFloat(offa + 1) * bk1l.getFloat(nl - 1));
-
- ak.setFloat(nl + 1, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl + 1) + a.getFloat(offa + 1) * bk1l.getFloat(nl + 2));
- ak.setFloat(nl + 2, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl + 2) - a.getFloat(offa + 1) * bk1l.getFloat(nl + 1));
-
- for (long i = (nl - 1) / 2 + 2; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + 2 * nl - idx1;
- long idx4 = idx3 + 1;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) - a.getFloat(idx4) * bk1l.getFloat(idx1));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + i, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + i, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- }
- }
- }
-
- private void bluestein_real_inverse2(final float[] a, final int offa) {
- final float[] ak = new float[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (n % 2 == 0) {
- a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n] - bk1[n + 1] * ak[n + 1];
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- a[offa + n - 1] = bk1[n - 1] * ak[n - 1] - bk1[n] * ak[n];
- }
- }
-
- private void bluestein_real_inverse2(final FloatLargeArray a, final long offa) {
- final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
- ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
- ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
- ak.setFloat(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (nl % 2 == 0) {
- a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) - bk1l.getFloat(1) * ak.getFloat(1));
- a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl) - bk1l.getFloat(nl + 1) * ak.getFloat(nl + 1));
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- } else {
- a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) - bk1l.getFloat(1) * ak.getFloat(1));
- a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl - 1) + bk1l.getFloat(nl - 1) * ak.getFloat(nl));
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
- a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
- }
- a.setFloat(offa + nl - 1, bk1l.getFloat(nl - 1) * ak.getFloat(nl - 1) - bk1l.getFloat(nl) * ak.getFloat(nl));
- }
- }
-
- /*---------------------------------------------------------
- rfftf1: further processing of Real forward FFT
- --------------------------------------------------------*/
- void rfftf(final float a[], final int offa) {
- if (n == 1) {
- return;
- }
- int l1, l2, na, kh, nf, ipll, iw, ido, idl1;
-
- final float[] ch = new float[n];
- final int twon = 2 * n;
- nf = (int) wtable_r[1 + twon];
- na = 1;
- l2 = n;
- iw = twon - 1;
- for (int k1 = 1; k1 <= nf; ++k1) {
- kh = nf - k1;
- ipll = (int) wtable_r[kh + 2 + twon];
- l1 = l2 / ipll;
- ido = n / l2;
- idl1 = ido * l1;
- iw -= (ipll - 1) * ido;
- na = 1 - na;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radf2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf2(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 3:
- if (na == 0) {
- radf3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf3(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 4:
- if (na == 0) {
- radf4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf4(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 5:
- if (na == 0) {
- radf5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf5(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- default:
- if (ido == 1) {
- na = 1 - na;
- }
- if (na == 0) {
- radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- na = 1;
- } else {
- radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- na = 0;
- }
- break;
- }
- l2 = l1;
- }
- if (na == 1) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, n);
- }
-
- /*---------------------------------------------------------
- rfftf1: further processing of Real forward FFT
- --------------------------------------------------------*/
- void rfftf(final FloatLargeArray a, final long offa) {
- if (nl == 1) {
- return;
- }
- long l1, l2, na, kh, nf, iw, ido, idl1;
- int ipll;
-
- final FloatLargeArray ch = new FloatLargeArray(nl, false);
- final long twon = 2 * nl;
- nf = (long) wtable_rl.getFloat(1 + twon);
- na = 1;
- l2 = nl;
- iw = twon - 1;
- for (long k1 = 1; k1 <= nf; ++k1) {
- kh = nf - k1;
- ipll = (int) wtable_rl.getFloat(kh + 2 + twon);
- l1 = l2 / ipll;
- ido = nl / l2;
- idl1 = ido * l1;
- iw -= (ipll - 1) * ido;
- na = 1 - na;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radf2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf2(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 3:
- if (na == 0) {
- radf3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf3(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 4:
- if (na == 0) {
- radf4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf4(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 5:
- if (na == 0) {
- radf5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf5(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- default:
- if (ido == 1) {
- na = 1 - na;
- }
- if (na == 0) {
- radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- na = 1;
- } else {
- radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- na = 0;
- }
- break;
- }
- l2 = l1;
- }
- if (na == 1) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, nl);
- }
-
- /*---------------------------------------------------------
- rfftb1: further processing of Real backward FFT
- --------------------------------------------------------*/
- void rfftb(final float a[], final int offa) {
- if (n == 1) {
- return;
- }
- int l1, l2, na, nf, ipll, iw, ido, idl1;
-
- float[] ch = new float[n];
- final int twon = 2 * n;
- nf = (int) wtable_r[1 + twon];
- na = 0;
- l1 = 1;
- iw = n;
- for (int k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable_r[k1 + 1 + twon];
- l2 = ipll * l1;
- ido = n / l2;
- idl1 = ido * l1;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radb2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb2(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- radb3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb3(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 4:
- if (na == 0) {
- radb4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb4(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- radb5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb5(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- } else {
- radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- }
- if (ido == 1) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * ido;
- }
- if (na == 0) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, n);
- }
-
- /*---------------------------------------------------------
- rfftb1: further processing of Real backward FFT
- --------------------------------------------------------*/
- void rfftb(final FloatLargeArray a, final long offa) {
- if (nl == 1) {
- return;
- }
- long l1, l2, na, nf, iw, ido, idl1;
- int ipll;
- FloatLargeArray ch = new FloatLargeArray(nl, false);
- final long twon = 2 * nl;
- nf = (long) wtable_rl.getFloat(1 + twon);
- na = 0;
- l1 = 1;
- iw = nl;
- for (long k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable_rl.getFloat(k1 + 1 + twon);
- l2 = ipll * l1;
- ido = nl / l2;
- idl1 = ido * l1;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radb2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb2(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- radb3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb3(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 4:
- if (na == 0) {
- radb4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb4(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- radb5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb5(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- } else {
- radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- }
- if (ido == 1) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * ido;
- }
- if (na == 0) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, nl);
- }
-
- /*-------------------------------------------------
- radf2: Real FFT's forward processing of factor 2
- -------------------------------------------------*/
- void radf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- int i, ic, idx0, idx1, idx2, idx3, idx4;
- float t1i, t1r, w1r, w1i;
- int iw1;
- iw1 = offset;
- idx0 = l1 * ido;
- idx1 = 2 * ido;
- for (int k = 0; k < l1; k++) {
- int oidx1 = out_off + k * idx1;
- int oidx2 = oidx1 + idx1 - 1;
- int iidx1 = in_off + k * ido;
- int iidx2 = iidx1 + idx0;
-
- float i1r = in[iidx1];
- float i2r = in[iidx2];
-
- out[oidx1] = i1r + i2r;
- out[oidx2] = i1r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; k++) {
- idx1 = k * ido;
- idx2 = 2 * idx1;
- idx3 = idx2 + ido;
- idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int oidx1 = out_off + i + idx2;
- int oidx2 = out_off + ic + idx3;
- int iidx1 = in_off + i + idx1;
- int iidx2 = in_off + i + idx4;
-
- float a1i = in[iidx1 - 1];
- float a1r = in[iidx1];
- float a2i = in[iidx2 - 1];
- float a2r = in[iidx2];
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
-
- t1r = w1r * a2i + w1i * a2r;
- t1i = w1r * a2r - w1i * a2i;
-
- out[oidx1] = a1r + t1i;
- out[oidx1 - 1] = a1i + t1r;
-
- out[oidx2] = t1i - a1r;
- out[oidx2 - 1] = a1i - t1r;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- idx2 = 2 * idx1;
- for (int k = 0; k < l1; k++) {
- idx1 = k * ido;
- int oidx1 = out_off + idx2 + ido;
- int iidx1 = in_off + ido - 1 + idx1;
-
- out[oidx1] = -in[iidx1 + idx0];
- out[oidx1 - 1] = in[iidx1];
- }
- }
-
- /*-------------------------------------------------
- radf2: Real FFT's forward processing of factor 2
- -------------------------------------------------*/
- void radf2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- long i, ic, idx0, idx1, idx2, idx3, idx4;
- float t1i, t1r, w1r, w1i;
- long iw1;
- iw1 = offset;
- idx0 = l1 * ido;
- idx1 = 2 * ido;
- for (long k = 0; k < l1; k++) {
- long oidx1 = out_off + k * idx1;
- long oidx2 = oidx1 + idx1 - 1;
- long iidx1 = in_off + k * ido;
- long iidx2 = iidx1 + idx0;
-
- float i1r = in.getFloat(iidx1);
- float i2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1, i1r + i2r);
- out.setFloat(oidx2, i1r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; k++) {
- idx1 = k * ido;
- idx2 = 2 * idx1;
- idx3 = idx2 + ido;
- idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long oidx1 = out_off + i + idx2;
- long oidx2 = out_off + ic + idx3;
- long iidx1 = in_off + i + idx1;
- long iidx2 = in_off + i + idx4;
-
- float a1i = in.getFloat(iidx1 - 1);
- float a1r = in.getFloat(iidx1);
- float a2i = in.getFloat(iidx2 - 1);
- float a2r = in.getFloat(iidx2);
-
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
-
- t1r = w1r * a2i + w1i * a2r;
- t1i = w1r * a2r - w1i * a2i;
-
- out.setFloat(oidx1, a1r + t1i);
- out.setFloat(oidx1 - 1, a1i + t1r);
-
- out.setFloat(oidx2, t1i - a1r);
- out.setFloat(oidx2 - 1, a1i - t1r);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- idx2 = 2 * idx1;
- for (long k = 0; k < l1; k++) {
- idx1 = k * ido;
- long oidx1 = out_off + idx2 + ido;
- long iidx1 = in_off + ido - 1 + idx1;
-
- out.setFloat(oidx1, -in.getFloat(iidx1 + idx0));
- out.setFloat(oidx1 - 1, in.getFloat(iidx1));
- }
- }
-
- /*-------------------------------------------------
- radb2: Real FFT's backward processing of factor 2
- -------------------------------------------------*/
- void radb2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- int i, ic;
- float t1i, t1r, w1r, w1i;
- int iw1 = offset;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int idx3 = idx2 + ido;
- int oidx1 = out_off + idx1;
- int iidx1 = in_off + idx2;
- int iidx2 = in_off + ido - 1 + idx3;
- float i1r = in[iidx1];
- float i2r = in[iidx2];
- out[oidx1] = i1r + i2r;
- out[oidx1 + idx0] = i1r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx5 = i - 1 + iw1;
- int idx6 = out_off + i;
- int idx7 = in_off + i;
- int idx8 = in_off + ic;
- w1r = wtable_r[idx5 - 1];
- w1i = wtable_r[idx5];
- int iidx1 = idx7 + idx2;
- int iidx2 = idx8 + idx3;
- int oidx1 = idx6 + idx1;
- int oidx2 = idx6 + idx4;
- t1r = in[iidx1 - 1] - in[iidx2 - 1];
- t1i = in[iidx1] + in[iidx2];
- float i1i = in[iidx1];
- float i1r = in[iidx1 - 1];
- float i2i = in[iidx2];
- float i2r = in[iidx2 - 1];
-
- out[oidx1 - 1] = i1r + i2r;
- out[oidx1] = i1i - i2i;
- out[oidx2 - 1] = w1r * t1r - w1i * t1i;
- out[oidx2] = w1r * t1i + w1i * t1r;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int oidx1 = out_off + ido - 1 + idx1;
- int iidx1 = in_off + idx2 + ido;
- out[oidx1] = 2 * in[iidx1 - 1];
- out[oidx1 + idx0] = -2 * in[iidx1];
- }
- }
-
- /*-------------------------------------------------
- radb2: Real FFT's backward processing of factor 2
- -------------------------------------------------*/
- void radb2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- long i, ic;
- float t1i, t1r, w1r, w1i;
- long iw1 = offset;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long idx3 = idx2 + ido;
- long oidx1 = out_off + idx1;
- long iidx1 = in_off + idx2;
- long iidx2 = in_off + ido - 1 + idx3;
- float i1r = in.getFloat(iidx1);
- float i2r = in.getFloat(iidx2);
- out.setFloat(oidx1, i1r + i2r);
- out.setFloat(oidx1 + idx0, i1r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx5 = i - 1 + iw1;
- long idx6 = out_off + i;
- long idx7 = in_off + i;
- long idx8 = in_off + ic;
- w1r = wtable_rl.getFloat(idx5 - 1);
- w1i = wtable_rl.getFloat(idx5);
- long iidx1 = idx7 + idx2;
- long iidx2 = idx8 + idx3;
- long oidx1 = idx6 + idx1;
- long oidx2 = idx6 + idx4;
- t1r = in.getFloat(iidx1 - 1) - in.getFloat(iidx2 - 1);
- t1i = in.getFloat(iidx1) + in.getFloat(iidx2);
- float i1i = in.getFloat(iidx1);
- float i1r = in.getFloat(iidx1 - 1);
- float i2i = in.getFloat(iidx2);
- float i2r = in.getFloat(iidx2 - 1);
-
- out.setFloat(oidx1 - 1, i1r + i2r);
- out.setFloat(oidx1, i1i - i2i);
- out.setFloat(oidx2 - 1, w1r * t1r - w1i * t1i);
- out.setFloat(oidx2, w1r * t1i + w1i * t1r);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long oidx1 = out_off + ido - 1 + idx1;
- long iidx1 = in_off + idx2 + ido;
- out.setFloat(oidx1, 2 * in.getFloat(iidx1 - 1));
- out.setFloat(oidx1 + idx0, -2 * in.getFloat(iidx1));
- }
- }
-
- /*-------------------------------------------------
- radf3: Real FFT's forward processing of factor 3
- -------------------------------------------------*/
- void radf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- int i, ic;
- float ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
- int iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx3 = 2 * idx0;
- int idx4 = (3 * k + 1) * ido;
- int iidx1 = in_off + idx1;
- int iidx2 = iidx1 + idx0;
- int iidx3 = iidx1 + idx3;
- float i1r = in[iidx1];
- float i2r = in[iidx2];
- float i3r = in[iidx3];
- cr2 = i2r + i3r;
- out[out_off + 3 * idx1] = i1r + cr2;
- out[out_off + idx4 + ido] = taui * (i3r - i2r);
- out[out_off + ido - 1 + idx4] = i1r + taur * cr2;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int idx4 = 3 * idx3;
- int idx5 = idx3 + idx0;
- int idx6 = idx5 + idx0;
- int idx7 = idx4 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
-
- int idx9 = in_off + i;
- int idx10 = out_off + i;
- int idx11 = out_off + ic;
- int iidx1 = idx9 + idx3;
- int iidx2 = idx9 + idx5;
- int iidx3 = idx9 + idx6;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- cr2 = dr2 + dr3;
- ci2 = di2 + di3;
- tr2 = i1i + taur * cr2;
- ti2 = i1r + taur * ci2;
- tr3 = taui * (di2 - di3);
- ti3 = taui * (dr3 - dr2);
-
- int oidx1 = idx10 + idx4;
- int oidx2 = idx11 + idx7;
- int oidx3 = idx10 + idx8;
-
- out[oidx1 - 1] = i1i + cr2;
- out[oidx1] = i1r + ci2;
- out[oidx2 - 1] = tr2 - tr3;
- out[oidx2] = ti3 - ti2;
- out[oidx3 - 1] = tr2 + tr3;
- out[oidx3] = ti2 + ti3;
- }
- }
- }
-
- /*-------------------------------------------------
- radf3: Real FFT's forward processing of factor 3
- -------------------------------------------------*/
- void radf3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- long i, ic;
- float ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
- long iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx3 = 2 * idx0;
- long idx4 = (3 * k + 1) * ido;
- long iidx1 = in_off + idx1;
- long iidx2 = iidx1 + idx0;
- long iidx3 = iidx1 + idx3;
- float i1r = in.getFloat(iidx1);
- float i2r = in.getFloat(iidx2);
- float i3r = in.getFloat(iidx3);
- cr2 = i2r + i3r;
- out.setFloat(out_off + 3 * idx1, i1r + cr2);
- out.setFloat(out_off + idx4 + ido, taui * (i3r - i2r));
- out.setFloat(out_off + ido - 1 + idx4, i1r + taur * cr2);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long idx4 = 3 * idx3;
- long idx5 = idx3 + idx0;
- long idx6 = idx5 + idx0;
- long idx7 = idx4 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
-
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
-
- long idx9 = in_off + i;
- long idx10 = out_off + i;
- long idx11 = out_off + ic;
- long iidx1 = idx9 + idx3;
- long iidx2 = idx9 + idx5;
- long iidx3 = idx9 + idx6;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- cr2 = dr2 + dr3;
- ci2 = di2 + di3;
- tr2 = i1i + taur * cr2;
- ti2 = i1r + taur * ci2;
- tr3 = taui * (di2 - di3);
- ti3 = taui * (dr3 - dr2);
-
- long oidx1 = idx10 + idx4;
- long oidx2 = idx11 + idx7;
- long oidx3 = idx10 + idx8;
-
- out.setFloat(oidx1 - 1, i1i + cr2);
- out.setFloat(oidx1, i1r + ci2);
- out.setFloat(oidx2 - 1, tr2 - tr3);
- out.setFloat(oidx2, ti3 - ti2);
- out.setFloat(oidx3 - 1, tr2 + tr3);
- out.setFloat(oidx3, ti2 + ti3);
- }
- }
- }
-
- /*-------------------------------------------------
- radb3: Real FFT's backward processing of factor 3
- -------------------------------------------------*/
- void radb3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- int i, ic;
- float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
- int iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int iidx1 = in_off + 3 * idx1;
- int iidx2 = iidx1 + 2 * ido;
- float i1i = in[iidx1];
-
- tr2 = 2 * in[iidx2 - 1];
- cr2 = i1i + taur * tr2;
- ci3 = 2 * taui * in[iidx2];
-
- out[out_off + idx1] = i1i + tr2;
- out[out_off + (k + l1) * ido] = cr2 - ci3;
- out[out_off + (k + 2 * l1) * ido] = cr2 + ci3;
- }
- if (ido == 1) {
- return;
- }
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 3 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx1 + idx0;
- int idx6 = idx5 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = in_off + i;
- int idx8 = in_off + ic;
- int idx9 = out_off + i;
- int iidx1 = idx7 + idx2;
- int iidx2 = idx7 + idx4;
- int iidx3 = idx8 + idx3;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
-
- tr2 = i2i + i3i;
- cr2 = i1i + taur * tr2;
- ti2 = i2r - i3r;
- ci2 = i1r + taur * ti2;
- cr3 = taui * (i2i - i3i);
- ci3 = taui * (i2r + i3r);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
-
- int oidx1 = idx9 + idx1;
- int oidx2 = idx9 + idx5;
- int oidx3 = idx9 + idx6;
-
- out[oidx1 - 1] = i1i + tr2;
- out[oidx1] = i1r + ti2;
- out[oidx2 - 1] = w1r * dr2 - w1i * di2;
- out[oidx2] = w1r * di2 + w1i * dr2;
- out[oidx3 - 1] = w2r * dr3 - w2i * di3;
- out[oidx3] = w2r * di3 + w2i * dr3;
- }
- }
- }
-
- /*-------------------------------------------------
- radb3: Real FFT's backward processing of factor 3
- -------------------------------------------------*/
- void radb3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- long i, ic;
- float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
- long iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long iidx1 = in_off + 3 * idx1;
- long iidx2 = iidx1 + 2 * ido;
- float i1i = in.getFloat(iidx1);
-
- tr2 = 2 * in.getFloat(iidx2 - 1);
- cr2 = i1i + taur * tr2;
- ci3 = 2 * taui * in.getFloat(iidx2);
-
- out.setFloat(out_off + idx1, i1i + tr2);
- out.setFloat(out_off + (k + l1) * ido, cr2 - ci3);
- out.setFloat(out_off + (k + 2 * l1) * ido, cr2 + ci3);
- }
- if (ido == 1) {
- return;
- }
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 3 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx1 + idx0;
- long idx6 = idx5 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = in_off + i;
- long idx8 = in_off + ic;
- long idx9 = out_off + i;
- long iidx1 = idx7 + idx2;
- long iidx2 = idx7 + idx4;
- long iidx3 = idx8 + idx3;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
-
- tr2 = i2i + i3i;
- cr2 = i1i + taur * tr2;
- ti2 = i2r - i3r;
- ci2 = i1r + taur * ti2;
- cr3 = taui * (i2i - i3i);
- ci3 = taui * (i2r + i3r);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
-
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
-
- long oidx1 = idx9 + idx1;
- long oidx2 = idx9 + idx5;
- long oidx3 = idx9 + idx6;
-
- out.setFloat(oidx1 - 1, i1i + tr2);
- out.setFloat(oidx1, i1r + ti2);
- out.setFloat(oidx2 - 1, w1r * dr2 - w1i * di2);
- out.setFloat(oidx2, w1r * di2 + w1i * dr2);
- out.setFloat(oidx3 - 1, w2r * dr3 - w2i * di3);
- out.setFloat(oidx3, w2r * di3 + w2i * dr3);
- }
- }
- }
-
- /*-------------------------------------------------
- radf4: Real FFT's forward processing of factor 4
- -------------------------------------------------*/
- void radf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float hsqt2 = 0.707106781186547572737310929369414225f;
- int i, ic;
- float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = offset + ido;
- iw3 = iw2 + ido;
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- float i1r = in[in_off + idx1];
- float i2r = in[in_off + idx3];
- float i3r = in[in_off + idx4];
- float i4r = in[in_off + idx5];
-
- tr1 = i2r + i4r;
- tr2 = i1r + i3r;
-
- int oidx1 = out_off + idx2;
- int oidx2 = out_off + idx6 + ido;
-
- out[oidx1] = tr1 + tr2;
- out[oidx2 - 1 + ido + ido] = tr2 - tr1;
- out[oidx2 - 1] = i1r - i3r;
- out[oidx2] = i4r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 + idx0;
- int idx3 = idx2 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = 4 * idx1;
- int idx6 = idx5 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
-
- int idx9 = in_off + i;
- int idx10 = out_off + i;
- int idx11 = out_off + ic;
- int iidx1 = idx9 + idx1;
- int iidx2 = idx9 + idx2;
- int iidx3 = idx9 + idx3;
- int iidx4 = idx9 + idx4;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
-
- cr2 = w1r * i2i + w1i * i2r;
- ci2 = w1r * i2r - w1i * i2i;
- cr3 = w2r * i3i + w2i * i3r;
- ci3 = w2r * i3r - w2i * i3i;
- cr4 = w3r * i4i + w3i * i4r;
- ci4 = w3r * i4r - w3i * i4i;
- tr1 = cr2 + cr4;
- tr4 = cr4 - cr2;
- ti1 = ci2 + ci4;
- ti4 = ci2 - ci4;
- ti2 = i1r + ci3;
- ti3 = i1r - ci3;
- tr2 = i1i + cr3;
- tr3 = i1i - cr3;
-
- int oidx1 = idx10 + idx5;
- int oidx2 = idx11 + idx6;
- int oidx3 = idx10 + idx7;
- int oidx4 = idx11 + idx8;
-
- out[oidx1 - 1] = tr1 + tr2;
- out[oidx4 - 1] = tr2 - tr1;
- out[oidx1] = ti1 + ti2;
- out[oidx4] = ti1 - ti2;
- out[oidx3 - 1] = ti4 + tr3;
- out[oidx2 - 1] = tr3 - ti4;
- out[oidx3] = tr4 + ti3;
- out[oidx2] = tr4 - ti3;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- int idx9 = in_off + ido;
- int idx10 = out_off + ido;
-
- float i1i = in[idx9 - 1 + idx1];
- float i2i = in[idx9 - 1 + idx3];
- float i3i = in[idx9 - 1 + idx4];
- float i4i = in[idx9 - 1 + idx5];
-
- ti1 = -hsqt2 * (i2i + i4i);
- tr1 = hsqt2 * (i2i - i4i);
-
- out[idx10 - 1 + idx2] = tr1 + i1i;
- out[idx10 - 1 + idx7] = i1i - tr1;
- out[out_off + idx6] = ti1 - i3i;
- out[out_off + idx8] = ti1 + i3i;
- }
- }
-
- /*-------------------------------------------------
- radf4: Real FFT's forward processing of factor 4
- -------------------------------------------------*/
- void radf4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float hsqt2 = 0.707106781186547572737310929369414225f;
- long i, ic;
- float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = offset + ido;
- iw3 = iw2 + ido;
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- float i1r = in.getFloat(in_off + idx1);
- float i2r = in.getFloat(in_off + idx3);
- float i3r = in.getFloat(in_off + idx4);
- float i4r = in.getFloat(in_off + idx5);
-
- tr1 = i2r + i4r;
- tr2 = i1r + i3r;
-
- long oidx1 = out_off + idx2;
- long oidx2 = out_off + idx6 + ido;
-
- out.setFloat(oidx1, tr1 + tr2);
- out.setFloat(oidx2 - 1 + ido + ido, tr2 - tr1);
- out.setFloat(oidx2 - 1, i1r - i3r);
- out.setFloat(oidx2, i4r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 + idx0;
- long idx3 = idx2 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = 4 * idx1;
- long idx6 = idx5 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
- w3r = wtable_rl.getFloat(widx3 - 1);
- w3i = wtable_rl.getFloat(widx3);
-
- long idx9 = in_off + i;
- long idx10 = out_off + i;
- long idx11 = out_off + ic;
- long iidx1 = idx9 + idx1;
- long iidx2 = idx9 + idx2;
- long iidx3 = idx9 + idx3;
- long iidx4 = idx9 + idx4;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
-
- cr2 = w1r * i2i + w1i * i2r;
- ci2 = w1r * i2r - w1i * i2i;
- cr3 = w2r * i3i + w2i * i3r;
- ci3 = w2r * i3r - w2i * i3i;
- cr4 = w3r * i4i + w3i * i4r;
- ci4 = w3r * i4r - w3i * i4i;
- tr1 = cr2 + cr4;
- tr4 = cr4 - cr2;
- ti1 = ci2 + ci4;
- ti4 = ci2 - ci4;
- ti2 = i1r + ci3;
- ti3 = i1r - ci3;
- tr2 = i1i + cr3;
- tr3 = i1i - cr3;
-
- long oidx1 = idx10 + idx5;
- long oidx2 = idx11 + idx6;
- long oidx3 = idx10 + idx7;
- long oidx4 = idx11 + idx8;
-
- out.setFloat(oidx1 - 1, tr1 + tr2);
- out.setFloat(oidx4 - 1, tr2 - tr1);
- out.setFloat(oidx1, ti1 + ti2);
- out.setFloat(oidx4, ti1 - ti2);
- out.setFloat(oidx3 - 1, ti4 + tr3);
- out.setFloat(oidx2 - 1, tr3 - ti4);
- out.setFloat(oidx3, tr4 + ti3);
- out.setFloat(oidx2, tr4 - ti3);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- long idx9 = in_off + ido;
- long idx10 = out_off + ido;
-
- float i1i = in.getFloat(idx9 - 1 + idx1);
- float i2i = in.getFloat(idx9 - 1 + idx3);
- float i3i = in.getFloat(idx9 - 1 + idx4);
- float i4i = in.getFloat(idx9 - 1 + idx5);
-
- ti1 = -hsqt2 * (i2i + i4i);
- tr1 = hsqt2 * (i2i - i4i);
-
- out.setFloat(idx10 - 1 + idx2, tr1 + i1i);
- out.setFloat(idx10 - 1 + idx7, i1i - tr1);
- out.setFloat(out_off + idx6, ti1 - i3i);
- out.setFloat(out_off + idx8, ti1 + i3i);
- }
- }
-
- /*-------------------------------------------------
- radb4: Real FFT's backward processing of factor 4
- -------------------------------------------------*/
- void radb4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float sqrt2 = 1.41421356237309514547462185873882845f;
- int i, ic;
- float ci2, ci3, ci4, cr2, cr3, cr4;
- float ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
-
- float i1r = in[in_off + idx2];
- float i2r = in[in_off + idx7];
- float i3r = in[in_off + ido - 1 + idx8];
- float i4r = in[in_off + ido - 1 + idx6];
-
- tr1 = i1r - i3r;
- tr2 = i1r + i3r;
- tr3 = i4r + i4r;
- tr4 = i2r + i2r;
-
- out[out_off + idx1] = tr2 + tr3;
- out[out_off + idx3] = tr1 - tr4;
- out[out_off + idx4] = tr2 - tr3;
- out[out_off + idx5] = tr1 + tr4;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = idx1 + idx0;
- int idx3 = idx2 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = 4 * idx1;
- int idx6 = idx5 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
-
- int idx12 = in_off + i;
- int idx13 = in_off + ic;
- int idx14 = out_off + i;
-
- int iidx1 = idx12 + idx5;
- int iidx2 = idx13 + idx6;
- int iidx3 = idx12 + idx7;
- int iidx4 = idx13 + idx8;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
-
- ti1 = i1r + i4r;
- ti2 = i1r - i4r;
- ti3 = i3r - i2r;
- tr4 = i3r + i2r;
- tr1 = i1i - i4i;
- tr2 = i1i + i4i;
- ti4 = i3i - i2i;
- tr3 = i3i + i2i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 - tr4;
- cr4 = tr1 + tr4;
- ci2 = ti1 + ti4;
- ci4 = ti1 - ti4;
-
- int oidx1 = idx14 + idx1;
- int oidx2 = idx14 + idx2;
- int oidx3 = idx14 + idx3;
- int oidx4 = idx14 + idx4;
-
- out[oidx1 - 1] = tr2 + tr3;
- out[oidx1] = ti2 + ti3;
- out[oidx2 - 1] = w1r * cr2 - w1i * ci2;
- out[oidx2] = w1r * ci2 + w1i * cr2;
- out[oidx3 - 1] = w2r * cr3 - w2i * ci3;
- out[oidx3] = w2r * ci3 + w2i * cr3;
- out[oidx4 - 1] = w3r * cr4 - w3i * ci4;
- out[oidx4] = w3r * ci4 + w3i * cr4;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- int idx9 = in_off + ido;
- int idx10 = out_off + ido;
-
- float i1r = in[idx9 - 1 + idx2];
- float i2r = in[idx9 - 1 + idx7];
- float i3r = in[in_off + idx6];
- float i4r = in[in_off + idx8];
-
- ti1 = i3r + i4r;
- ti2 = i4r - i3r;
- tr1 = i1r - i2r;
- tr2 = i1r + i2r;
-
- out[idx10 - 1 + idx1] = tr2 + tr2;
- out[idx10 - 1 + idx3] = sqrt2 * (tr1 - ti1);
- out[idx10 - 1 + idx4] = ti2 + ti2;
- out[idx10 - 1 + idx5] = -sqrt2 * (tr1 + ti1);
- }
- }
-
- /*-------------------------------------------------
- radb4: Real FFT's backward processing of factor 4
- -------------------------------------------------*/
- void radb4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float sqrt2 = 1.41421356237309514547462185873882845f;
- long i, ic;
- float ci2, ci3, ci4, cr2, cr3, cr4;
- float ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
-
- float i1r = in.getFloat(in_off + idx2);
- float i2r = in.getFloat(in_off + idx7);
- float i3r = in.getFloat(in_off + ido - 1 + idx8);
- float i4r = in.getFloat(in_off + ido - 1 + idx6);
-
- tr1 = i1r - i3r;
- tr2 = i1r + i3r;
- tr3 = i4r + i4r;
- tr4 = i2r + i2r;
-
- out.setFloat(out_off + idx1, tr2 + tr3);
- out.setFloat(out_off + idx3, tr1 - tr4);
- out.setFloat(out_off + idx4, tr2 - tr3);
- out.setFloat(out_off + idx5, tr1 + tr4);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = idx1 + idx0;
- long idx3 = idx2 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = 4 * idx1;
- long idx6 = idx5 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
- w3r = wtable_rl.getFloat(widx3 - 1);
- w3i = wtable_rl.getFloat(widx3);
-
- long idx12 = in_off + i;
- long idx13 = in_off + ic;
- long idx14 = out_off + i;
-
- long iidx1 = idx12 + idx5;
- long iidx2 = idx13 + idx6;
- long iidx3 = idx12 + idx7;
- long iidx4 = idx13 + idx8;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
-
- ti1 = i1r + i4r;
- ti2 = i1r - i4r;
- ti3 = i3r - i2r;
- tr4 = i3r + i2r;
- tr1 = i1i - i4i;
- tr2 = i1i + i4i;
- ti4 = i3i - i2i;
- tr3 = i3i + i2i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 - tr4;
- cr4 = tr1 + tr4;
- ci2 = ti1 + ti4;
- ci4 = ti1 - ti4;
-
- long oidx1 = idx14 + idx1;
- long oidx2 = idx14 + idx2;
- long oidx3 = idx14 + idx3;
- long oidx4 = idx14 + idx4;
-
- out.setFloat(oidx1 - 1, tr2 + tr3);
- out.setFloat(oidx1, ti2 + ti3);
- out.setFloat(oidx2 - 1, w1r * cr2 - w1i * ci2);
- out.setFloat(oidx2, w1r * ci2 + w1i * cr2);
- out.setFloat(oidx3 - 1, w2r * cr3 - w2i * ci3);
- out.setFloat(oidx3, w2r * ci3 + w2i * cr3);
- out.setFloat(oidx4 - 1, w3r * cr4 - w3i * ci4);
- out.setFloat(oidx4, w3r * ci4 + w3i * cr4);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- long idx9 = in_off + ido;
- long idx10 = out_off + ido;
-
- float i1r = in.getFloat(idx9 - 1 + idx2);
- float i2r = in.getFloat(idx9 - 1 + idx7);
- float i3r = in.getFloat(in_off + idx6);
- float i4r = in.getFloat(in_off + idx8);
-
- ti1 = i3r + i4r;
- ti2 = i4r - i3r;
- tr1 = i1r - i2r;
- tr2 = i1r + i2r;
-
- out.setFloat(idx10 - 1 + idx1, tr2 + tr2);
- out.setFloat(idx10 - 1 + idx3, sqrt2 * (tr1 - ti1));
- out.setFloat(idx10 - 1 + idx4, ti2 + ti2);
- out.setFloat(idx10 - 1 + idx5, -sqrt2 * (tr1 + ti1));
- }
- }
-
- /*-------------------------------------------------
- radf5: Real FFT's forward processing of factor 5
- -------------------------------------------------*/
- void radf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- int i, ic;
- float ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- int iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- int idx11 = out_off + ido - 1;
-
- float i1r = in[in_off + idx1];
- float i2r = in[in_off + idx7];
- float i3r = in[in_off + idx8];
- float i4r = in[in_off + idx9];
- float i5r = in[in_off + idx10];
-
- cr2 = i5r + i2r;
- ci5 = i5r - i2r;
- cr3 = i4r + i3r;
- ci4 = i4r - i3r;
-
- out[out_off + idx2] = i1r + cr2 + cr3;
- out[idx11 + idx3] = i1r + tr11 * cr2 + tr12 * cr3;
- out[out_off + idx4] = ti11 * ci5 + ti12 * ci4;
- out[idx11 + idx5] = i1r + tr12 * cr2 + tr11 * cr3;
- out[out_off + idx6] = ti12 * ci5 - ti11 * ci4;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- int widx4 = i - 1 + iw4;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
- w4r = wtable_r[widx4 - 1];
- w4i = wtable_r[widx4];
-
- ic = ido - i;
- int idx15 = in_off + i;
- int idx16 = out_off + i;
- int idx17 = out_off + ic;
-
- int iidx1 = idx15 + idx1;
- int iidx2 = idx15 + idx7;
- int iidx3 = idx15 + idx8;
- int iidx4 = idx15 + idx9;
- int iidx5 = idx15 + idx10;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
- float i5i = in[iidx5 - 1];
- float i5r = in[iidx5];
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- dr4 = w3r * i4i + w3i * i4r;
- di4 = w3r * i4r - w3i * i4i;
- dr5 = w4r * i5i + w4i * i5r;
- di5 = w4r * i5r - w4i * i5i;
-
- cr2 = dr2 + dr5;
- ci5 = dr5 - dr2;
- cr5 = di2 - di5;
- ci2 = di2 + di5;
- cr3 = dr3 + dr4;
- ci4 = dr4 - dr3;
- cr4 = di3 - di4;
- ci3 = di3 + di4;
-
- tr2 = i1i + tr11 * cr2 + tr12 * cr3;
- ti2 = i1r + tr11 * ci2 + tr12 * ci3;
- tr3 = i1i + tr12 * cr2 + tr11 * cr3;
- ti3 = i1r + tr12 * ci2 + tr11 * ci3;
- tr5 = ti11 * cr5 + ti12 * cr4;
- ti5 = ti11 * ci5 + ti12 * ci4;
- tr4 = ti12 * cr5 - ti11 * cr4;
- ti4 = ti12 * ci5 - ti11 * ci4;
-
- int oidx1 = idx16 + idx2;
- int oidx2 = idx17 + idx3;
- int oidx3 = idx16 + idx4;
- int oidx4 = idx17 + idx5;
- int oidx5 = idx16 + idx6;
-
- out[oidx1 - 1] = i1i + cr2 + cr3;
- out[oidx1] = i1r + ci2 + ci3;
- out[oidx3 - 1] = tr2 + tr5;
- out[oidx2 - 1] = tr2 - tr5;
- out[oidx3] = ti2 + ti5;
- out[oidx2] = ti5 - ti2;
- out[oidx5 - 1] = tr3 + tr4;
- out[oidx4 - 1] = tr3 - tr4;
- out[oidx5] = ti3 + ti4;
- out[oidx4] = ti4 - ti3;
- }
- }
- }
-
- /*-------------------------------------------------
- radf5: Real FFT's forward processing of factor 5
- -------------------------------------------------*/
- void radf5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- long i, ic;
- float ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- long iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- long idx11 = out_off + ido - 1;
-
- float i1r = in.getFloat(in_off + idx1);
- float i2r = in.getFloat(in_off + idx7);
- float i3r = in.getFloat(in_off + idx8);
- float i4r = in.getFloat(in_off + idx9);
- float i5r = in.getFloat(in_off + idx10);
-
- cr2 = i5r + i2r;
- ci5 = i5r - i2r;
- cr3 = i4r + i3r;
- ci4 = i4r - i3r;
-
- out.setFloat(out_off + idx2, i1r + cr2 + cr3);
- out.setFloat(idx11 + idx3, i1r + tr11 * cr2 + tr12 * cr3);
- out.setFloat(out_off + idx4, ti11 * ci5 + ti12 * ci4);
- out.setFloat(idx11 + idx5, i1r + tr12 * cr2 + tr11 * cr3);
- out.setFloat(out_off + idx6, ti12 * ci5 - ti11 * ci4);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- long widx4 = i - 1 + iw4;
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
- w3r = wtable_rl.getFloat(widx3 - 1);
- w3i = wtable_rl.getFloat(widx3);
- w4r = wtable_rl.getFloat(widx4 - 1);
- w4i = wtable_rl.getFloat(widx4);
-
- ic = ido - i;
- long idx15 = in_off + i;
- long idx16 = out_off + i;
- long idx17 = out_off + ic;
-
- long iidx1 = idx15 + idx1;
- long iidx2 = idx15 + idx7;
- long iidx3 = idx15 + idx8;
- long iidx4 = idx15 + idx9;
- long iidx5 = idx15 + idx10;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
- float i5i = in.getFloat(iidx5 - 1);
- float i5r = in.getFloat(iidx5);
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- dr4 = w3r * i4i + w3i * i4r;
- di4 = w3r * i4r - w3i * i4i;
- dr5 = w4r * i5i + w4i * i5r;
- di5 = w4r * i5r - w4i * i5i;
-
- cr2 = dr2 + dr5;
- ci5 = dr5 - dr2;
- cr5 = di2 - di5;
- ci2 = di2 + di5;
- cr3 = dr3 + dr4;
- ci4 = dr4 - dr3;
- cr4 = di3 - di4;
- ci3 = di3 + di4;
-
- tr2 = i1i + tr11 * cr2 + tr12 * cr3;
- ti2 = i1r + tr11 * ci2 + tr12 * ci3;
- tr3 = i1i + tr12 * cr2 + tr11 * cr3;
- ti3 = i1r + tr12 * ci2 + tr11 * ci3;
- tr5 = ti11 * cr5 + ti12 * cr4;
- ti5 = ti11 * ci5 + ti12 * ci4;
- tr4 = ti12 * cr5 - ti11 * cr4;
- ti4 = ti12 * ci5 - ti11 * ci4;
-
- long oidx1 = idx16 + idx2;
- long oidx2 = idx17 + idx3;
- long oidx3 = idx16 + idx4;
- long oidx4 = idx17 + idx5;
- long oidx5 = idx16 + idx6;
-
- out.setFloat(oidx1 - 1, i1i + cr2 + cr3);
- out.setFloat(oidx1, i1r + ci2 + ci3);
- out.setFloat(oidx3 - 1, tr2 + tr5);
- out.setFloat(oidx2 - 1, tr2 - tr5);
- out.setFloat(oidx3, ti2 + ti5);
- out.setFloat(oidx2, ti5 - ti2);
- out.setFloat(oidx5 - 1, tr3 + tr4);
- out.setFloat(oidx4 - 1, tr3 - tr4);
- out.setFloat(oidx5, ti3 + ti4);
- out.setFloat(oidx4, ti4 - ti3);
- }
- }
- }
-
- /*-------------------------------------------------
- radb5: Real FFT's backward processing of factor 5
- -------------------------------------------------*/
- void radb5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- int i, ic;
- float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- int iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- int idx11 = in_off + ido - 1;
-
- float i1r = in[in_off + idx2];
-
- ti5 = 2 * in[in_off + idx4];
- ti4 = 2 * in[in_off + idx6];
- tr2 = 2 * in[idx11 + idx3];
- tr3 = 2 * in[idx11 + idx5];
- cr2 = i1r + tr11 * tr2 + tr12 * tr3;
- cr3 = i1r + tr12 * tr2 + tr11 * tr3;
- ci5 = ti11 * ti5 + ti12 * ti4;
- ci4 = ti12 * ti5 - ti11 * ti4;
-
- out[out_off + idx1] = i1r + tr2 + tr3;
- out[out_off + idx7] = cr2 - ci5;
- out[out_off + idx8] = cr3 - ci4;
- out[out_off + idx9] = cr3 + ci4;
- out[out_off + idx10] = cr2 + ci5;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- int widx4 = i - 1 + iw4;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
- w4r = wtable_r[widx4 - 1];
- w4i = wtable_r[widx4];
-
- int idx15 = in_off + i;
- int idx16 = in_off + ic;
- int idx17 = out_off + i;
-
- int iidx1 = idx15 + idx2;
- int iidx2 = idx16 + idx3;
- int iidx3 = idx15 + idx4;
- int iidx4 = idx16 + idx5;
- int iidx5 = idx15 + idx6;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
- float i5i = in[iidx5 - 1];
- float i5r = in[iidx5];
-
- ti5 = i3r + i2r;
- ti2 = i3r - i2r;
- ti4 = i5r + i4r;
- ti3 = i5r - i4r;
- tr5 = i3i - i2i;
- tr2 = i3i + i2i;
- tr4 = i5i - i4i;
- tr3 = i5i + i4i;
-
- cr2 = i1i + tr11 * tr2 + tr12 * tr3;
- ci2 = i1r + tr11 * ti2 + tr12 * ti3;
- cr3 = i1i + tr12 * tr2 + tr11 * tr3;
- ci3 = i1r + tr12 * ti2 + tr11 * ti3;
- cr5 = ti11 * tr5 + ti12 * tr4;
- ci5 = ti11 * ti5 + ti12 * ti4;
- cr4 = ti12 * tr5 - ti11 * tr4;
- ci4 = ti12 * ti5 - ti11 * ti4;
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- int oidx1 = idx17 + idx1;
- int oidx2 = idx17 + idx7;
- int oidx3 = idx17 + idx8;
- int oidx4 = idx17 + idx9;
- int oidx5 = idx17 + idx10;
-
- out[oidx1 - 1] = i1i + tr2 + tr3;
- out[oidx1] = i1r + ti2 + ti3;
- out[oidx2 - 1] = w1r * dr2 - w1i * di2;
- out[oidx2] = w1r * di2 + w1i * dr2;
- out[oidx3 - 1] = w2r * dr3 - w2i * di3;
- out[oidx3] = w2r * di3 + w2i * dr3;
- out[oidx4 - 1] = w3r * dr4 - w3i * di4;
- out[oidx4] = w3r * di4 + w3i * dr4;
- out[oidx5 - 1] = w4r * dr5 - w4i * di5;
- out[oidx5] = w4r * di5 + w4i * dr5;
- }
- }
- }
-
- /*-------------------------------------------------
- radb5: Real FFT's backward processing of factor 5
- -------------------------------------------------*/
- void radb5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- long i, ic;
- float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- long iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- long idx11 = in_off + ido - 1;
-
- float i1r = in.getFloat(in_off + idx2);
-
- ti5 = 2 * in.getFloat(in_off + idx4);
- ti4 = 2 * in.getFloat(in_off + idx6);
- tr2 = 2 * in.getFloat(idx11 + idx3);
- tr3 = 2 * in.getFloat(idx11 + idx5);
- cr2 = i1r + tr11 * tr2 + tr12 * tr3;
- cr3 = i1r + tr12 * tr2 + tr11 * tr3;
- ci5 = ti11 * ti5 + ti12 * ti4;
- ci4 = ti12 * ti5 - ti11 * ti4;
-
- out.setFloat(out_off + idx1, i1r + tr2 + tr3);
- out.setFloat(out_off + idx7, cr2 - ci5);
- out.setFloat(out_off + idx8, cr3 - ci4);
- out.setFloat(out_off + idx9, cr3 + ci4);
- out.setFloat(out_off + idx10, cr2 + ci5);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- long widx4 = i - 1 + iw4;
- w1r = wtable_rl.getFloat(widx1 - 1);
- w1i = wtable_rl.getFloat(widx1);
- w2r = wtable_rl.getFloat(widx2 - 1);
- w2i = wtable_rl.getFloat(widx2);
- w3r = wtable_rl.getFloat(widx3 - 1);
- w3i = wtable_rl.getFloat(widx3);
- w4r = wtable_rl.getFloat(widx4 - 1);
- w4i = wtable_rl.getFloat(widx4);
-
- long idx15 = in_off + i;
- long idx16 = in_off + ic;
- long idx17 = out_off + i;
-
- long iidx1 = idx15 + idx2;
- long iidx2 = idx16 + idx3;
- long iidx3 = idx15 + idx4;
- long iidx4 = idx16 + idx5;
- long iidx5 = idx15 + idx6;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
- float i5i = in.getFloat(iidx5 - 1);
- float i5r = in.getFloat(iidx5);
-
- ti5 = i3r + i2r;
- ti2 = i3r - i2r;
- ti4 = i5r + i4r;
- ti3 = i5r - i4r;
- tr5 = i3i - i2i;
- tr2 = i3i + i2i;
- tr4 = i5i - i4i;
- tr3 = i5i + i4i;
-
- cr2 = i1i + tr11 * tr2 + tr12 * tr3;
- ci2 = i1r + tr11 * ti2 + tr12 * ti3;
- cr3 = i1i + tr12 * tr2 + tr11 * tr3;
- ci3 = i1r + tr12 * ti2 + tr11 * ti3;
- cr5 = ti11 * tr5 + ti12 * tr4;
- ci5 = ti11 * ti5 + ti12 * ti4;
- cr4 = ti12 * tr5 - ti11 * tr4;
- ci4 = ti12 * ti5 - ti11 * ti4;
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- long oidx1 = idx17 + idx1;
- long oidx2 = idx17 + idx7;
- long oidx3 = idx17 + idx8;
- long oidx4 = idx17 + idx9;
- long oidx5 = idx17 + idx10;
-
- out.setFloat(oidx1 - 1, i1i + tr2 + tr3);
- out.setFloat(oidx1, i1r + ti2 + ti3);
- out.setFloat(oidx2 - 1, w1r * dr2 - w1i * di2);
- out.setFloat(oidx2, w1r * di2 + w1i * dr2);
- out.setFloat(oidx3 - 1, w2r * dr3 - w2i * di3);
- out.setFloat(oidx3, w2r * di3 + w2i * dr3);
- out.setFloat(oidx4 - 1, w3r * dr4 - w3i * di4);
- out.setFloat(oidx4, w3r * di4 + w3i * dr4);
- out.setFloat(oidx5 - 1, w4r * dr5 - w4i * di5);
- out.setFloat(oidx5, w4r * di5 + w4i * dr5);
- }
- }
- }
-
- /*---------------------------------------------------------
- radfg: Real FFT's forward processing of general factor
- --------------------------------------------------------*/
- void radfg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- int idij, ipph, j2, ic, jc, lc, is, nbd;
- float dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
- int iw1 = offset;
-
- arg = TWO_PI / (float) ip;
- dcp = (float)Math.cos(arg);
- dsp = (float)Math.sin(arg);
- ipph = (ip + 1) / 2;
- nbd = (ido - 1) / 2;
- if (ido != 1) {
- for (int ik = 0; ik < idl1; ik++) {
- out[out_off + ik] = in[in_off + ik];
- }
- for (int j = 1; j < ip; j++) {
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido + idx1;
- out[out_off + idx2] = in[in_off + idx2];
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- int idx1 = j * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int oidx1 = idx5 + idx3;
- int iidx1 = idx4 + idx3;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
-
- out[oidx1 - 1] = w1r * i1i + w1i * i1r;
- out[oidx1] = w1r * i1r - w1i * i1i;
- }
- }
- }
- } else {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = is - 1;
- int idx3 = k * ido + idx1;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int oidx1 = out_off + i + idx3;
- int iidx1 = in_off + i + idx3;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
-
- out[oidx1 - 1] = w1r * i1i + w1i * i1r;
- out[oidx1] = w1r * i1r - w1i * i1i;
- }
- }
- }
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- for (int i = 2; i < ido; i += 2) {
- int idx5 = in_off + i;
- int idx6 = out_off + i;
- int iidx1 = idx5 + idx3;
- int iidx2 = idx5 + idx4;
- int oidx1 = idx6 + idx3;
- int oidx2 = idx6 + idx4;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- float o2i = out[oidx2 - 1];
- float o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx1] = o1r + o2r;
-
- in[iidx2 - 1] = o1r - o2r;
- in[iidx2] = o2i - o1i;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx5 = in_off + i;
- int idx6 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- int iidx1 = idx5 + idx3;
- int iidx2 = idx5 + idx4;
- int oidx1 = idx6 + idx3;
- int oidx2 = idx6 + idx4;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- float o2i = out[oidx2 - 1];
- float o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2 - 1] = o1r - o2r;
- in[iidx2] = o2i - o1i;
- }
- }
- }
- }
- } else {
- System.arraycopy(out, out_off, in, in_off, idl1);
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- int oidx1 = out_off + idx3;
- int oidx2 = out_off + idx4;
- float o1r = out[oidx1];
- float o2r = out[oidx2];
-
- in[in_off + idx3] = o1r + o2r;
- in[in_off + idx4] = o2r - o1r;
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- int idx0 = (ip - 1) * idl1;
- for (int l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- int idx1 = l * idl1;
- int idx2 = lc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx3 = out_off + ik;
- int idx4 = in_off + ik;
- out[idx3 + idx1] = in[idx4] + ar1 * in[idx4 + idl1];
- out[idx3 + idx2] = ai1 * in[idx4 + idx0];
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- int idx3 = j * idl1;
- int idx4 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx5 = out_off + ik;
- int idx6 = in_off + ik;
- out[idx5 + idx1] += ar2 * in[idx6 + idx3];
- out[idx5 + idx2] += ai2 * in[idx6 + idx4];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idx1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- out[out_off + ik] += in[in_off + ik + idx1];
- }
- }
-
- if (ido >= l1) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 * ip;
- for (int i = 0; i < ido; i++) {
- in[in_off + i + idx2] = out[out_off + i + idx1];
- }
- }
- } else {
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- in[in_off + i + idx1 * ip] = out[out_off + i + idx1];
- }
- }
- }
- int idx01 = ip * ido;
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido;
- int idx5 = idx4 + idx1;
- int idx6 = idx4 + idx2;
- int idx7 = k * idx01;
- in[in_off + ido - 1 + idx3 - ido + idx7] = out[out_off + idx5];
- in[in_off + idx3 + idx7] = out[out_off + idx6];
- }
- }
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * idx01;
- int idx5 = k * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx6 = in_off + i;
- int idx7 = in_off + ic;
- int idx8 = out_off + i;
- int iidx1 = idx6 + idx3 + idx4;
- int iidx2 = idx7 + idx3 - ido + idx4;
- int oidx1 = idx8 + idx5 + idx1;
- int oidx2 = idx8 + idx5 + idx2;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- float o2i = out[oidx2 - 1];
- float o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx2 - 1] = o1i - o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2] = o2r - o1r;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx6 = in_off + i;
- int idx7 = in_off + ic;
- int idx8 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * idx01;
- int idx5 = k * ido;
- int iidx1 = idx6 + idx3 + idx4;
- int iidx2 = idx7 + idx3 - ido + idx4;
- int oidx1 = idx8 + idx5 + idx1;
- int oidx2 = idx8 + idx5 + idx2;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- float o2i = out[oidx2 - 1];
- float o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx2 - 1] = o1i - o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2] = o2r - o1r;
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radfg: Real FFT's forward processing of general factor
- --------------------------------------------------------*/
- void radfg(final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- long idij, ipph, j2, ic, jc, lc, is, nbd;
- float dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
- long iw1 = offset;
-
- arg = TWO_PI / (float) ip;
- dcp = (float)Math.cos(arg);
- dsp = (float)Math.sin(arg);
- ipph = (ip + 1) / 2;
- nbd = (ido - 1) / 2;
- if (ido != 1) {
- for (long ik = 0; ik < idl1; ik++) {
- out.setFloat(out_off + ik, in.getFloat(in_off + ik));
- }
- for (long j = 1; j < ip; j++) {
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido + idx1;
- out.setFloat(out_off + idx2, in.getFloat(in_off + idx2));
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- long idx1 = j * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- w1r = wtable_rl.getFloat(idx2 - 1);
- w1i = wtable_rl.getFloat(idx2);
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long oidx1 = idx5 + idx3;
- long iidx1 = idx4 + idx3;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
-
- out.setFloat(oidx1 - 1, w1r * i1i + w1i * i1r);
- out.setFloat(oidx1, w1r * i1r - w1i * i1i);
- }
- }
- }
- } else {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = is - 1;
- long idx3 = k * ido + idx1;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getFloat(idx2 - 1);
- w1i = wtable_rl.getFloat(idx2);
- long oidx1 = out_off + i + idx3;
- long iidx1 = in_off + i + idx3;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
-
- out.setFloat(oidx1 - 1, w1r * i1i + w1i * i1r);
- out.setFloat(oidx1, w1r * i1r - w1i * i1i);
- }
- }
- }
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- for (long i = 2; i < ido; i += 2) {
- long idx5 = in_off + i;
- long idx6 = out_off + i;
- long iidx1 = idx5 + idx3;
- long iidx2 = idx5 + idx4;
- long oidx1 = idx6 + idx3;
- long oidx2 = idx6 + idx4;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- float o2i = out.getFloat(oidx2 - 1);
- float o2r = out.getFloat(oidx2);
-
- in.setFloat(iidx1 - 1, o1i + o2i);
- in.setFloat(iidx1, o1r + o2r);
-
- in.setFloat(iidx2 - 1, o1r - o2r);
- in.setFloat(iidx2, o2i - o1i);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx5 = in_off + i;
- long idx6 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- long iidx1 = idx5 + idx3;
- long iidx2 = idx5 + idx4;
- long oidx1 = idx6 + idx3;
- long oidx2 = idx6 + idx4;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- float o2i = out.getFloat(oidx2 - 1);
- float o2r = out.getFloat(oidx2);
-
- in.setFloat(iidx1 - 1, o1i + o2i);
- in.setFloat(iidx1, o1r + o2r);
- in.setFloat(iidx2 - 1, o1r - o2r);
- in.setFloat(iidx2, o2i - o1i);
- }
- }
- }
- }
- } else {
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- long oidx1 = out_off + idx3;
- long oidx2 = out_off + idx4;
- float o1r = out.getFloat(oidx1);
- float o2r = out.getFloat(oidx2);
-
- in.setFloat(in_off + idx3, o1r + o2r);
- in.setFloat(in_off + idx4, o2r - o1r);
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- long idx0 = (ip - 1) * idl1;
- for (long l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- long idx1 = l * idl1;
- long idx2 = lc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx3 = out_off + ik;
- long idx4 = in_off + ik;
- out.setFloat(idx3 + idx1, in.getFloat(idx4) + ar1 * in.getFloat(idx4 + idl1));
- out.setFloat(idx3 + idx2, ai1 * in.getFloat(idx4 + idx0));
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- long idx3 = j * idl1;
- long idx4 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx5 = out_off + ik;
- long idx6 = in_off + ik;
- out.setFloat(idx5 + idx1, out.getFloat(idx5 + idx1) + ar2 * in.getFloat(idx6 + idx3));
- out.setFloat(idx5 + idx2, out.getFloat(idx5 + idx2) + ai2 * in.getFloat(idx6 + idx4));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idx1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- out.setFloat(out_off + ik, out.getFloat(out_off + ik) + in.getFloat(in_off + ik + idx1));
- }
- }
-
- if (ido >= l1) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 * ip;
- for (long i = 0; i < ido; i++) {
- in.setFloat(in_off + i + idx2, out.getFloat(out_off + i + idx1));
- }
- }
- } else {
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- in.setFloat(in_off + i + idx1 * ip, out.getFloat(out_off + i + idx1));
- }
- }
- }
- long idx01 = ip * ido;
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido;
- long idx5 = idx4 + idx1;
- long idx6 = idx4 + idx2;
- long idx7 = k * idx01;
- in.setFloat(in_off + ido - 1 + idx3 - ido + idx7, out.getFloat(out_off + idx5));
- in.setFloat(in_off + idx3 + idx7, out.getFloat(out_off + idx6));
- }
- }
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * idx01;
- long idx5 = k * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx6 = in_off + i;
- long idx7 = in_off + ic;
- long idx8 = out_off + i;
- long iidx1 = idx6 + idx3 + idx4;
- long iidx2 = idx7 + idx3 - ido + idx4;
- long oidx1 = idx8 + idx5 + idx1;
- long oidx2 = idx8 + idx5 + idx2;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- float o2i = out.getFloat(oidx2 - 1);
- float o2r = out.getFloat(oidx2);
-
- in.setFloat(iidx1 - 1, o1i + o2i);
- in.setFloat(iidx2 - 1, o1i - o2i);
- in.setFloat(iidx1, o1r + o2r);
- in.setFloat(iidx2, o2r - o1r);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx6 = in_off + i;
- long idx7 = in_off + ic;
- long idx8 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * idx01;
- long idx5 = k * ido;
- long iidx1 = idx6 + idx3 + idx4;
- long iidx2 = idx7 + idx3 - ido + idx4;
- long oidx1 = idx8 + idx5 + idx1;
- long oidx2 = idx8 + idx5 + idx2;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- float o2i = out.getFloat(oidx2 - 1);
- float o2r = out.getFloat(oidx2);
-
- in.setFloat(iidx1 - 1, o1i + o2i);
- in.setFloat(iidx2 - 1, o1i - o2i);
- in.setFloat(iidx1, o1r + o2r);
- in.setFloat(iidx2, o2r - o1r);
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radbg: Real FFT's backward processing of general factor
- --------------------------------------------------------*/
- void radbg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
- int idij, ipph, j2, ic, jc, lc, is;
- float dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
- int nbd;
- float dcp, arg, dsp, ar1h, ar2h;
- int iw1 = offset;
-
- arg = TWO_PI / (float) ip;
- dcp = (float)Math.cos(arg);
- dsp = (float)Math.sin(arg);
- nbd = (ido - 1) / 2;
- ipph = (ip + 1) / 2;
- int idx0 = ip * ido;
- if (ido >= l1) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = k * idx0;
- for (int i = 0; i < ido; i++) {
- out[out_off + i + idx1] = in[in_off + i + idx2];
- }
- }
- } else {
- for (int i = 0; i < ido; i++) {
- int idx1 = out_off + i;
- int idx2 = in_off + i;
- for (int k = 0; k < l1; k++) {
- out[idx1 + k * ido] = in[idx2 + k * idx0];
- }
- }
- }
- int iidx0 = in_off + ido - 1;
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido;
- int idx5 = idx4 * ip;
- int iidx1 = iidx0 + idx3 + idx5 - ido;
- int iidx2 = in_off + idx3 + idx5;
- float i1r = in[iidx1];
- float i2r = in[iidx2];
-
- out[out_off + idx4 + idx1] = i1r + i1r;
- out[out_off + idx4 + idx2] = i2r + i2r;
- }
- }
-
- if (ido != 1) {
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = 2 * j * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido + idx1;
- int idx5 = k * ido + idx2;
- int idx6 = k * ip * ido + idx3;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = out_off + i;
- int idx8 = in_off + ic;
- int idx9 = in_off + i;
- int oidx1 = idx7 + idx4;
- int oidx2 = idx7 + idx5;
- int iidx1 = idx9 + idx6;
- int iidx2 = idx8 + idx6 - ido;
- float a1i = in[iidx1 - 1];
- float a1r = in[iidx1];
- float a2i = in[iidx2 - 1];
- float a2r = in[iidx2];
-
- out[oidx1 - 1] = a1i + a2i;
- out[oidx2 - 1] = a1i - a2i;
- out[oidx1] = a1r - a2r;
- out[oidx2] = a1r + a2r;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = 2 * j * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = out_off + i;
- int idx8 = in_off + ic;
- int idx9 = in_off + i;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido + idx1;
- int idx5 = k * ido + idx2;
- int idx6 = k * ip * ido + idx3;
- int oidx1 = idx7 + idx4;
- int oidx2 = idx7 + idx5;
- int iidx1 = idx9 + idx6;
- int iidx2 = idx8 + idx6 - ido;
- float a1i = in[iidx1 - 1];
- float a1r = in[iidx1];
- float a2i = in[iidx2 - 1];
- float a2r = in[iidx2];
-
- out[oidx1 - 1] = a1i + a2i;
- out[oidx2 - 1] = a1i - a2i;
- out[oidx1] = a1r - a2r;
- out[oidx2] = a1r + a2r;
- }
- }
- }
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- int idx01 = (ip - 1) * idl1;
- for (int l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- int idx1 = l * idl1;
- int idx2 = lc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx3 = in_off + ik;
- int idx4 = out_off + ik;
- in[idx3 + idx1] = out[idx4] + ar1 * out[idx4 + idl1];
- in[idx3 + idx2] = ai1 * out[idx4 + idx01];
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- int idx5 = j * idl1;
- int idx6 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx7 = in_off + ik;
- int idx8 = out_off + ik;
- in[idx7 + idx1] += ar2 * out[idx8 + idx5];
- in[idx7 + idx2] += ai2 * out[idx8 + idx6];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idx1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx2 = out_off + ik;
- out[idx2] += out[idx2 + idx1];
- }
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int oidx1 = out_off + idx3;
- int iidx1 = in_off + idx3 + idx1;
- int iidx2 = in_off + idx3 + idx2;
- float i1r = in[iidx1];
- float i2r = in[iidx2];
-
- out[oidx1 + idx1] = i1r - i2r;
- out[oidx1 + idx2] = i1r + i2r;
- }
- }
-
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx4 = out_off + i;
- int idx5 = in_off + i;
- int oidx1 = idx4 + idx3 + idx1;
- int oidx2 = idx4 + idx3 + idx2;
- int iidx1 = idx5 + idx3 + idx1;
- int iidx2 = idx5 + idx3 + idx2;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
-
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx4 = out_off + i;
- int idx5 = in_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int oidx1 = idx4 + idx3 + idx1;
- int oidx2 = idx4 + idx3 + idx2;
- int iidx1 = idx5 + idx3 + idx1;
- int iidx2 = idx5 + idx3 + idx2;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
-
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- }
- }
- System.arraycopy(out, out_off, in, in_off, idl1);
- for (int j = 1; j < ip; j++) {
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido + idx1;
- in[in_off + idx2] = out[out_off + idx2];
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- int idx1 = j * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int iidx1 = idx4 + idx3;
- int oidx1 = idx5 + idx3;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
-
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- } else {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = is - 1;
- int idx3 = k * ido + idx1;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- int iidx1 = idx4 + idx3;
- int oidx1 = idx5 + idx3;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
-
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
-
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radbg: Real FFT's backward processing of general factor
- --------------------------------------------------------*/
- void radbg(final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
- long idij, ipph, j2, ic, jc, lc, is;
- float dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
- long nbd;
- float dcp, arg, dsp, ar1h, ar2h;
- long iw1 = offset;
-
- arg = TWO_PI / (float) ip;
- dcp = (float)Math.cos(arg);
- dsp = (float)Math.sin(arg);
- nbd = (ido - 1) / 2;
- ipph = (ip + 1) / 2;
- long idx0 = ip * ido;
- if (ido >= l1) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = k * idx0;
- for (long i = 0; i < ido; i++) {
- out.setFloat(out_off + i + idx1, in.getFloat(in_off + i + idx2));
- }
- }
- } else {
- for (long i = 0; i < ido; i++) {
- long idx1 = out_off + i;
- long idx2 = in_off + i;
- for (long k = 0; k < l1; k++) {
- out.setFloat(idx1 + k * ido, in.getFloat(idx2 + k * idx0));
- }
- }
- }
- long iidx0 = in_off + ido - 1;
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido;
- long idx5 = idx4 * ip;
- long iidx1 = iidx0 + idx3 + idx5 - ido;
- long iidx2 = in_off + idx3 + idx5;
- float i1r = in.getFloat(iidx1);
- float i2r = in.getFloat(iidx2);
-
- out.setFloat(out_off + idx4 + idx1, i1r + i1r);
- out.setFloat(out_off + idx4 + idx2, i2r + i2r);
- }
- }
-
- if (ido != 1) {
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = 2 * j * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido + idx1;
- long idx5 = k * ido + idx2;
- long idx6 = k * ip * ido + idx3;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = out_off + i;
- long idx8 = in_off + ic;
- long idx9 = in_off + i;
- long oidx1 = idx7 + idx4;
- long oidx2 = idx7 + idx5;
- long iidx1 = idx9 + idx6;
- long iidx2 = idx8 + idx6 - ido;
- float a1i = in.getFloat(iidx1 - 1);
- float a1r = in.getFloat(iidx1);
- float a2i = in.getFloat(iidx2 - 1);
- float a2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1 - 1, a1i + a2i);
- out.setFloat(oidx2 - 1, a1i - a2i);
- out.setFloat(oidx1, a1r - a2r);
- out.setFloat(oidx2, a1r + a2r);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = 2 * j * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = out_off + i;
- long idx8 = in_off + ic;
- long idx9 = in_off + i;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido + idx1;
- long idx5 = k * ido + idx2;
- long idx6 = k * ip * ido + idx3;
- long oidx1 = idx7 + idx4;
- long oidx2 = idx7 + idx5;
- long iidx1 = idx9 + idx6;
- long iidx2 = idx8 + idx6 - ido;
- float a1i = in.getFloat(iidx1 - 1);
- float a1r = in.getFloat(iidx1);
- float a2i = in.getFloat(iidx2 - 1);
- float a2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1 - 1, a1i + a2i);
- out.setFloat(oidx2 - 1, a1i - a2i);
- out.setFloat(oidx1, a1r - a2r);
- out.setFloat(oidx2, a1r + a2r);
- }
- }
- }
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- long idx01 = (ip - 1) * idl1;
- for (long l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- long idx1 = l * idl1;
- long idx2 = lc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx3 = in_off + ik;
- long idx4 = out_off + ik;
- in.setFloat(idx3 + idx1, out.getFloat(idx4) + ar1 * out.getFloat(idx4 + idl1));
- in.setFloat(idx3 + idx2, ai1 * out.getFloat(idx4 + idx01));
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- long idx5 = j * idl1;
- long idx6 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx7 = in_off + ik;
- long idx8 = out_off + ik;
- in.setFloat(idx7 + idx1, in.getFloat(idx7 + idx1) + ar2 * out.getFloat(idx8 + idx5));
- in.setFloat(idx7 + idx2, in.getFloat(idx7 + idx2) + ai2 * out.getFloat(idx8 + idx6));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idx1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx2 = out_off + ik;
- out.setFloat(idx2, out.getFloat(idx2) + out.getFloat(idx2 + idx1));
- }
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long oidx1 = out_off + idx3;
- long iidx1 = in_off + idx3 + idx1;
- long iidx2 = in_off + idx3 + idx2;
- float i1r = in.getFloat(iidx1);
- float i2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1 + idx1, i1r - i2r);
- out.setFloat(oidx1 + idx2, i1r + i2r);
- }
- }
-
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx4 = out_off + i;
- long idx5 = in_off + i;
- long oidx1 = idx4 + idx3 + idx1;
- long oidx2 = idx4 + idx3 + idx2;
- long iidx1 = idx5 + idx3 + idx1;
- long iidx2 = idx5 + idx3 + idx2;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1 - 1, i1i - i2r);
- out.setFloat(oidx2 - 1, i1i + i2r);
- out.setFloat(oidx1, i1r + i2i);
- out.setFloat(oidx2, i1r - i2i);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx4 = out_off + i;
- long idx5 = in_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long oidx1 = idx4 + idx3 + idx1;
- long oidx2 = idx4 + idx3 + idx2;
- long iidx1 = idx5 + idx3 + idx1;
- long iidx2 = idx5 + idx3 + idx2;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
-
- out.setFloat(oidx1 - 1, i1i - i2r);
- out.setFloat(oidx2 - 1, i1i + i2r);
- out.setFloat(oidx1, i1r + i2i);
- out.setFloat(oidx2, i1r - i2i);
- }
- }
- }
- }
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- for (long j = 1; j < ip; j++) {
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido + idx1;
- in.setFloat(in_off + idx2, out.getFloat(out_off + idx2));
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- long idx1 = j * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getFloat(idx2 - 1);
- w1i = wtable_rl.getFloat(idx2);
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long iidx1 = idx4 + idx3;
- long oidx1 = idx5 + idx3;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
-
- in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setFloat(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- } else {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = is - 1;
- long idx3 = k * ido + idx1;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getFloat(idx2 - 1);
- w1i = wtable_rl.getFloat(idx2);
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- long iidx1 = idx4 + idx3;
- long oidx1 = idx5 + idx3;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
-
- in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setFloat(iidx1, w1r * o1r + w1i * o1i);
-
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- cfftf1: further processing of Complex forward FFT
- --------------------------------------------------------*/
- void cfftf(float a[], int offa, int isign) {
- int idot;
- int l1, l2;
- int na, nf, ipll, iw, ido, idl1;
- int[] nac = new int[1];
- final int twon = 2 * n;
-
- int iw1, iw2;
- float[] ch = new float[twon];
-
- iw1 = twon;
- iw2 = 4 * n;
- nac[0] = 0;
- nf = (int) wtable[1 + iw2];
- na = 0;
- l1 = 1;
- iw = iw1;
- for (int k1 = 2; k1 <= nf + 1; k1++) {
- ipll = (int) wtable[k1 + iw2];
- l2 = ipll * l1;
- ido = n / l2;
- idot = ido + ido;
- idl1 = idot * l1;
- switch (ipll) {
- case 4:
- if (na == 0) {
- passf4(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf4(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 2:
- if (na == 0) {
- passf2(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf2(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- passf3(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf3(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- passf5(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf5(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
- } else {
- passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
- }
- if (nac[0] != 0) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * idot;
- }
- if (na == 0) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, twon);
-
- }
-
- /*---------------------------------------------------------
- cfftf1: further processing of Complex forward FFT
- --------------------------------------------------------*/
- void cfftf(FloatLargeArray a, long offa, int isign) {
- long idot;
- long l1, l2;
- long na, nf, iw, ido, idl1;
- int[] nac = new int[1];
- final long twon = 2 * nl;
- int ipll;
-
- long iw1, iw2;
- FloatLargeArray ch = new FloatLargeArray(twon, false);
-
- iw1 = twon;
- iw2 = 4 * nl;
- nac[0] = 0;
- nf = (long) wtablel.getFloat(1 + iw2);
- na = 0;
- l1 = 1;
- iw = iw1;
- for (long k1 = 2; k1 <= nf + 1; k1++) {
- ipll = (int) wtablel.getFloat(k1 + iw2);
- l2 = ipll * l1;
- ido = nl / l2;
- idot = ido + ido;
- idl1 = idot * l1;
- switch (ipll) {
- case 4:
- if (na == 0) {
- passf4(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf4(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 2:
- if (na == 0) {
- passf2(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf2(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- passf3(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf3(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- passf5(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf5(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
- } else {
- passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
- }
- if (nac[0] != 0) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * idot;
- }
- if (na == 0) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, twon);
-
- }
-
- /*----------------------------------------------------------------------
- passf2: Complex FFT's forward/backward processing of factor 2;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
- float t1i, t1r;
- int iw1;
- iw1 = offset;
- int idx = ido * l1;
- if (ido <= 2) {
- for (int k = 0; k < l1; k++) {
- int idx0 = k * ido;
- int iidx1 = in_off + 2 * idx0;
- int iidx2 = iidx1 + ido;
- float a1r = in[iidx1];
- float a1i = in[iidx1 + 1];
- float a2r = in[iidx2];
- float a2i = in[iidx2 + 1];
-
- int oidx1 = out_off + idx0;
- int oidx2 = oidx1 + idx;
- out[oidx1] = a1r + a2r;
- out[oidx1 + 1] = a1i + a2i;
- out[oidx2] = a1r - a2r;
- out[oidx2 + 1] = a1i - a2i;
- }
- } else {
- for (int k = 0; k < l1; k++) {
- for (int i = 0; i < ido - 1; i += 2) {
- int idx0 = k * ido;
- int iidx1 = in_off + i + 2 * idx0;
- int iidx2 = iidx1 + ido;
- float i1r = in[iidx1];
- float i1i = in[iidx1 + 1];
- float i2r = in[iidx2];
- float i2i = in[iidx2 + 1];
-
- int widx1 = i + iw1;
- float w1r = wtable[widx1];
- float w1i = isign * wtable[widx1 + 1];
-
- t1r = i1r - i2r;
- t1i = i1i - i2i;
-
- int oidx1 = out_off + i + idx0;
- int oidx2 = oidx1 + idx;
- out[oidx1] = i1r + i2r;
- out[oidx1 + 1] = i1i + i2i;
- out[oidx2] = w1r * t1r - w1i * t1i;
- out[oidx2 + 1] = w1r * t1i + w1i * t1r;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf2: Complex FFT's forward/backward processing of factor 2;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
- float t1i, t1r;
- long iw1;
- iw1 = offset;
- long idx = ido * l1;
- if (ido <= 2) {
- for (long k = 0; k < l1; k++) {
- long idx0 = k * ido;
- long iidx1 = in_off + 2 * idx0;
- long iidx2 = iidx1 + ido;
- float a1r = in.getFloat(iidx1);
- float a1i = in.getFloat(iidx1 + 1);
- float a2r = in.getFloat(iidx2);
- float a2i = in.getFloat(iidx2 + 1);
-
- long oidx1 = out_off + idx0;
- long oidx2 = oidx1 + idx;
- out.setFloat(oidx1, a1r + a2r);
- out.setFloat(oidx1 + 1, a1i + a2i);
- out.setFloat(oidx2, a1r - a2r);
- out.setFloat(oidx2 + 1, a1i - a2i);
- }
- } else {
- for (long k = 0; k < l1; k++) {
- for (long i = 0; i < ido - 1; i += 2) {
- long idx0 = k * ido;
- long iidx1 = in_off + i + 2 * idx0;
- long iidx2 = iidx1 + ido;
- float i1r = in.getFloat(iidx1);
- float i1i = in.getFloat(iidx1 + 1);
- float i2r = in.getFloat(iidx2);
- float i2i = in.getFloat(iidx2 + 1);
-
- long widx1 = i + iw1;
- float w1r = wtablel.getFloat(widx1);
- float w1i = isign * wtablel.getFloat(widx1 + 1);
-
- t1r = i1r - i2r;
- t1i = i1i - i2i;
-
- long oidx1 = out_off + i + idx0;
- long oidx2 = oidx1 + idx;
- out.setFloat(oidx1, i1r + i2r);
- out.setFloat(oidx1 + 1, i1i + i2i);
- out.setFloat(oidx2, w1r * t1r - w1i * t1i);
- out.setFloat(oidx2 + 1, w1r * t1i + w1i * t1r);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf3: Complex FFT's forward/backward processing of factor 3;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
- int iw1, iw2;
-
- iw1 = offset;
- iw2 = iw1 + ido;
-
- final int idxt = l1 * ido;
-
- if (ido == 2) {
- for (int k = 1; k <= l1; k++) {
- int iidx1 = in_off + (3 * k - 2) * ido;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- float i1r = in[iidx1];
- float i1i = in[iidx1 + 1];
- float i2r = in[iidx2];
- float i2i = in[iidx2 + 1];
- float i3r = in[iidx3];
- float i3i = in[iidx3 + 1];
-
- tr2 = i1r + i2r;
- cr2 = i3r + taur * tr2;
- ti2 = i1i + i2i;
- ci2 = i3i + taur * ti2;
- cr3 = isign * taui * (i1r - i2r);
- ci3 = isign * taui * (i1i - i2i);
-
- int oidx1 = out_off + (k - 1) * ido;
- int oidx2 = oidx1 + idxt;
- int oidx3 = oidx2 + idxt;
- out[oidx1] = in[iidx3] + tr2;
- out[oidx1 + 1] = i3i + ti2;
- out[oidx2] = cr2 - ci3;
- out[oidx2 + 1] = ci2 + cr3;
- out[oidx3] = cr2 + ci3;
- out[oidx3 + 1] = ci2 - cr3;
- }
- } else {
- for (int k = 1; k <= l1; k++) {
- int idx1 = in_off + (3 * k - 2) * ido;
- int idx2 = out_off + (k - 1) * ido;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- float a1r = in[iidx1];
- float a1i = in[iidx1 + 1];
- float a2r = in[iidx2];
- float a2i = in[iidx2 + 1];
- float a3r = in[iidx3];
- float a3i = in[iidx3 + 1];
-
- tr2 = a1r + a2r;
- cr2 = a3r + taur * tr2;
- ti2 = a1i + a2i;
- ci2 = a3i + taur * ti2;
- cr3 = isign * taui * (a1r - a2r);
- ci3 = isign * taui * (a1i - a2i);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- float w1r = wtable[widx1];
- float w1i = isign * wtable[widx1 + 1];
- float w2r = wtable[widx2];
- float w2i = isign * wtable[widx2 + 1];
-
- int oidx1 = i + idx2;
- int oidx2 = oidx1 + idxt;
- int oidx3 = oidx2 + idxt;
- out[oidx1] = a3r + tr2;
- out[oidx1 + 1] = a3i + ti2;
- out[oidx2] = w1r * dr2 - w1i * di2;
- out[oidx2 + 1] = w1r * di2 + w1i * dr2;
- out[oidx3] = w2r * dr3 - w2i * di3;
- out[oidx3 + 1] = w2r * di3 + w2i * dr3;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf3: Complex FFT's forward/backward processing of factor 3;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
- final float taur = -0.5f;
- final float taui = 0.866025403784438707610604524234076962f;
- float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
- long iw1, iw2;
-
- iw1 = offset;
- iw2 = iw1 + ido;
-
- final long idxt = l1 * ido;
-
- if (ido == 2) {
- for (long k = 1; k <= l1; k++) {
- long iidx1 = in_off + (3 * k - 2) * ido;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- float i1r = in.getFloat(iidx1);
- float i1i = in.getFloat(iidx1 + 1);
- float i2r = in.getFloat(iidx2);
- float i2i = in.getFloat(iidx2 + 1);
- float i3r = in.getFloat(iidx3);
- float i3i = in.getFloat(iidx3 + 1);
-
- tr2 = i1r + i2r;
- cr2 = i3r + taur * tr2;
- ti2 = i1i + i2i;
- ci2 = i3i + taur * ti2;
- cr3 = isign * taui * (i1r - i2r);
- ci3 = isign * taui * (i1i - i2i);
-
- long oidx1 = out_off + (k - 1) * ido;
- long oidx2 = oidx1 + idxt;
- long oidx3 = oidx2 + idxt;
- out.setFloat(oidx1, in.getFloat(iidx3) + tr2);
- out.setFloat(oidx1 + 1, i3i + ti2);
- out.setFloat(oidx2, cr2 - ci3);
- out.setFloat(oidx2 + 1, ci2 + cr3);
- out.setFloat(oidx3, cr2 + ci3);
- out.setFloat(oidx3 + 1, ci2 - cr3);
- }
- } else {
- for (long k = 1; k <= l1; k++) {
- long idx1 = in_off + (3 * k - 2) * ido;
- long idx2 = out_off + (k - 1) * ido;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- float a1r = in.getFloat(iidx1);
- float a1i = in.getFloat(iidx1 + 1);
- float a2r = in.getFloat(iidx2);
- float a2i = in.getFloat(iidx2 + 1);
- float a3r = in.getFloat(iidx3);
- float a3i = in.getFloat(iidx3 + 1);
-
- tr2 = a1r + a2r;
- cr2 = a3r + taur * tr2;
- ti2 = a1i + a2i;
- ci2 = a3i + taur * ti2;
- cr3 = isign * taui * (a1r - a2r);
- ci3 = isign * taui * (a1i - a2i);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- float w1r = wtablel.getFloat(widx1);
- float w1i = isign * wtablel.getFloat(widx1 + 1);
- float w2r = wtablel.getFloat(widx2);
- float w2i = isign * wtablel.getFloat(widx2 + 1);
-
- long oidx1 = i + idx2;
- long oidx2 = oidx1 + idxt;
- long oidx3 = oidx2 + idxt;
- out.setFloat(oidx1, a3r + tr2);
- out.setFloat(oidx1 + 1, a3i + ti2);
- out.setFloat(oidx2, w1r * dr2 - w1i * di2);
- out.setFloat(oidx2 + 1, w1r * di2 + w1i * dr2);
- out.setFloat(oidx3, w2r * dr3 - w2i * di3);
- out.setFloat(oidx3 + 1, w2r * di3 + w2i * dr3);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf4: Complex FFT's forward/backward processing of factor 4;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
- float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- int idx0 = l1 * ido;
- if (ido == 2) {
- for (int k = 0; k < l1; k++) {
- int idxt1 = k * ido;
- int iidx1 = in_off + 4 * idxt1 + 1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx2 + ido;
- int iidx4 = iidx3 + ido;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- tr4 = i4r - i2r;
- ti3 = i2r + i4r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
-
- int oidx1 = out_off + idxt1;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- out[oidx1] = tr2 + tr3;
- out[oidx1 + 1] = ti2 + ti3;
- out[oidx2] = tr1 + isign * tr4;
- out[oidx2 + 1] = ti1 + isign * ti4;
- out[oidx3] = tr2 - tr3;
- out[oidx3 + 1] = ti2 - ti3;
- out[oidx4] = tr1 - isign * tr4;
- out[oidx4 + 1] = ti1 - isign * ti4;
- }
- } else {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = in_off + 1 + 4 * idx1;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx2;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx2 + ido;
- int iidx4 = iidx3 + ido;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- ti3 = i2r + i4r;
- tr4 = i4r - i2r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 + isign * tr4;
- cr4 = tr1 - isign * tr4;
- ci2 = ti1 + isign * ti4;
- ci4 = ti1 - isign * ti4;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- int widx3 = i + iw3;
- float w1r = wtable[widx1];
- float w1i = isign * wtable[widx1 + 1];
- float w2r = wtable[widx2];
- float w2i = isign * wtable[widx2 + 1];
- float w3r = wtable[widx3];
- float w3i = isign * wtable[widx3 + 1];
-
- int oidx1 = out_off + i + idx1;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- out[oidx1] = tr2 + tr3;
- out[oidx1 + 1] = ti2 + ti3;
- out[oidx2] = w1r * cr2 - w1i * ci2;
- out[oidx2 + 1] = w1r * ci2 + w1i * cr2;
- out[oidx3] = w2r * cr3 - w2i * ci3;
- out[oidx3 + 1] = w2r * ci3 + w2i * cr3;
- out[oidx4] = w3r * cr4 - w3i * ci4;
- out[oidx4 + 1] = w3r * ci4 + w3i * cr4;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf4: Complex FFT's forward/backward processing of factor 4;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final int isign) {
- float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- long idx0 = l1 * ido;
- if (ido == 2) {
- for (long k = 0; k < l1; k++) {
- long idxt1 = k * ido;
- long iidx1 = in_off + 4 * idxt1 + 1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx2 + ido;
- long iidx4 = iidx3 + ido;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- tr4 = i4r - i2r;
- ti3 = i2r + i4r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
-
- long oidx1 = out_off + idxt1;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- out.setFloat(oidx1, tr2 + tr3);
- out.setFloat(oidx1 + 1, ti2 + ti3);
- out.setFloat(oidx2, tr1 + isign * tr4);
- out.setFloat(oidx2 + 1, ti1 + isign * ti4);
- out.setFloat(oidx3, tr2 - tr3);
- out.setFloat(oidx3 + 1, ti2 - ti3);
- out.setFloat(oidx4, tr1 - isign * tr4);
- out.setFloat(oidx4 + 1, ti1 - isign * ti4);
- }
- } else {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = in_off + 1 + 4 * idx1;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx2;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx2 + ido;
- long iidx4 = iidx3 + ido;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- ti3 = i2r + i4r;
- tr4 = i4r - i2r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 + isign * tr4;
- cr4 = tr1 - isign * tr4;
- ci2 = ti1 + isign * ti4;
- ci4 = ti1 - isign * ti4;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- long widx3 = i + iw3;
- float w1r = wtablel.getFloat(widx1);
- float w1i = isign * wtablel.getFloat(widx1 + 1);
- float w2r = wtablel.getFloat(widx2);
- float w2i = isign * wtablel.getFloat(widx2 + 1);
- float w3r = wtablel.getFloat(widx3);
- float w3i = isign * wtablel.getFloat(widx3 + 1);
-
- long oidx1 = out_off + i + idx1;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- out.setFloat(oidx1, tr2 + tr3);
- out.setFloat(oidx1 + 1, ti2 + ti3);
- out.setFloat(oidx2, w1r * cr2 - w1i * ci2);
- out.setFloat(oidx2 + 1, w1r * ci2 + w1i * cr2);
- out.setFloat(oidx3, w2r * cr3 - w2i * ci3);
- out.setFloat(oidx3 + 1, w2r * ci3 + w2i * cr3);
- out.setFloat(oidx4, w3r * cr4 - w3i * ci4);
- out.setFloat(oidx4 + 1, w3r * ci4 + w3i * cr4);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf5: Complex FFT's forward/backward processing of factor 5;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) /* isign==-1 for forward transform and+1 for backward transform */ {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
- int iw1, iw2, iw3, iw4;
-
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
-
- if (ido == 2) {
- for (int k = 1; k <= l1; ++k) {
- int iidx1 = in_off + (5 * k - 4) * ido + 1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- int iidx4 = iidx2 + ido;
- int iidx5 = iidx4 + ido;
-
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
- float i5i = in[iidx5 - 1];
- float i5r = in[iidx5];
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
-
- int oidx1 = out_off + (k - 1) * ido;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- int oidx5 = oidx4 + idx0;
- out[oidx1] = i3i + tr2 + tr3;
- out[oidx1 + 1] = i3r + ti2 + ti3;
- out[oidx2] = cr2 - ci5;
- out[oidx2 + 1] = ci2 + cr5;
- out[oidx3] = cr3 - ci4;
- out[oidx3 + 1] = ci3 + cr4;
- out[oidx4] = cr3 + ci4;
- out[oidx4 + 1] = ci3 - cr4;
- out[oidx5] = cr2 + ci5;
- out[oidx5 + 1] = ci2 - cr5;
- }
- } else {
- for (int k = 1; k <= l1; k++) {
- int idx1 = in_off + 1 + (k * 5 - 4) * ido;
- int idx2 = out_off + (k - 1) * ido;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- int iidx4 = iidx2 + ido;
- int iidx5 = iidx4 + ido;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
- float i3i = in[iidx3 - 1];
- float i3r = in[iidx3];
- float i4i = in[iidx4 - 1];
- float i4r = in[iidx4];
- float i5i = in[iidx5 - 1];
- float i5r = in[iidx5];
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- int widx3 = i + iw3;
- int widx4 = i + iw4;
- float w1r = wtable[widx1];
- float w1i = isign * wtable[widx1 + 1];
- float w2r = wtable[widx2];
- float w2i = isign * wtable[widx2 + 1];
- float w3r = wtable[widx3];
- float w3i = isign * wtable[widx3 + 1];
- float w4r = wtable[widx4];
- float w4i = isign * wtable[widx4 + 1];
-
- int oidx1 = i + idx2;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- int oidx5 = oidx4 + idx0;
- out[oidx1] = i3i + tr2 + tr3;
- out[oidx1 + 1] = i3r + ti2 + ti3;
- out[oidx2] = w1r * dr2 - w1i * di2;
- out[oidx2 + 1] = w1r * di2 + w1i * dr2;
- out[oidx3] = w2r * dr3 - w2i * di3;
- out[oidx3 + 1] = w2r * di3 + w2i * dr3;
- out[oidx4] = w3r * dr4 - w3i * di4;
- out[oidx4 + 1] = w3r * di4 + w3i * dr4;
- out[oidx5] = w4r * dr5 - w4i * di5;
- out[oidx5 + 1] = w4r * di5 + w4i * dr5;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf5: Complex FFT's forward/backward processing of factor 5;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) /* isign==-1 for forward transform and+1 for backward transform */ {
- final float tr11 = 0.309016994374947451262869435595348477f;
- final float ti11 = 0.951056516295153531181938433292089030f;
- final float tr12 = -0.809016994374947340240566973079694435f;
- final float ti12 = 0.587785252292473248125759255344746634f;
- float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
- long iw1, iw2, iw3, iw4;
-
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
-
- if (ido == 2) {
- for (long k = 1; k <= l1; ++k) {
- long iidx1 = in_off + (5 * k - 4) * ido + 1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- long iidx4 = iidx2 + ido;
- long iidx5 = iidx4 + ido;
-
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
- float i5i = in.getFloat(iidx5 - 1);
- float i5r = in.getFloat(iidx5);
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
-
- long oidx1 = out_off + (k - 1) * ido;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- long oidx5 = oidx4 + idx0;
- out.setFloat(oidx1, i3i + tr2 + tr3);
- out.setFloat(oidx1 + 1, i3r + ti2 + ti3);
- out.setFloat(oidx2, cr2 - ci5);
- out.setFloat(oidx2 + 1, ci2 + cr5);
- out.setFloat(oidx3, cr3 - ci4);
- out.setFloat(oidx3 + 1, ci3 + cr4);
- out.setFloat(oidx4, cr3 + ci4);
- out.setFloat(oidx4 + 1, ci3 - cr4);
- out.setFloat(oidx5, cr2 + ci5);
- out.setFloat(oidx5 + 1, ci2 - cr5);
- }
- } else {
- for (long k = 1; k <= l1; k++) {
- long idx1 = in_off + 1 + (k * 5 - 4) * ido;
- long idx2 = out_off + (k - 1) * ido;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- long iidx4 = iidx2 + ido;
- long iidx5 = iidx4 + ido;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
- float i3i = in.getFloat(iidx3 - 1);
- float i3r = in.getFloat(iidx3);
- float i4i = in.getFloat(iidx4 - 1);
- float i4r = in.getFloat(iidx4);
- float i5i = in.getFloat(iidx5 - 1);
- float i5r = in.getFloat(iidx5);
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- long widx3 = i + iw3;
- long widx4 = i + iw4;
- float w1r = wtablel.getFloat(widx1);
- float w1i = isign * wtablel.getFloat(widx1 + 1);
- float w2r = wtablel.getFloat(widx2);
- float w2i = isign * wtablel.getFloat(widx2 + 1);
- float w3r = wtablel.getFloat(widx3);
- float w3i = isign * wtablel.getFloat(widx3 + 1);
- float w4r = wtablel.getFloat(widx4);
- float w4i = isign * wtablel.getFloat(widx4 + 1);
-
- long oidx1 = i + idx2;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- long oidx5 = oidx4 + idx0;
- out.setFloat(oidx1, i3i + tr2 + tr3);
- out.setFloat(oidx1 + 1, i3r + ti2 + ti3);
- out.setFloat(oidx2, w1r * dr2 - w1i * di2);
- out.setFloat(oidx2 + 1, w1r * di2 + w1i * dr2);
- out.setFloat(oidx3, w2r * dr3 - w2i * di3);
- out.setFloat(oidx3 + 1, w2r * di3 + w2i * dr3);
- out.setFloat(oidx4, w3r * dr4 - w3i * di4);
- out.setFloat(oidx4 + 1, w3r * di4 + w3i * dr4);
- out.setFloat(oidx5, w4r * dr5 - w4i * di5);
- out.setFloat(oidx5 + 1, w4r * di5 + w4i * dr5);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passfg: Complex FFT's forward/backward processing of general factor;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passfg(final int nac[], final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
- int idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
- float w1r, w1i, w2i, w2r;
- int iw1;
-
- iw1 = offset;
- idot = ido / 2;
- ipph = (ip + 1) / 2;
- idp = ip * ido;
- if (ido >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * ido;
- int idx2 = jc * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int idx4 = idx3 + idx1 * l1;
- int idx5 = idx3 + idx2 * l1;
- int idx6 = idx3 * ip;
- for (int i = 0; i < ido; i++) {
- int oidx1 = out_off + i;
- float i1r = in[in_off + i + idx1 + idx6];
- float i2r = in[in_off + i + idx2 + idx6];
- out[oidx1 + idx4] = i1r + i2r;
- out[oidx1 + idx5] = i1r - i2r;
- }
- }
- }
- for (int k = 0; k < l1; k++) {
- int idxt1 = k * ido;
- int idxt2 = idxt1 * ip;
- for (int i = 0; i < ido; i++) {
- out[out_off + i + idxt1] = in[in_off + i + idxt2];
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idxt1 = j * l1 * ido;
- int idxt2 = jc * l1 * ido;
- int idxt3 = j * ido;
- int idxt4 = jc * ido;
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 * ip;
- int idx3 = out_off + i;
- int idx4 = in_off + i;
- float i1r = in[idx4 + idxt3 + idx2];
- float i2r = in[idx4 + idxt4 + idx2];
- out[idx3 + idx1 + idxt1] = i1r + i2r;
- out[idx3 + idx1 + idxt2] = i1r - i2r;
- }
- }
- }
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- out[out_off + i + idx1] = in[in_off + i + idx1 * ip];
- }
- }
- }
-
- idl = 2 - ido;
- inc = 0;
- int idxt0 = (ip - 1) * idl1;
- for (l = 1; l < ipph; l++) {
- lc = ip - l;
- idl += ido;
- int idxt1 = l * idl1;
- int idxt2 = lc * idl1;
- int idxt3 = idl + iw1;
- w1r = wtable[idxt3 - 2];
- w1i = isign * wtable[idxt3 - 1];
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = in_off + ik;
- int idx2 = out_off + ik;
- in[idx1 + idxt1] = out[idx2] + w1r * out[idx2 + idl1];
- in[idx1 + idxt2] = w1i * out[idx2 + idxt0];
- }
- idlj = idl;
- inc += ido;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- idlj += inc;
- if (idlj > idp) {
- idlj -= idp;
- }
- int idxt4 = idlj + iw1;
- w2r = wtable[idxt4 - 2];
- w2i = isign * wtable[idxt4 - 1];
- int idxt5 = j * idl1;
- int idxt6 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = in_off + ik;
- int idx2 = out_off + ik;
- in[idx1 + idxt1] += w2r * out[idx2 + idxt5];
- in[idx1 + idxt2] += w2i * out[idx2 + idxt6];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idxt1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = out_off + ik;
- out[idx1] += out[idx1 + idxt1];
- }
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * idl1;
- int idx2 = jc * idl1;
- for (int ik = 1; ik < idl1; ik += 2) {
- int idx3 = out_off + ik;
- int idx4 = in_off + ik;
- int iidx1 = idx4 + idx1;
- int iidx2 = idx4 + idx2;
- float i1i = in[iidx1 - 1];
- float i1r = in[iidx1];
- float i2i = in[iidx2 - 1];
- float i2r = in[iidx2];
-
- int oidx1 = idx3 + idx1;
- int oidx2 = idx3 + idx2;
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- nac[0] = 1;
- if (ido == 2) {
- return;
- }
- nac[0] = 0;
- System.arraycopy(out, out_off, in, in_off, idl1);
- int idx0 = l1 * ido;
- for (int j = 1; j < ip; j++) {
- int idx1 = j * idx0;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido;
- int oidx1 = out_off + idx2 + idx1;
- int iidx1 = in_off + idx2 + idx1;
- in[iidx1] = out[oidx1];
- in[iidx1 + 1] = out[oidx1 + 1];
- }
- }
- if (idot <= l1) {
- idij = 0;
- for (int j = 1; j < ip; j++) {
- idij += 2;
- int idx1 = j * l1 * ido;
- for (int i = 3; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1 - 1;
- w1r = wtable[idx2 - 1];
- w1i = isign * wtable[idx2];
- int idx3 = in_off + i;
- int idx4 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx5 = k * ido + idx1;
- int iidx1 = idx3 + idx5;
- int oidx1 = idx4 + idx5;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- } else {
- idj = 2 - ido;
- for (int j = 1; j < ip; j++) {
- idj += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = idj;
- int idx3 = k * ido + idx1;
- for (int i = 3; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij - 1 + iw1;
- w1r = wtable[idx2 - 1];
- w1i = isign * wtable[idx2];
- int iidx1 = in_off + i + idx3;
- int oidx1 = out_off + i + idx3;
- float o1i = out[oidx1 - 1];
- float o1r = out[oidx1];
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passfg: Complex FFT's forward/backward processing of general factor;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passfg(final int nac[], final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
- long idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
- float w1r, w1i, w2i, w2r;
- long iw1;
-
- iw1 = offset;
- idot = ido / 2;
- ipph = (ip + 1) / 2;
- idp = ip * ido;
- if (ido >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * ido;
- long idx2 = jc * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long idx4 = idx3 + idx1 * l1;
- long idx5 = idx3 + idx2 * l1;
- long idx6 = idx3 * ip;
- for (long i = 0; i < ido; i++) {
- long oidx1 = out_off + i;
- float i1r = in.getFloat(in_off + i + idx1 + idx6);
- float i2r = in.getFloat(in_off + i + idx2 + idx6);
- out.setFloat(oidx1 + idx4, i1r + i2r);
- out.setFloat(oidx1 + idx5, i1r - i2r);
- }
- }
- }
- for (long k = 0; k < l1; k++) {
- long idxt1 = k * ido;
- long idxt2 = idxt1 * ip;
- for (long i = 0; i < ido; i++) {
- out.setFloat(out_off + i + idxt1, in.getFloat(in_off + i + idxt2));
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idxt1 = j * l1 * ido;
- long idxt2 = jc * l1 * ido;
- long idxt3 = j * ido;
- long idxt4 = jc * ido;
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 * ip;
- long idx3 = out_off + i;
- long idx4 = in_off + i;
- float i1r = in.getFloat(idx4 + idxt3 + idx2);
- float i2r = in.getFloat(idx4 + idxt4 + idx2);
- out.setFloat(idx3 + idx1 + idxt1, i1r + i2r);
- out.setFloat(idx3 + idx1 + idxt2, i1r - i2r);
- }
- }
- }
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- out.setFloat(out_off + i + idx1, in.getFloat(in_off + i + idx1 * ip));
- }
- }
- }
-
- idl = 2 - ido;
- inc = 0;
- long idxt0 = (ip - 1) * idl1;
- for (l = 1; l < ipph; l++) {
- lc = ip - l;
- idl += ido;
- long idxt1 = l * idl1;
- long idxt2 = lc * idl1;
- long idxt3 = idl + iw1;
- w1r = wtablel.getFloat(idxt3 - 2);
- w1i = isign * wtablel.getFloat(idxt3 - 1);
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = in_off + ik;
- long idx2 = out_off + ik;
- in.setFloat(idx1 + idxt1, out.getFloat(idx2) + w1r * out.getFloat(idx2 + idl1));
- in.setFloat(idx1 + idxt2, w1i * out.getFloat(idx2 + idxt0));
- }
- idlj = idl;
- inc += ido;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- idlj += inc;
- if (idlj > idp) {
- idlj -= idp;
- }
- long idxt4 = idlj + iw1;
- w2r = wtablel.getFloat(idxt4 - 2);
- w2i = isign * wtablel.getFloat(idxt4 - 1);
- long idxt5 = j * idl1;
- long idxt6 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = in_off + ik;
- long idx2 = out_off + ik;
- in.setFloat(idx1 + idxt1, in.getFloat(idx1 + idxt1) + w2r * out.getFloat(idx2 + idxt5));
- in.setFloat(idx1 + idxt2, in.getFloat(idx1 + idxt2) + w2i * out.getFloat(idx2 + idxt6));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idxt1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = out_off + ik;
- out.setFloat(idx1, out.getFloat(idx1) + out.getFloat(idx1 + idxt1));
- }
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * idl1;
- long idx2 = jc * idl1;
- for (long ik = 1; ik < idl1; ik += 2) {
- long idx3 = out_off + ik;
- long idx4 = in_off + ik;
- long iidx1 = idx4 + idx1;
- long iidx2 = idx4 + idx2;
- float i1i = in.getFloat(iidx1 - 1);
- float i1r = in.getFloat(iidx1);
- float i2i = in.getFloat(iidx2 - 1);
- float i2r = in.getFloat(iidx2);
-
- long oidx1 = idx3 + idx1;
- long oidx2 = idx3 + idx2;
- out.setFloat(oidx1 - 1, i1i - i2r);
- out.setFloat(oidx2 - 1, i1i + i2r);
- out.setFloat(oidx1, i1r + i2i);
- out.setFloat(oidx2, i1r - i2i);
- }
- }
- nac[0] = 1;
- if (ido == 2) {
- return;
- }
- nac[0] = 0;
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- long idx0 = l1 * ido;
- for (long j = 1; j < ip; j++) {
- long idx1 = j * idx0;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido;
- long oidx1 = out_off + idx2 + idx1;
- long iidx1 = in_off + idx2 + idx1;
- in.setFloat(iidx1, out.getFloat(oidx1));
- in.setFloat(iidx1 + 1, out.getFloat(oidx1 + 1));
- }
- }
- if (idot <= l1) {
- idij = 0;
- for (long j = 1; j < ip; j++) {
- idij += 2;
- long idx1 = j * l1 * ido;
- for (long i = 3; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1 - 1;
- w1r = wtablel.getFloat(idx2 - 1);
- w1i = isign * wtablel.getFloat(idx2);
- long idx3 = in_off + i;
- long idx4 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx5 = k * ido + idx1;
- long iidx1 = idx3 + idx5;
- long oidx1 = idx4 + idx5;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setFloat(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- } else {
- idj = 2 - ido;
- for (long j = 1; j < ip; j++) {
- idj += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = idj;
- long idx3 = k * ido + idx1;
- for (long i = 3; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij - 1 + iw1;
- w1r = wtablel.getFloat(idx2 - 1);
- w1i = isign * wtablel.getFloat(idx2);
- long iidx1 = in_off + i + idx3;
- long oidx1 = out_off + i + idx3;
- float o1i = out.getFloat(oidx1 - 1);
- float o1r = out.getFloat(oidx1);
- in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setFloat(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- }
- }
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * JTransforms
+ * Copyright (c) 2007 onward, Piotr Wendykier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Code modified for inclusion with fairSIM:
+// - changed package name
+// - Commented out all dependence on ...LargeArray
+// - based on JTransforms 3.1, git ede249c9824262bd9b5f571e56f7a0fa596f6f20
+
+package org.fairsim.extern.jtransforms;
+
+import java.util.concurrent.Future;
+//import org.jtransforms.utils.CommonUtils;
+//import org.jtransforms.utils.ConcurrencyUtils;
+//import pl.edu.icm.jlargearrays.FloatLargeArray;
+//import pl.edu.icm.jlargearrays.LongLargeArray;
+//import pl.edu.icm.jlargearrays.Utilities;
+
+/**
+ * Computes 1D Discrete Fourier Transform (DFT) of complex and real, single
+ * precision data. The size of the data can be an arbitrary number. This is a
+ * parallel implementation of split-radix and mixed-radix algorithms optimized
+ * for SMP systems. a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + */ + public void complexForward(float[] a) { + complexForward(a, 0); + } + + /** + * Computes 1D forward DFT of complex data leaving the result in + *
a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * + public void complexForward(FloatLargeArray a) { + complexForward(a, 0); + } */ + + /** + * Computes 1D forward DFT of complex data leaving the result in + *
a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param offa index of the first element in array
a
+ */
+ public void complexForward(float[] a, int offa) {
+ /*
+ if (useLargeArrays) {
+ complexForward(new FloatLargeArray(a), offa);
+ } else */ // <-- no LargeArray support
+ if (true) {
+ if (n == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ CommonUtils.cftbsub(2 * n, a, offa, ip, nw, w);
+ break;
+ case MIXED_RADIX:
+ cfftf(a, offa, -1);
+ break;
+ case BLUESTEIN:
+ bluestein_complex(a, offa, -1);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Computes 1D forward DFT of complex data leaving the result in
+ * a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param offa index of the first element in array
a
+ *
+ public void complexForward(FloatLargeArray a, long offa) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ complexForward(a.getData(), (int) offa);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ if (nl == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ CommonUtils.cftbsub(2 * nl, a, offa, ipl, nwl, wl);
+ break;
+ case MIXED_RADIX:
+ cfftf(a, offa, -1);
+ break;
+ case BLUESTEIN:
+ bluestein_complex(a, offa, -1);
+ break;
+ }
+ }
+ } */
+
+ /**
+ * Computes 1D inverse DFT of complex data leaving the result in
+ * a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param scale if true then scaling is performed + */ + public void complexInverse(float[] a, boolean scale) { + complexInverse(a, 0, scale); + } + + /** + * Computes 1D inverse DFT of complex data leaving the result in + *
a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param scale if true then scaling is performed + * + public void complexInverse(FloatLargeArray a, boolean scale) { + complexInverse(a, 0, scale); + } */ + + /** + * Computes 1D inverse DFT of complex data leaving the result in + *
a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param offa index of the first element in array
a
+ * @param scale if true then scaling is performed
+ */
+ public void complexInverse(float[] a, int offa, boolean scale) {
+ /*
+ if (useLargeArrays) {
+ complexInverse(new FloatLargeArray(a), offa, scale);
+ } else */ // <-- no LargeArray support
+ if (true) {
+ if (n == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ CommonUtils.cftfsub(2 * n, a, offa, ip, nw, w);
+ break;
+ case MIXED_RADIX:
+ cfftf(a, offa, +1);
+ break;
+ case BLUESTEIN:
+ bluestein_complex(a, offa, 1);
+ break;
+ }
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / (float) n, a, offa, true);
+ }
+ }
+ }
+
+ /**
+ * Computes 1D inverse DFT of complex data leaving the result in
+ * a. Complex number is stored as two float values in
+ * sequence: the real and imaginary part, i.e. the size of the input array
+ * must be greater or equal 2*n. The physical layout of the input data has
+ * to be as follows:+ * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n + *+ * + * @param a data to transform + * @param offa index of the first element in array
a
+ * @param scale if true then scaling is performed
+ *
+ public void complexInverse(FloatLargeArray a, long offa, boolean scale) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ complexInverse(a.getData(), (int) offa, scale);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ if (nl == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ CommonUtils.cftfsub(2 * nl, a, offa, ipl, nwl, wl);
+ break;
+ case MIXED_RADIX:
+ cfftf(a, offa, +1);
+ break;
+ case BLUESTEIN:
+ bluestein_complex(a, offa, 1);
+ break;
+ }
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / (float) nl, a, offa, true);
+ }
+ }
+ } */
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . The physical layout of the output data is as follows:+ * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = + * Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 + * a[1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForward(float[] a) {
+ realForward(a, 0);
+ }
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . The physical layout of the output data is as follows:+ * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = + * Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 + * a[1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ *
+ public void realForward(FloatLargeArray a) {
+ realForward(a, 0);
+ } */
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . The physical layout of the output data is as follows:+ * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 + * a[offa+1] = Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], + * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ */
+ public void realForward(float[] a, int offa) {
+ /* if (useLargeArrays) {
+ realForward(new FloatLargeArray(a), offa);
+ } else { */ // <-- no LargeArray support
+ if (true) {
+ if (n == 1) {
+ return;
+ }
+
+ switch (plan) {
+ case SPLIT_RADIX:
+ float xi;
+
+ if (n > 4) {
+ CommonUtils.cftfsub(n, a, offa, ip, nw, w);
+ CommonUtils.rftfsub(n, a, offa, nc, w, nw);
+ } else if (n == 4) {
+ CommonUtils.cftx020(a, offa);
+ }
+ xi = a[offa] - a[offa + 1];
+ a[offa] += a[offa + 1];
+ a[offa + 1] = xi;
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ for (int k = n - 1; k >= 2; k--) {
+ int idx = offa + k;
+ float tmp = a[idx];
+ a[idx] = a[idx - 1];
+ a[idx - 1] = tmp;
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_forward(a, offa);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . The physical layout of the output data is as follows:+ * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 + * a[offa+1] = Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], + * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ *
+ public void realForward(FloatLargeArray a, long offa) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ realForward(a.getData(), (int) offa);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ if (nl == 1) {
+ return;
+ }
+
+ switch (plan) {
+ case SPLIT_RADIX:
+ float xi;
+
+ if (nl > 4) {
+ CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
+ CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
+ } else if (nl == 4) {
+ CommonUtils.cftx020(a, offa);
+ }
+ xi = a.getFloat(offa) - a.getFloat(offa + 1);
+ a.setFloat(offa, a.getFloat(offa) + a.getFloat(offa + 1));
+ a.setFloat(offa + 1, xi);
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ for (long k = nl - 1; k >= 2; k--) {
+ long idx = offa + k;
+ float tmp = a.getFloat(idx);
+ a.setFloat(idx, a.getFloat(idx - 1));
+ a.setFloat(idx - 1, tmp);
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_forward(a, offa);
+ break;
+ }
+ }
+ } */
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . This method computes the full real forward transform, i.e. you will get
+ * the same result as from complexForward called with all
+ * imaginary parts equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data. To get back the original data,
+ * use complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForwardFull(float[] a) {
+ realForwardFull(a, 0);
+ }
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . This method computes the full real forward transform, i.e. you will get
+ * the same result as from complexForward called with all
+ * imaginary parts equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data. To get back the original data,
+ * use complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ *
+ public void realForwardFull(FloatLargeArray a) {
+ realForwardFull(a, 0);
+ } */
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . This method computes the full real forward transform, i.e. you will get
+ * the same result as from complexForward called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data. To get back the original data,
+ * use complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ */
+ public void realForwardFull(final float[] a, final int offa) {
+ /*
+ if (useLargeArrays) {
+ realForwardFull(new FloatLargeArray(a), offa);
+ } else { */ // <-- no LargeArray support
+ if (true) {
+ final int twon = 2 * n;
+ switch (plan) {
+ case SPLIT_RADIX:
+ realForward(a, offa);
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ Future>[] futures = new Future[nthreads];
+ int k = n / 2 / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx1, idx2;
+ for (int k = firstIdx; k < lastIdx; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a[idx2] = a[offa + idx1];
+ a[idx2 + 1] = -a[offa + idx1 + 1];
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ int idx1, idx2;
+ for (int k = 0; k < n / 2; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a[idx2] = a[offa + idx1];
+ a[idx2 + 1] = -a[offa + idx1 + 1];
+ }
+ }
+ a[offa + n] = -a[offa + 1];
+ a[offa + 1] = 0;
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ int m;
+ if (n % 2 == 0) {
+ m = n / 2;
+ } else {
+ m = (n + 1) / 2;
+ }
+ for (int k = 1; k < m; k++) {
+ int idx1 = offa + twon - 2 * k;
+ int idx2 = offa + 2 * k;
+ a[idx1 + 1] = -a[idx2];
+ a[idx1] = a[idx2 - 1];
+ }
+ for (int k = 1; k < n; k++) {
+ int idx = offa + n - k;
+ float tmp = a[idx + 1];
+ a[idx + 1] = a[idx];
+ a[idx] = tmp;
+ }
+ a[offa + 1] = 0;
+ break;
+ case BLUESTEIN:
+ bluestein_real_full(a, offa, -1);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Computes 1D forward DFT of real data leaving the result in a
+ * . This method computes the full real forward transform, i.e. you will get
+ * the same result as from complexForward called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data. To get back the original data,
+ * use complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ *
+ public void realForwardFull(final FloatLargeArray a, final long offa) {
+
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ realForwardFull(a.getData(), (int) offa);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ final long twon = 2 * nl;
+ switch (plan) {
+ case SPLIT_RADIX:
+ realForward(a, offa);
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ Future>[] futures = new Future[nthreads];
+ long k = nl / 2 / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ long idx1, idx2;
+ for (long k = firstIdx; k < lastIdx; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a.setFloat(idx2, a.getFloat(offa + idx1));
+ a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ long idx1, idx2;
+ for (long k = 0; k < nl / 2; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a.setFloat(idx2, a.getFloat(offa + idx1));
+ a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
+ }
+ }
+ a.setFloat(offa + nl, -a.getFloat(offa + 1));
+ a.setFloat(offa + 1, 0);
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ long m;
+ if (nl % 2 == 0) {
+ m = nl / 2;
+ } else {
+ m = (nl + 1) / 2;
+ }
+ for (long k = 1; k < m; k++) {
+ long idx1 = offa + twon - 2 * k;
+ long idx2 = offa + 2 * k;
+ a.setFloat(idx1 + 1, -a.getFloat(idx2));
+ a.setFloat(idx1, a.getFloat(idx2 - 1));
+ }
+ for (long k = 1; k < nl; k++) {
+ long idx = offa + nl - k;
+ float tmp = a.getFloat(idx + 1);
+ a.setFloat(idx + 1, a.getFloat(idx));
+ a.setFloat(idx, tmp);
+ }
+ a.setFloat(offa + 1, 0);
+ break;
+ case BLUESTEIN:
+ bluestein_real_full(a, offa, -1);
+ break;
+ }
+ }
+ } */
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . The physical layout of the input data has to be as follows:+ * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = + * Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 + * a[1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ *
+ */
+ public void realInverse(float[] a, boolean scale) {
+ realInverse(a, 0, scale);
+ }
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . The physical layout of the input data has to be as follows:+ * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = + * Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 + * a[1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ *
+ *
+ public void realInverse(FloatLargeArray a, boolean scale) {
+ realInverse(a, 0, scale);
+ } */
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . The physical layout of the input data has to be as follows:+ * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 + * a[offa+1] = Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], + * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ * @param scale if true then scaling is performed
+ *
+ */
+ public void realInverse(float[] a, int offa, boolean scale) {
+ /*
+ if (useLargeArrays) {
+ realInverse(new FloatLargeArray(a), offa, scale);
+ } else { */ // <-- no LargeArray support
+ if (true) {
+ if (n == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ a[offa + 1] = 0.5f * (a[offa] - a[offa + 1]);
+ a[offa] -= a[offa + 1];
+ if (n > 4) {
+ CommonUtils.rftfsub(n, a, offa, nc, w, nw);
+ CommonUtils.cftbsub(n, a, offa, ip, nw, w);
+ } else if (n == 4) {
+ CommonUtils.cftxc020(a, offa);
+ }
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / (n / 2.0f), a, offa, false);
+ }
+ break;
+ case MIXED_RADIX:
+ for (int k = 2; k < n; k++) {
+ int idx = offa + k;
+ float tmp = a[idx - 1];
+ a[idx - 1] = a[idx];
+ a[idx] = tmp;
+ }
+ rfftb(a, offa);
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_inverse(a, offa);
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ break;
+ }
+ }
+
+ }
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . The physical layout of the input data has to be as follows:+ * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 + * a[offa+1] = Re[n/2] + *+ * + * if n is odd then + * + * *
+ * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], + * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ * @param scale if true then scaling is performed
+ *
+ *
+ public void realInverse(FloatLargeArray a, long offa, boolean scale) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ realInverse(a.getData(), (int) offa, scale);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ if (nl == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ a.setFloat(offa + 1, 0.5f * (a.getFloat(offa) - a.getFloat(offa + 1)));
+ a.setFloat(offa, a.getFloat(offa) - a.getFloat(offa + 1));
+ if (nl > 4) {
+ CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
+ CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
+ } else if (nl == 4) {
+ CommonUtils.cftxc020(a, offa);
+ }
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / (nl / 2.0f), a, offa, false);
+ }
+ break;
+ case MIXED_RADIX:
+ for (long k = 2; k < nl; k++) {
+ long idx = offa + k;
+ float tmp = a.getFloat(idx - 1);
+ a.setFloat(idx - 1, a.getFloat(idx));
+ a.setFloat(idx, tmp);
+ }
+ rfftb(a, offa);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_inverse(a, offa);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ break;
+ }
+ }
+
+ } */
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . This method computes the full real inverse transform, i.e. you will get
+ * the same result as from complexInverse called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data.
+ *
+ * @param a data to transform
+ * @param scale if true then scaling is performed
+ */
+ public void realInverseFull(float[] a, boolean scale) {
+ realInverseFull(a, 0, scale);
+ }
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . This method computes the full real inverse transform, i.e. you will get
+ * the same result as from complexInverse called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data.
+ *
+ * @param a data to transform
+ * @param scale if true then scaling is performed
+ *
+ public void realInverseFull(FloatLargeArray a, boolean scale) {
+ realInverseFull(a, 0, scale);
+ } */
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . This method computes the full real inverse transform, i.e. you will get
+ * the same result as from complexInverse called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ * @param scale if true then scaling is performed
+ */
+ public void realInverseFull(final float[] a, final int offa, boolean scale) {
+ /*
+ if (useLargeArrays) {
+ realInverseFull(new FloatLargeArray(a), offa, scale);
+ } else { */ // <-- no LargeArray support
+ if (true) {
+ final int twon = 2 * n;
+ switch (plan) {
+ case SPLIT_RADIX:
+ realInverse2(a, offa, scale);
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ Future>[] futures = new Future[nthreads];
+ int k = n / 2 / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx1, idx2;
+ for (int k = firstIdx; k < lastIdx; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a[idx2] = a[offa + idx1];
+ a[idx2 + 1] = -a[offa + idx1 + 1];
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ int idx1, idx2;
+ for (int k = 0; k < n / 2; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a[idx2] = a[offa + idx1];
+ a[idx2 + 1] = -a[offa + idx1 + 1];
+ }
+ }
+ a[offa + n] = -a[offa + 1];
+ a[offa + 1] = 0;
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ int m;
+ if (n % 2 == 0) {
+ m = n / 2;
+ } else {
+ m = (n + 1) / 2;
+ }
+ for (int k = 1; k < m; k++) {
+ int idx1 = offa + 2 * k;
+ int idx2 = offa + twon - 2 * k;
+ a[idx1] = -a[idx1];
+ a[idx2 + 1] = -a[idx1];
+ a[idx2] = a[idx1 - 1];
+ }
+ for (int k = 1; k < n; k++) {
+ int idx = offa + n - k;
+ float tmp = a[idx + 1];
+ a[idx + 1] = a[idx];
+ a[idx] = tmp;
+ }
+ a[offa + 1] = 0;
+ break;
+ case BLUESTEIN:
+ bluestein_real_full(a, offa, 1);
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, true);
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Computes 1D inverse DFT of real data leaving the result in a
+ * . This method computes the full real inverse transform, i.e. you will get
+ * the same result as from complexInverse called with all
+ * imaginary part equal 0. Because the result is stored in a,
+ * the size of the input array must greater or equal 2*n, with only the
+ * first n elements filled with real data.
+ *
+ * @param a data to transform
+ * @param offa index of the first element in array a
+ * @param scale if true then scaling is performed
+ *
+ public void realInverseFull(final FloatLargeArray a, final long offa, boolean scale) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ realInverseFull(a.getData(), (int) offa, scale);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ final long twon = 2 * nl;
+ switch (plan) {
+ case SPLIT_RADIX:
+ realInverse2(a, offa, scale);
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ Future>[] futures = new Future[nthreads];
+ long k = nl / 2 / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ long idx1, idx2;
+ for (long k = firstIdx; k < lastIdx; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a.setFloat(idx2, a.getFloat(offa + idx1));
+ a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ long idx1, idx2;
+ for (long k = 0; k < nl / 2; k++) {
+ idx1 = 2 * k;
+ idx2 = offa + ((twon - idx1) % twon);
+ a.setFloat(idx2, a.getFloat(offa + idx1));
+ a.setFloat(idx2 + 1, -a.getFloat(offa + idx1 + 1));
+ }
+ }
+ a.setFloat(offa + nl, -a.getFloat(offa + 1));
+ a.setFloat(offa + 1, 0);
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ long m;
+ if (nl % 2 == 0) {
+ m = nl / 2;
+ } else {
+ m = (nl + 1) / 2;
+ }
+ for (long k = 1; k < m; k++) {
+ long idx1 = offa + 2 * k;
+ long idx2 = offa + twon - 2 * k;
+ a.setFloat(idx1, -a.getFloat(idx1));
+ a.setFloat(idx2 + 1, -a.getFloat(idx1));
+ a.setFloat(idx2, a.getFloat(idx1 - 1));
+ }
+ for (long k = 1; k < nl; k++) {
+ long idx = offa + nl - k;
+ float tmp = a.getFloat(idx + 1);
+ a.setFloat(idx + 1, a.getFloat(idx));
+ a.setFloat(idx, tmp);
+ }
+ a.setFloat(offa + 1, 0);
+ break;
+ case BLUESTEIN:
+ bluestein_real_full(a, offa, 1);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, true);
+ }
+ break;
+ }
+ }
+ } */
+
+ protected void realInverse2(float[] a, int offa, boolean scale) {
+ /*
+ if (useLargeArrays) {
+ realInverse2(new FloatLargeArray(a), offa, scale);
+ } else { */ // <-- no LargeArray support
+ if (true) {
+ if (n == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ float xi;
+
+ if (n > 4) {
+ CommonUtils.cftfsub(n, a, offa, ip, nw, w);
+ CommonUtils.rftbsub(n, a, offa, nc, w, nw);
+ } else if (n == 4) {
+ CommonUtils.cftbsub(n, a, offa, ip, nw, w);
+ }
+ xi = a[offa] - a[offa + 1];
+ a[offa] += a[offa + 1];
+ a[offa + 1] = xi;
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ for (int k = n - 1; k >= 2; k--) {
+ int idx = offa + k;
+ float tmp = a[idx];
+ a[idx] = a[idx - 1];
+ a[idx - 1] = tmp;
+ }
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ int m;
+ if (n % 2 == 0) {
+ m = n / 2;
+ for (int i = 1; i < m; i++) {
+ int idx = offa + 2 * i + 1;
+ a[idx] = -a[idx];
+ }
+ } else {
+ m = (n - 1) / 2;
+ for (int i = 0; i < m; i++) {
+ int idx = offa + 2 * i + 1;
+ a[idx] = -a[idx];
+ }
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_inverse2(a, offa);
+ if (scale) {
+ CommonUtils.scale(n, 1.0f / n, a, offa, false);
+ }
+ break;
+ }
+ }
+ }
+/*
+ protected void realInverse2(FloatLargeArray a, long offa, boolean scale) {
+ if (!useLargeArrays) {
+ if (a.getData() != null && offa < Integer.MAX_VALUE) {
+ realInverse2(a.getData(), (int) offa, scale);
+ } else {
+ throw new IllegalArgumentException("The data array is too big.");
+ }
+ } else {
+ if (nl == 1) {
+ return;
+ }
+ switch (plan) {
+ case SPLIT_RADIX:
+ float xi;
+
+ if (nl > 4) {
+ CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
+ CommonUtils.rftbsub(nl, a, offa, ncl, wl, nwl);
+ } else if (nl == 4) {
+ CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
+ }
+ xi = a.getFloat(offa) - a.getFloat(offa + 1);
+ a.setFloat(offa, a.getFloat(offa) + a.getFloat(offa + 1));
+ a.setFloat(offa + 1, xi);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ break;
+ case MIXED_RADIX:
+ rfftf(a, offa);
+ for (long k = nl - 1; k >= 2; k--) {
+ long idx = offa + k;
+ float tmp = a.getFloat(idx);
+ a.setFloat(idx, a.getFloat(idx - 1));
+ a.setFloat(idx - 1, tmp);
+ }
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ long m;
+ if (nl % 2 == 0) {
+ m = nl / 2;
+ for (long i = 1; i < m; i++) {
+ long idx = offa + 2 * i + 1;
+ a.setFloat(idx, -a.getFloat(idx));
+ }
+ } else {
+ m = (nl - 1) / 2;
+ for (long i = 0; i < m; i++) {
+ long idx = offa + 2 * i + 1;
+ a.setFloat(idx, -a.getFloat(idx));
+ }
+ }
+ break;
+ case BLUESTEIN:
+ bluestein_real_inverse2(a, offa);
+ if (scale) {
+ CommonUtils.scale(nl, 1.0f / nl, a, offa, false);
+ }
+ break;
+ }
+ }
+ }
+*/
+
+ /* -------- initializing routines -------- */
+
+ /*---------------------------------------------------------
+ cffti: initialization of Complex FFT
+ --------------------------------------------------------*/
+ void cffti(int n, int offw) {
+ if (n == 1) {
+ return;
+ }
+
+ final int twon = 2 * n;
+ final int fourn = 4 * n;
+ float argh;
+ int idot, ntry = 0, i, j;
+ float argld;
+ int i1, k1, l1, l2, ib;
+ float fi;
+ int ld, ii, nf, ipll, nll, nq, nr;
+ float arg;
+ int ido, ipm;
+
+ nll = n;
+ nf = 0;
+ j = 0;
+
+ factorize_loop:
+ while (true) {
+ j++;
+ if (j <= 4) {
+ ntry = factors[j - 1];
+ } else {
+ ntry += 2;
+ }
+ do {
+ nq = nll / ntry;
+ nr = nll - ntry * nq;
+ if (nr != 0) {
+ continue factorize_loop;
+ }
+ nf++;
+ wtable[offw + nf + 1 + fourn] = ntry;
+ nll = nq;
+ if (ntry == 2 && nf != 1) {
+ for (i = 2; i <= nf; i++) {
+ ib = nf - i + 2;
+ int idx = ib + fourn;
+ wtable[offw + idx + 1] = wtable[offw + idx];
+ }
+ wtable[offw + 2 + fourn] = 2;
+ }
+ } while (nll != 1);
+ break;
+ }
+ wtable[offw + fourn] = n;
+ wtable[offw + 1 + fourn] = nf;
+ argh = TWO_PI / (float) n;
+ i = 1;
+ l1 = 1;
+ for (k1 = 1; k1 <= nf; k1++) {
+ ipll = (int) wtable[offw + k1 + 1 + fourn];
+ ld = 0;
+ l2 = l1 * ipll;
+ ido = n / l2;
+ idot = ido + ido + 2;
+ ipm = ipll - 1;
+ for (j = 1; j <= ipm; j++) {
+ i1 = i;
+ wtable[offw + i - 1 + twon] = 1;
+ wtable[offw + i + twon] = 0;
+ ld += l1;
+ fi = 0;
+ argld = ld * argh;
+ for (ii = 4; ii <= idot; ii += 2) {
+ i += 2;
+ fi += 1;
+ arg = fi * argld;
+ int idx = i + twon;
+ wtable[offw + idx - 1] = (float)Math.cos(arg);
+ wtable[offw + idx] = (float)Math.sin(arg);
+ }
+ if (ipll > 5) {
+ int idx1 = i1 + twon;
+ int idx2 = i + twon;
+ wtable[offw + idx1 - 1] = wtable[offw + idx2 - 1];
+ wtable[offw + idx1] = wtable[offw + idx2];
+ }
+ }
+ l1 = l2;
+ }
+
+ }
+
+ final void cffti() {
+ if (n == 1) {
+ return;
+ }
+
+ final int twon = 2 * n;
+ final int fourn = 4 * n;
+ float argh;
+ int idot, ntry = 0, i, j;
+ float argld;
+ int i1, k1, l1, l2, ib;
+ float fi;
+ int ld, ii, nf, ipll, nll, nq, nr;
+ float arg;
+ int ido, ipm;
+
+ nll = n;
+ nf = 0;
+ j = 0;
+
+ factorize_loop:
+ while (true) {
+ j++;
+ if (j <= 4) {
+ ntry = factors[j - 1];
+ } else {
+ ntry += 2;
+ }
+ do {
+ nq = nll / ntry;
+ nr = nll - ntry * nq;
+ if (nr != 0) {
+ continue factorize_loop;
+ }
+ nf++;
+ wtable[nf + 1 + fourn] = ntry;
+ nll = nq;
+ if (ntry == 2 && nf != 1) {
+ for (i = 2; i <= nf; i++) {
+ ib = nf - i + 2;
+ int idx = ib + fourn;
+ wtable[idx + 1] = wtable[idx];
+ }
+ wtable[2 + fourn] = 2;
+ }
+ } while (nll != 1);
+ break;
+ }
+ wtable[fourn] = n;
+ wtable[1 + fourn] = nf;
+ argh = TWO_PI / (float) n;
+ i = 1;
+ l1 = 1;
+ for (k1 = 1; k1 <= nf; k1++) {
+ ipll = (int) wtable[k1 + 1 + fourn];
+ ld = 0;
+ l2 = l1 * ipll;
+ ido = n / l2;
+ idot = ido + ido + 2;
+ ipm = ipll - 1;
+ for (j = 1; j <= ipm; j++) {
+ i1 = i;
+ wtable[i - 1 + twon] = 1;
+ wtable[i + twon] = 0;
+ ld += l1;
+ fi = 0;
+ argld = ld * argh;
+ for (ii = 4; ii <= idot; ii += 2) {
+ i += 2;
+ fi += 1;
+ arg = fi * argld;
+ int idx = i + twon;
+ wtable[idx - 1] = (float)Math.cos(arg);
+ wtable[idx] = (float)Math.sin(arg);
+ }
+ if (ipll > 5) {
+ int idx1 = i1 + twon;
+ int idx2 = i + twon;
+ wtable[idx1 - 1] = wtable[idx2 - 1];
+ wtable[idx1] = wtable[idx2];
+ }
+ }
+ l1 = l2;
+ }
+
+ }
+/*
+ final void cfftil() {
+ if (nl == 1) {
+ return;
+ }
+
+ final long twon = 2 * nl;
+ final long fourn = 4 * nl;
+ float argh;
+ long idot, ntry = 0, i, j;
+ float argld;
+ long i1, k1, l1, l2, ib;
+ float fi;
+ long ld, ii, nf, ipll, nl2, nq, nr;
+ float arg;
+ long ido, ipm;
+
+ nl2 = nl;
+ nf = 0;
+ j = 0;
+
+ factorize_loop:
+ while (true) {
+ j++;
+ if (j <= 4) {
+ ntry = factors[(int) (j - 1)];
+ } else {
+ ntry += 2;
+ }
+ do {
+ nq = nl2 / ntry;
+ nr = nl2 - ntry * nq;
+ if (nr != 0) {
+ continue factorize_loop;
+ }
+ nf++;
+ wtablel.setFloat(nf + 1 + fourn, ntry);
+ nl2 = nq;
+ if (ntry == 2 && nf != 1) {
+ for (i = 2; i <= nf; i++) {
+ ib = nf - i + 2;
+ long idx = ib + fourn;
+ wtablel.setFloat(idx + 1, wtablel.getFloat(idx));
+ }
+ wtablel.setFloat(2 + fourn, 2);
+ }
+ } while (nl2 != 1);
+ break;
+ }
+ wtablel.setFloat(fourn, nl);
+ wtablel.setFloat(1 + fourn, nf);
+ argh = TWO_PI / (float) nl;
+ i = 1;
+ l1 = 1;
+ for (k1 = 1; k1 <= nf; k1++) {
+ ipll = (long) wtablel.getFloat(k1 + 1 + fourn);
+ ld = 0;
+ l2 = l1 * ipll;
+ ido = nl / l2;
+ idot = ido + ido + 2;
+ ipm = ipll - 1;
+ for (j = 1; j <= ipm; j++) {
+ i1 = i;
+ wtablel.setFloat(i - 1 + twon, 1);
+ wtablel.setFloat(i + twon, 0);
+ ld += l1;
+ fi = 0;
+ argld = ld * argh;
+ for (ii = 4; ii <= idot; ii += 2) {
+ i += 2;
+ fi += 1;
+ arg = fi * argld;
+ long idx = i + twon;
+ wtablel.setFloat(idx - 1, (float)Math.cos(arg));
+ wtablel.setFloat(idx, (float)Math.sin(arg));
+ }
+ if (ipll > 5) {
+ long idx1 = i1 + twon;
+ long idx2 = i + twon;
+ wtablel.setFloat(idx1 - 1, wtablel.getFloat(idx2 - 1));
+ wtablel.setFloat(idx1, wtablel.getFloat(idx2));
+ }
+ }
+ l1 = l2;
+ }
+
+ }
+*/
+ void rffti() {
+
+ if (n == 1) {
+ return;
+ }
+ final int twon = 2 * n;
+ float argh;
+ int ntry = 0, i, j;
+ float argld;
+ int k1, l1, l2, ib;
+ float fi;
+ int ld, ii, nf, ipll, nll, is, nq, nr;
+ float arg;
+ int ido, ipm;
+ int nfm1;
+
+ nll = n;
+ nf = 0;
+ j = 0;
+
+ factorize_loop:
+ while (true) {
+ ++j;
+ if (j <= 4) {
+ ntry = factors[j - 1];
+ } else {
+ ntry += 2;
+ }
+ do {
+ nq = nll / ntry;
+ nr = nll - ntry * nq;
+ if (nr != 0) {
+ continue factorize_loop;
+ }
+ ++nf;
+ wtable_r[nf + 1 + twon] = ntry;
+
+ nll = nq;
+ if (ntry == 2 && nf != 1) {
+ for (i = 2; i <= nf; i++) {
+ ib = nf - i + 2;
+ int idx = ib + twon;
+ wtable_r[idx + 1] = wtable_r[idx];
+ }
+ wtable_r[2 + twon] = 2;
+ }
+ } while (nll != 1);
+ break;
+ }
+ wtable_r[twon] = n;
+ wtable_r[1 + twon] = nf;
+ argh = TWO_PI / (float) (n);
+ is = 0;
+ nfm1 = nf - 1;
+ l1 = 1;
+ if (nfm1 == 0) {
+ return;
+ }
+ for (k1 = 1; k1 <= nfm1; k1++) {
+ ipll = (int) wtable_r[k1 + 1 + twon];
+ ld = 0;
+ l2 = l1 * ipll;
+ ido = n / l2;
+ ipm = ipll - 1;
+ for (j = 1; j <= ipm; ++j) {
+ ld += l1;
+ i = is;
+ argld = (float) ld * argh;
+
+ fi = 0;
+ for (ii = 3; ii <= ido; ii += 2) {
+ i += 2;
+ fi += 1;
+ arg = fi * argld;
+ int idx = i + n;
+ wtable_r[idx - 2] = (float)Math.cos(arg);
+ wtable_r[idx - 1] = (float)Math.sin(arg);
+ }
+ is += ido;
+ }
+ l1 = l2;
+ }
+ }
+/*
+ void rfftil() {
+
+ if (nl == 1) {
+ return;
+ }
+ final long twon = 2 * nl;
+ float argh;
+ long ntry = 0, i, j;
+ float argld;
+ long k1, l1, l2, ib;
+ float fi;
+ long ld, ii, nf, ipll, nl2, is, nq, nr;
+ float arg;
+ long ido, ipm;
+ long nfm1;
+
+ nl2 = nl;
+ nf = 0;
+ j = 0;
+
+ factorize_loop:
+ while (true) {
+ ++j;
+ if (j <= 4) {
+ ntry = factors[(int) (j - 1)];
+ } else {
+ ntry += 2;
+ }
+ do {
+ nq = nl2 / ntry;
+ nr = nl2 - ntry * nq;
+ if (nr != 0) {
+ continue factorize_loop;
+ }
+ ++nf;
+ wtable_rl.setFloat(nf + 1 + twon, ntry);
+
+ nl2 = nq;
+ if (ntry == 2 && nf != 1) {
+ for (i = 2; i <= nf; i++) {
+ ib = nf - i + 2;
+ long idx = ib + twon;
+ wtable_rl.setFloat(idx + 1, wtable_rl.getFloat(idx));
+ }
+ wtable_rl.setFloat(2 + twon, 2);
+ }
+ } while (nl2 != 1);
+ break;
+ }
+ wtable_rl.setFloat(twon, nl);
+ wtable_rl.setFloat(1 + twon, nf);
+ argh = TWO_PI / (float) (nl);
+ is = 0;
+ nfm1 = nf - 1;
+ l1 = 1;
+ if (nfm1 == 0) {
+ return;
+ }
+ for (k1 = 1; k1 <= nfm1; k1++) {
+ ipll = (long) wtable_rl.getFloat(k1 + 1 + twon);
+ ld = 0;
+ l2 = l1 * ipll;
+ ido = nl / l2;
+ ipm = ipll - 1;
+ for (j = 1; j <= ipm; ++j) {
+ ld += l1;
+ i = is;
+ argld = (float) ld * argh;
+
+ fi = 0;
+ for (ii = 3; ii <= ido; ii += 2) {
+ i += 2;
+ fi += 1;
+ arg = fi * argld;
+ long idx = i + nl;
+ wtable_rl.setFloat(idx - 2, (float)Math.cos(arg));
+ wtable_rl.setFloat(idx - 1, (float)Math.sin(arg));
+ }
+ is += ido;
+ }
+ l1 = l2;
+ }
+ }
+*/
+ private void bluesteini() {
+ int k = 0;
+ float arg;
+ float pi_n = PI / n;
+ bk1[0] = 1;
+ bk1[1] = 0;
+ for (int i = 1; i < n; i++) {
+ k += 2 * i - 1;
+ if (k >= 2 * n) {
+ k -= 2 * n;
+ }
+ arg = pi_n * k;
+ bk1[2 * i] = (float)Math.cos(arg);
+ bk1[2 * i + 1] = (float)Math.sin(arg);
+ }
+ float scale = 1.0f / nBluestein;
+ bk2[0] = bk1[0] * scale;
+ bk2[1] = bk1[1] * scale;
+ for (int i = 2; i < 2 * n; i += 2) {
+ bk2[i] = bk1[i] * scale;
+ bk2[i + 1] = bk1[i + 1] * scale;
+ bk2[2 * nBluestein - i] = bk2[i];
+ bk2[2 * nBluestein - i + 1] = bk2[i + 1];
+ }
+ CommonUtils.cftbsub(2 * nBluestein, bk2, 0, ip, nw, w);
+ }
+/*
+ private void bluesteinil() {
+ long k = 0;
+ float arg;
+ float pi_n = PI / nl;
+ bk1l.setFloat(0, 1);
+ bk1l.setFloat(1, 0);
+ for (int i = 1; i < nl; i++) {
+ k += 2 * i - 1;
+ if (k >= 2 * nl) {
+ k -= 2 * nl;
+ }
+ arg = pi_n * k;
+ bk1l.setFloat(2 * i, (float)Math.cos(arg));
+ bk1l.setFloat(2 * i + 1, (float)Math.sin(arg));
+ }
+ float scale = 1.0f / nBluesteinl;
+ bk2l.setFloat(0, bk1l.getFloat(0) * scale);
+ bk2l.setFloat(1, bk1l.getFloat(1) * scale);
+ for (int i = 2; i < 2 * nl; i += 2) {
+ bk2l.setFloat(i, bk1l.getFloat(i) * scale);
+ bk2l.setFloat(i + 1, bk1l.getFloat(i + 1) * scale);
+ bk2l.setFloat(2 * nBluesteinl - i, bk2l.getFloat(i));
+ bk2l.setFloat(2 * nBluesteinl - i + 1, bk2l.getFloat(i + 1));
+ }
+ CommonUtils.cftbsub(2 * nBluesteinl, bk2l, 0, ipl, nwl, wl);
+ }
+*/
+ private void bluestein_complex(final float[] a, final int offa, final int isign) {
+ final float[] ak = new float[2 * nBluestein];
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ int k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
+ ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = nBluestein / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ if (isign > 0) {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+ } else {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
+ ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ if (isign > 0) {
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ } else {
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+ if (isign > 0) {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ }
+ }
+ }
+/*
+ private void bluestein_complex(final FloatLargeArray a, final long offa, final int isign) {
+ final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ long k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nBluesteinl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(idx4, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(idx4, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ if (isign > 0) {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+ } else {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ if (isign > 0) {
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ } else {
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+ if (isign > 0) {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(idx4, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ a.setFloat(idx3, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(idx4, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ }
+ }
+ }
+*/
+ private void bluestein_real_full(final float[] a, final int offa, final int isign) {
+ final float[] ak = new float[2 * nBluestein];
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ int k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = a[idx3] * bk1[idx2];
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = -a[idx3] * bk1[idx2];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = nBluestein / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ if (isign > 0) {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = a[idx3] * bk1[idx2];
+ }
+ } else {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = -a[idx3] * bk1[idx2];
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ if (isign > 0) {
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ } else {
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ if (isign > 0) {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ }
+ }
+ }
+/*
+ private void bluestein_real_full(final FloatLargeArray a, final long offa, final long isign) {
+ final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ long k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nBluesteinl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (isign > 0) {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ if (isign > 0) {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ } else {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ if (isign > 0) {
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ } else {
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ if (isign > 0) {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ }
+ }
+ }
+*/
+ private void bluestein_real_forward(final float[] a, final int offa) {
+ final float[] ak = new float[2 * nBluestein];
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ int k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = -a[idx3] * bk1[idx2];
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = nBluestein / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = -a[idx3] * bk1[idx2];
+ }
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ if (n % 2 == 0) {
+ a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
+ a[offa + 1] = bk1[n] * ak[n] + bk1[n + 1] * ak[n + 1];
+ for (int i = 1; i < n / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
+ a[offa + 1] = -bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
+ for (int i = 1; i < (n - 1) / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
+ a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ a[offa + n - 1] = bk1[n - 1] * ak[n - 1] + bk1[n] * ak[n];
+ }
+
+ }
+/*
+ private void bluestein_real_forward(final FloatLargeArray a, final long offa) {
+ final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ long k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nBluesteinl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, -a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) - ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ if (nl % 2 == 0) {
+ a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) + bk1l.getFloat(1) * ak.getFloat(1));
+ a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl) + bk1l.getFloat(nl + 1) * ak.getFloat(nl + 1));
+ for (long i = 1; i < nl / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) + bk1l.getFloat(1) * ak.getFloat(1));
+ a.setFloat(offa + 1, -bk1l.getFloat(nl) * ak.getFloat(nl - 1) + bk1l.getFloat(nl - 1) * ak.getFloat(nl));
+ for (long i = 1; i < (nl - 1) / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) + bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, -bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ a.setFloat(offa + nl - 1, bk1l.getFloat(nl - 1) * ak.getFloat(nl - 1) + bk1l.getFloat(nl) * ak.getFloat(nl));
+ }
+
+ }
+*/
+ private void bluestein_real_inverse(final float[] a, final int offa) {
+ final float[] ak = new float[2 * nBluestein];
+ if (n % 2 == 0) {
+ ak[0] = a[offa] * bk1[0];
+ ak[1] = a[offa] * bk1[1];
+
+ for (int i = 1; i < n / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+
+ ak[n] = a[offa + 1] * bk1[n];
+ ak[n + 1] = a[offa + 1] * bk1[n + 1];
+
+ for (int i = n / 2 + 1; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + 2 * n - idx1;
+ int idx4 = idx3 + 1;
+ ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
+ }
+
+ } else {
+ ak[0] = a[offa] * bk1[0];
+ ak[1] = a[offa] * bk1[1];
+
+ for (int i = 1; i < (n - 1) / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + idx1;
+ int idx4 = offa + idx2;
+ ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
+ }
+
+ ak[n - 1] = a[offa + n - 1] * bk1[n - 1] - a[offa + 1] * bk1[n];
+ ak[n] = a[offa + n - 1] * bk1[n] + a[offa + 1] * bk1[n - 1];
+
+ ak[n + 1] = a[offa + n - 1] * bk1[n + 1] + a[offa + 1] * bk1[n + 2];
+ ak[n + 2] = a[offa + n - 1] * bk1[n + 2] - a[offa + 1] * bk1[n + 1];
+
+ for (int i = (n - 1) / 2 + 2; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + 2 * n - idx1;
+ int idx4 = idx3 + 1;
+ ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
+ ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ int k = nBluestein / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ }
+ }
+ }
+/*
+ private void bluestein_real_inverse(final FloatLargeArray a, final long offa) {
+ final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
+ if (nl % 2 == 0) {
+ ak.setFloat(0, a.getFloat(offa) * bk1l.getFloat(0));
+ ak.setFloat(1, a.getFloat(offa) * bk1l.getFloat(1));
+
+ for (long i = 1; i < nl / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+
+ ak.setFloat(nl, a.getFloat(offa + 1) * bk1l.getFloat(nl));
+ ak.setFloat(nl + 1, a.getFloat(offa + 1) * bk1l.getFloat(nl + 1));
+
+ for (long i = nl / 2 + 1; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + 2 * nl - idx1;
+ long idx4 = idx3 + 1;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) - a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+
+ } else {
+ ak.setFloat(0, a.getFloat(offa) * bk1l.getFloat(0));
+ ak.setFloat(1, a.getFloat(offa) * bk1l.getFloat(1));
+
+ for (long i = 1; i < (nl - 1) / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + idx1;
+ long idx4 = offa + idx2;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) - a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) + a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+
+ ak.setFloat(nl - 1, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl - 1) - a.getFloat(offa + 1) * bk1l.getFloat(nl));
+ ak.setFloat(nl, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl) + a.getFloat(offa + 1) * bk1l.getFloat(nl - 1));
+
+ ak.setFloat(nl + 1, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl + 1) + a.getFloat(offa + 1) * bk1l.getFloat(nl + 2));
+ ak.setFloat(nl + 2, a.getFloat(offa + nl - 1) * bk1l.getFloat(nl + 2) - a.getFloat(offa + 1) * bk1l.getFloat(nl + 1));
+
+ for (long i = (nl - 1) / 2 + 2; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + 2 * nl - idx1;
+ long idx4 = idx3 + 1;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1) + a.getFloat(idx4) * bk1l.getFloat(idx2));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2) - a.getFloat(idx4) * bk1l.getFloat(idx1));
+ }
+ }
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ long k = nBluesteinl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + i, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + i, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ }
+ }
+ }
+*/
+ private void bluestein_real_inverse2(final float[] a, final int offa) {
+ final float[] ak = new float[2 * nBluestein];
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ int k = n / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = a[idx3] * bk1[idx2];
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ k = nBluestein / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int firstIdx = i * k;
+ final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstIdx; i < lastIdx; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (int i = 0; i < n; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ int idx3 = offa + i;
+ ak[idx1] = a[idx3] * bk1[idx1];
+ ak[idx2] = a[idx3] * bk1[idx2];
+ }
+
+ CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ for (int i = 0; i < nBluestein; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ float im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
+ ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
+ ak[idx2] = im;
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
+
+ if (n % 2 == 0) {
+ a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
+ a[offa + 1] = bk1[n] * ak[n] - bk1[n + 1] * ak[n + 1];
+ for (int i = 1; i < n / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ } else {
+ a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
+ a[offa + 1] = bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
+ for (int i = 1; i < (n - 1) / 2; i++) {
+ int idx1 = 2 * i;
+ int idx2 = idx1 + 1;
+ a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
+ a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
+ }
+ a[offa + n - 1] = bk1[n - 1] * ak[n - 1] - bk1[n] * ak[n];
+ }
+ }
+/*
+ private void bluestein_real_inverse2(final FloatLargeArray a, final long offa) {
+ final FloatLargeArray ak = new FloatLargeArray(2 * nBluesteinl, false);
+ int threads = ConcurrencyUtils.getNumberOfThreads();
+ if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
+ int nthreads = 2;
+ if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
+ nthreads = 4;
+ }
+ Future>[] futures = new Future[nthreads];
+ long k = nl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ k = nBluesteinl / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final long firstIdx = i * k;
+ final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstIdx; i < lastIdx; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (long i = 0; i < nl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ long idx3 = offa + i;
+ ak.setFloat(idx1, a.getFloat(idx3) * bk1l.getFloat(idx1));
+ ak.setFloat(idx2, a.getFloat(idx3) * bk1l.getFloat(idx2));
+ }
+
+ CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ for (long i = 0; i < nBluesteinl; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ float im = -ak.getFloat(idx1) * bk2l.getFloat(idx2) + ak.getFloat(idx2) * bk2l.getFloat(idx1);
+ ak.setFloat(idx1, ak.getFloat(idx1) * bk2l.getFloat(idx1) + ak.getFloat(idx2) * bk2l.getFloat(idx2));
+ ak.setFloat(idx2, im);
+ }
+ }
+
+ CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
+
+ if (nl % 2 == 0) {
+ a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) - bk1l.getFloat(1) * ak.getFloat(1));
+ a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl) - bk1l.getFloat(nl + 1) * ak.getFloat(nl + 1));
+ for (long i = 1; i < nl / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ } else {
+ a.setFloat(offa, bk1l.getFloat(0) * ak.getFloat(0) - bk1l.getFloat(1) * ak.getFloat(1));
+ a.setFloat(offa + 1, bk1l.getFloat(nl) * ak.getFloat(nl - 1) + bk1l.getFloat(nl - 1) * ak.getFloat(nl));
+ for (long i = 1; i < (nl - 1) / 2; i++) {
+ long idx1 = 2 * i;
+ long idx2 = idx1 + 1;
+ a.setFloat(offa + idx1, bk1l.getFloat(idx1) * ak.getFloat(idx1) - bk1l.getFloat(idx2) * ak.getFloat(idx2));
+ a.setFloat(offa + idx2, bk1l.getFloat(idx2) * ak.getFloat(idx1) + bk1l.getFloat(idx1) * ak.getFloat(idx2));
+ }
+ a.setFloat(offa + nl - 1, bk1l.getFloat(nl - 1) * ak.getFloat(nl - 1) - bk1l.getFloat(nl) * ak.getFloat(nl));
+ }
+ }
+*/
+ /*---------------------------------------------------------
+ rfftf1: further processing of Real forward FFT
+ --------------------------------------------------------*/
+ void rfftf(final float a[], final int offa) {
+ if (n == 1) {
+ return;
+ }
+ int l1, l2, na, kh, nf, ipll, iw, ido, idl1;
+
+ final float[] ch = new float[n];
+ final int twon = 2 * n;
+ nf = (int) wtable_r[1 + twon];
+ na = 1;
+ l2 = n;
+ iw = twon - 1;
+ for (int k1 = 1; k1 <= nf; ++k1) {
+ kh = nf - k1;
+ ipll = (int) wtable_r[kh + 2 + twon];
+ l1 = l2 / ipll;
+ ido = n / l2;
+ idl1 = ido * l1;
+ iw -= (ipll - 1) * ido;
+ na = 1 - na;
+ switch (ipll) {
+ case 2:
+ if (na == 0) {
+ radf2(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf2(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 3:
+ if (na == 0) {
+ radf3(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf3(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 4:
+ if (na == 0) {
+ radf4(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf4(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 5:
+ if (na == 0) {
+ radf5(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf5(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ default:
+ if (ido == 1) {
+ na = 1 - na;
+ }
+ if (na == 0) {
+ radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
+ na = 1;
+ } else {
+ radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
+ na = 0;
+ }
+ break;
+ }
+ l2 = l1;
+ }
+ if (na == 1) {
+ return;
+ }
+ System.arraycopy(ch, 0, a, offa, n);
+ }
+
+ /*---------------------------------------------------------
+ rfftf1: further processing of Real forward FFT
+ --------------------------------------------------------*/
+/*
+ void rfftf(final FloatLargeArray a, final long offa) {
+ if (nl == 1) {
+ return;
+ }
+ long l1, l2, na, kh, nf, iw, ido, idl1;
+ int ipll;
+
+ final FloatLargeArray ch = new FloatLargeArray(nl, false);
+ final long twon = 2 * nl;
+ nf = (long) wtable_rl.getFloat(1 + twon);
+ na = 1;
+ l2 = nl;
+ iw = twon - 1;
+ for (long k1 = 1; k1 <= nf; ++k1) {
+ kh = nf - k1;
+ ipll = (int) wtable_rl.getFloat(kh + 2 + twon);
+ l1 = l2 / ipll;
+ ido = nl / l2;
+ idl1 = ido * l1;
+ iw -= (ipll - 1) * ido;
+ na = 1 - na;
+ switch (ipll) {
+ case 2:
+ if (na == 0) {
+ radf2(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf2(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 3:
+ if (na == 0) {
+ radf3(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf3(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 4:
+ if (na == 0) {
+ radf4(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf4(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ case 5:
+ if (na == 0) {
+ radf5(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radf5(ido, l1, ch, 0, a, offa, iw);
+ }
+ break;
+ default:
+ if (ido == 1) {
+ na = 1 - na;
+ }
+ if (na == 0) {
+ radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
+ na = 1;
+ } else {
+ radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
+ na = 0;
+ }
+ break;
+ }
+ l2 = l1;
+ }
+ if (na == 1) {
+ return;
+ }
+ Utilities.arraycopy(ch, 0, a, offa, nl);
+ }
+*/
+ /*---------------------------------------------------------
+ rfftb1: further processing of Real backward FFT
+ --------------------------------------------------------*/
+ void rfftb(final float a[], final int offa) {
+ if (n == 1) {
+ return;
+ }
+ int l1, l2, na, nf, ipll, iw, ido, idl1;
+
+ float[] ch = new float[n];
+ final int twon = 2 * n;
+ nf = (int) wtable_r[1 + twon];
+ na = 0;
+ l1 = 1;
+ iw = n;
+ for (int k1 = 1; k1 <= nf; k1++) {
+ ipll = (int) wtable_r[k1 + 1 + twon];
+ l2 = ipll * l1;
+ ido = n / l2;
+ idl1 = ido * l1;
+ switch (ipll) {
+ case 2:
+ if (na == 0) {
+ radb2(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb2(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 3:
+ if (na == 0) {
+ radb3(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb3(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 4:
+ if (na == 0) {
+ radb4(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb4(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 5:
+ if (na == 0) {
+ radb5(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb5(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ default:
+ if (na == 0) {
+ radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
+ } else {
+ radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
+ }
+ if (ido == 1) {
+ na = 1 - na;
+ }
+ break;
+ }
+ l1 = l2;
+ iw += (ipll - 1) * ido;
+ }
+ if (na == 0) {
+ return;
+ }
+ System.arraycopy(ch, 0, a, offa, n);
+ }
+
+ /*---------------------------------------------------------
+ rfftb1: further processing of Real backward FFT
+ --------------------------------------------------------*/
+/*
+ void rfftb(final FloatLargeArray a, final long offa) {
+ if (nl == 1) {
+ return;
+ }
+ long l1, l2, na, nf, iw, ido, idl1;
+ int ipll;
+ FloatLargeArray ch = new FloatLargeArray(nl, false);
+ final long twon = 2 * nl;
+ nf = (long) wtable_rl.getFloat(1 + twon);
+ na = 0;
+ l1 = 1;
+ iw = nl;
+ for (long k1 = 1; k1 <= nf; k1++) {
+ ipll = (int) wtable_rl.getFloat(k1 + 1 + twon);
+ l2 = ipll * l1;
+ ido = nl / l2;
+ idl1 = ido * l1;
+ switch (ipll) {
+ case 2:
+ if (na == 0) {
+ radb2(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb2(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 3:
+ if (na == 0) {
+ radb3(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb3(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 4:
+ if (na == 0) {
+ radb4(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb4(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ case 5:
+ if (na == 0) {
+ radb5(ido, l1, a, offa, ch, 0, iw);
+ } else {
+ radb5(ido, l1, ch, 0, a, offa, iw);
+ }
+ na = 1 - na;
+ break;
+ default:
+ if (na == 0) {
+ radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
+ } else {
+ radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
+ }
+ if (ido == 1) {
+ na = 1 - na;
+ }
+ break;
+ }
+ l1 = l2;
+ iw += (ipll - 1) * ido;
+ }
+ if (na == 0) {
+ return;
+ }
+ Utilities.arraycopy(ch, 0, a, offa, nl);
+ }
+*/
+ /*-------------------------------------------------
+ radf2: Real FFT's forward processing of factor 2
+ -------------------------------------------------*/
+ void radf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ int i, ic, idx0, idx1, idx2, idx3, idx4;
+ float t1i, t1r, w1r, w1i;
+ int iw1;
+ iw1 = offset;
+ idx0 = l1 * ido;
+ idx1 = 2 * ido;
+ for (int k = 0; k < l1; k++) {
+ int oidx1 = out_off + k * idx1;
+ int oidx2 = oidx1 + idx1 - 1;
+ int iidx1 = in_off + k * ido;
+ int iidx2 = iidx1 + idx0;
+
+ float i1r = in[iidx1];
+ float i2r = in[iidx2];
+
+ out[oidx1] = i1r + i2r;
+ out[oidx2] = i1r - i2r;
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (int k = 0; k < l1; k++) {
+ idx1 = k * ido;
+ idx2 = 2 * idx1;
+ idx3 = idx2 + ido;
+ idx4 = idx1 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int widx1 = i - 1 + iw1;
+ int oidx1 = out_off + i + idx2;
+ int oidx2 = out_off + ic + idx3;
+ int iidx1 = in_off + i + idx1;
+ int iidx2 = in_off + i + idx4;
+
+ float a1i = in[iidx1 - 1];
+ float a1r = in[iidx1];
+ float a2i = in[iidx2 - 1];
+ float a2r = in[iidx2];
+
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+
+ t1r = w1r * a2i + w1i * a2r;
+ t1i = w1r * a2r - w1i * a2i;
+
+ out[oidx1] = a1r + t1i;
+ out[oidx1 - 1] = a1i + t1r;
+
+ out[oidx2] = t1i - a1r;
+ out[oidx2 - 1] = a1i - t1r;
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ idx2 = 2 * idx1;
+ for (int k = 0; k < l1; k++) {
+ idx1 = k * ido;
+ int oidx1 = out_off + idx2 + ido;
+ int iidx1 = in_off + ido - 1 + idx1;
+
+ out[oidx1] = -in[iidx1 + idx0];
+ out[oidx1 - 1] = in[iidx1];
+ }
+ }
+
+ /*-------------------------------------------------
+ radf2: Real FFT's forward processing of factor 2
+ -------------------------------------------------*/
+/*
+ void radf2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ long i, ic, idx0, idx1, idx2, idx3, idx4;
+ float t1i, t1r, w1r, w1i;
+ long iw1;
+ iw1 = offset;
+ idx0 = l1 * ido;
+ idx1 = 2 * ido;
+ for (long k = 0; k < l1; k++) {
+ long oidx1 = out_off + k * idx1;
+ long oidx2 = oidx1 + idx1 - 1;
+ long iidx1 = in_off + k * ido;
+ long iidx2 = iidx1 + idx0;
+
+ float i1r = in.getFloat(iidx1);
+ float i2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1, i1r + i2r);
+ out.setFloat(oidx2, i1r - i2r);
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (long k = 0; k < l1; k++) {
+ idx1 = k * ido;
+ idx2 = 2 * idx1;
+ idx3 = idx2 + ido;
+ idx4 = idx1 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long widx1 = i - 1 + iw1;
+ long oidx1 = out_off + i + idx2;
+ long oidx2 = out_off + ic + idx3;
+ long iidx1 = in_off + i + idx1;
+ long iidx2 = in_off + i + idx4;
+
+ float a1i = in.getFloat(iidx1 - 1);
+ float a1r = in.getFloat(iidx1);
+ float a2i = in.getFloat(iidx2 - 1);
+ float a2r = in.getFloat(iidx2);
+
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+
+ t1r = w1r * a2i + w1i * a2r;
+ t1i = w1r * a2r - w1i * a2i;
+
+ out.setFloat(oidx1, a1r + t1i);
+ out.setFloat(oidx1 - 1, a1i + t1r);
+
+ out.setFloat(oidx2, t1i - a1r);
+ out.setFloat(oidx2 - 1, a1i - t1r);
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ idx2 = 2 * idx1;
+ for (long k = 0; k < l1; k++) {
+ idx1 = k * ido;
+ long oidx1 = out_off + idx2 + ido;
+ long iidx1 = in_off + ido - 1 + idx1;
+
+ out.setFloat(oidx1, -in.getFloat(iidx1 + idx0));
+ out.setFloat(oidx1 - 1, in.getFloat(iidx1));
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radb2: Real FFT's backward processing of factor 2
+ -------------------------------------------------*/
+ void radb2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ int i, ic;
+ float t1i, t1r, w1r, w1i;
+ int iw1 = offset;
+
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 2 * idx1;
+ int idx3 = idx2 + ido;
+ int oidx1 = out_off + idx1;
+ int iidx1 = in_off + idx2;
+ int iidx2 = in_off + ido - 1 + idx3;
+ float i1r = in[iidx1];
+ float i2r = in[iidx2];
+ out[oidx1] = i1r + i2r;
+ out[oidx1 + idx0] = i1r - i2r;
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (int k = 0; k < l1; ++k) {
+ int idx1 = k * ido;
+ int idx2 = 2 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx1 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx5 = i - 1 + iw1;
+ int idx6 = out_off + i;
+ int idx7 = in_off + i;
+ int idx8 = in_off + ic;
+ w1r = wtable_r[idx5 - 1];
+ w1i = wtable_r[idx5];
+ int iidx1 = idx7 + idx2;
+ int iidx2 = idx8 + idx3;
+ int oidx1 = idx6 + idx1;
+ int oidx2 = idx6 + idx4;
+ t1r = in[iidx1 - 1] - in[iidx2 - 1];
+ t1i = in[iidx1] + in[iidx2];
+ float i1i = in[iidx1];
+ float i1r = in[iidx1 - 1];
+ float i2i = in[iidx2];
+ float i2r = in[iidx2 - 1];
+
+ out[oidx1 - 1] = i1r + i2r;
+ out[oidx1] = i1i - i2i;
+ out[oidx2 - 1] = w1r * t1r - w1i * t1i;
+ out[oidx2] = w1r * t1i + w1i * t1r;
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 2 * idx1;
+ int oidx1 = out_off + ido - 1 + idx1;
+ int iidx1 = in_off + idx2 + ido;
+ out[oidx1] = 2 * in[iidx1 - 1];
+ out[oidx1 + idx0] = -2 * in[iidx1];
+ }
+ }
+
+ /*-------------------------------------------------
+ radb2: Real FFT's backward processing of factor 2
+ -------------------------------------------------*/
+/*
+ void radb2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ long i, ic;
+ float t1i, t1r, w1r, w1i;
+ long iw1 = offset;
+
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 2 * idx1;
+ long idx3 = idx2 + ido;
+ long oidx1 = out_off + idx1;
+ long iidx1 = in_off + idx2;
+ long iidx2 = in_off + ido - 1 + idx3;
+ float i1r = in.getFloat(iidx1);
+ float i2r = in.getFloat(iidx2);
+ out.setFloat(oidx1, i1r + i2r);
+ out.setFloat(oidx1 + idx0, i1r - i2r);
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (long k = 0; k < l1; ++k) {
+ long idx1 = k * ido;
+ long idx2 = 2 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx1 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx5 = i - 1 + iw1;
+ long idx6 = out_off + i;
+ long idx7 = in_off + i;
+ long idx8 = in_off + ic;
+ w1r = wtable_rl.getFloat(idx5 - 1);
+ w1i = wtable_rl.getFloat(idx5);
+ long iidx1 = idx7 + idx2;
+ long iidx2 = idx8 + idx3;
+ long oidx1 = idx6 + idx1;
+ long oidx2 = idx6 + idx4;
+ t1r = in.getFloat(iidx1 - 1) - in.getFloat(iidx2 - 1);
+ t1i = in.getFloat(iidx1) + in.getFloat(iidx2);
+ float i1i = in.getFloat(iidx1);
+ float i1r = in.getFloat(iidx1 - 1);
+ float i2i = in.getFloat(iidx2);
+ float i2r = in.getFloat(iidx2 - 1);
+
+ out.setFloat(oidx1 - 1, i1r + i2r);
+ out.setFloat(oidx1, i1i - i2i);
+ out.setFloat(oidx2 - 1, w1r * t1r - w1i * t1i);
+ out.setFloat(oidx2, w1r * t1i + w1i * t1r);
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 2 * idx1;
+ long oidx1 = out_off + ido - 1 + idx1;
+ long iidx1 = in_off + idx2 + ido;
+ out.setFloat(oidx1, 2 * in.getFloat(iidx1 - 1));
+ out.setFloat(oidx1 + idx0, -2 * in.getFloat(iidx1));
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radf3: Real FFT's forward processing of factor 3
+ -------------------------------------------------*/
+ void radf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ int i, ic;
+ float ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
+ int iw1, iw2;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx3 = 2 * idx0;
+ int idx4 = (3 * k + 1) * ido;
+ int iidx1 = in_off + idx1;
+ int iidx2 = iidx1 + idx0;
+ int iidx3 = iidx1 + idx3;
+ float i1r = in[iidx1];
+ float i2r = in[iidx2];
+ float i3r = in[iidx3];
+ cr2 = i2r + i3r;
+ out[out_off + 3 * idx1] = i1r + cr2;
+ out[out_off + idx4 + ido] = taui * (i3r - i2r);
+ out[out_off + ido - 1 + idx4] = i1r + taur * cr2;
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido;
+ int idx4 = 3 * idx3;
+ int idx5 = idx3 + idx0;
+ int idx6 = idx5 + idx0;
+ int idx7 = idx4 + ido;
+ int idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+
+ int idx9 = in_off + i;
+ int idx10 = out_off + i;
+ int idx11 = out_off + ic;
+ int iidx1 = idx9 + idx3;
+ int iidx2 = idx9 + idx5;
+ int iidx3 = idx9 + idx6;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+
+ dr2 = w1r * i2i + w1i * i2r;
+ di2 = w1r * i2r - w1i * i2i;
+ dr3 = w2r * i3i + w2i * i3r;
+ di3 = w2r * i3r - w2i * i3i;
+ cr2 = dr2 + dr3;
+ ci2 = di2 + di3;
+ tr2 = i1i + taur * cr2;
+ ti2 = i1r + taur * ci2;
+ tr3 = taui * (di2 - di3);
+ ti3 = taui * (dr3 - dr2);
+
+ int oidx1 = idx10 + idx4;
+ int oidx2 = idx11 + idx7;
+ int oidx3 = idx10 + idx8;
+
+ out[oidx1 - 1] = i1i + cr2;
+ out[oidx1] = i1r + ci2;
+ out[oidx2 - 1] = tr2 - tr3;
+ out[oidx2] = ti3 - ti2;
+ out[oidx3 - 1] = tr2 + tr3;
+ out[oidx3] = ti2 + ti3;
+ }
+ }
+ }
+
+ /*-------------------------------------------------
+ radf3: Real FFT's forward processing of factor 3
+ -------------------------------------------------*/
+/*
+ void radf3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ long i, ic;
+ float ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
+ long iw1, iw2;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx3 = 2 * idx0;
+ long idx4 = (3 * k + 1) * ido;
+ long iidx1 = in_off + idx1;
+ long iidx2 = iidx1 + idx0;
+ long iidx3 = iidx1 + idx3;
+ float i1r = in.getFloat(iidx1);
+ float i2r = in.getFloat(iidx2);
+ float i3r = in.getFloat(iidx3);
+ cr2 = i2r + i3r;
+ out.setFloat(out_off + 3 * idx1, i1r + cr2);
+ out.setFloat(out_off + idx4 + ido, taui * (i3r - i2r));
+ out.setFloat(out_off + ido - 1 + idx4, i1r + taur * cr2);
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido;
+ long idx4 = 3 * idx3;
+ long idx5 = idx3 + idx0;
+ long idx6 = idx5 + idx0;
+ long idx7 = idx4 + ido;
+ long idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+
+ long idx9 = in_off + i;
+ long idx10 = out_off + i;
+ long idx11 = out_off + ic;
+ long iidx1 = idx9 + idx3;
+ long iidx2 = idx9 + idx5;
+ long iidx3 = idx9 + idx6;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+
+ dr2 = w1r * i2i + w1i * i2r;
+ di2 = w1r * i2r - w1i * i2i;
+ dr3 = w2r * i3i + w2i * i3r;
+ di3 = w2r * i3r - w2i * i3i;
+ cr2 = dr2 + dr3;
+ ci2 = di2 + di3;
+ tr2 = i1i + taur * cr2;
+ ti2 = i1r + taur * ci2;
+ tr3 = taui * (di2 - di3);
+ ti3 = taui * (dr3 - dr2);
+
+ long oidx1 = idx10 + idx4;
+ long oidx2 = idx11 + idx7;
+ long oidx3 = idx10 + idx8;
+
+ out.setFloat(oidx1 - 1, i1i + cr2);
+ out.setFloat(oidx1, i1r + ci2);
+ out.setFloat(oidx2 - 1, tr2 - tr3);
+ out.setFloat(oidx2, ti3 - ti2);
+ out.setFloat(oidx3 - 1, tr2 + tr3);
+ out.setFloat(oidx3, ti2 + ti3);
+ }
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radb3: Real FFT's backward processing of factor 3
+ -------------------------------------------------*/
+ void radb3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ int i, ic;
+ float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
+ int iw1, iw2;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int iidx1 = in_off + 3 * idx1;
+ int iidx2 = iidx1 + 2 * ido;
+ float i1i = in[iidx1];
+
+ tr2 = 2 * in[iidx2 - 1];
+ cr2 = i1i + taur * tr2;
+ ci3 = 2 * taui * in[iidx2];
+
+ out[out_off + idx1] = i1i + tr2;
+ out[out_off + (k + l1) * ido] = cr2 - ci3;
+ out[out_off + (k + 2 * l1) * ido] = cr2 + ci3;
+ }
+ if (ido == 1) {
+ return;
+ }
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 3 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx3 + ido;
+ int idx5 = idx1 + idx0;
+ int idx6 = idx5 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx7 = in_off + i;
+ int idx8 = in_off + ic;
+ int idx9 = out_off + i;
+ int iidx1 = idx7 + idx2;
+ int iidx2 = idx7 + idx4;
+ int iidx3 = idx8 + idx3;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+
+ tr2 = i2i + i3i;
+ cr2 = i1i + taur * tr2;
+ ti2 = i2r - i3r;
+ ci2 = i1r + taur * ti2;
+ cr3 = taui * (i2i - i3i);
+ ci3 = taui * (i2r + i3r);
+ dr2 = cr2 - ci3;
+ dr3 = cr2 + ci3;
+ di2 = ci2 + cr3;
+ di3 = ci2 - cr3;
+
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+
+ int oidx1 = idx9 + idx1;
+ int oidx2 = idx9 + idx5;
+ int oidx3 = idx9 + idx6;
+
+ out[oidx1 - 1] = i1i + tr2;
+ out[oidx1] = i1r + ti2;
+ out[oidx2 - 1] = w1r * dr2 - w1i * di2;
+ out[oidx2] = w1r * di2 + w1i * dr2;
+ out[oidx3 - 1] = w2r * dr3 - w2i * di3;
+ out[oidx3] = w2r * di3 + w2i * dr3;
+ }
+ }
+ }
+
+ /*-------------------------------------------------
+ radb3: Real FFT's backward processing of factor 3
+ -------------------------------------------------*/
+/*
+ void radb3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ long i, ic;
+ float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
+ long iw1, iw2;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long iidx1 = in_off + 3 * idx1;
+ long iidx2 = iidx1 + 2 * ido;
+ float i1i = in.getFloat(iidx1);
+
+ tr2 = 2 * in.getFloat(iidx2 - 1);
+ cr2 = i1i + taur * tr2;
+ ci3 = 2 * taui * in.getFloat(iidx2);
+
+ out.setFloat(out_off + idx1, i1i + tr2);
+ out.setFloat(out_off + (k + l1) * ido, cr2 - ci3);
+ out.setFloat(out_off + (k + 2 * l1) * ido, cr2 + ci3);
+ }
+ if (ido == 1) {
+ return;
+ }
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 3 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx3 + ido;
+ long idx5 = idx1 + idx0;
+ long idx6 = idx5 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx7 = in_off + i;
+ long idx8 = in_off + ic;
+ long idx9 = out_off + i;
+ long iidx1 = idx7 + idx2;
+ long iidx2 = idx7 + idx4;
+ long iidx3 = idx8 + idx3;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+
+ tr2 = i2i + i3i;
+ cr2 = i1i + taur * tr2;
+ ti2 = i2r - i3r;
+ ci2 = i1r + taur * ti2;
+ cr3 = taui * (i2i - i3i);
+ ci3 = taui * (i2r + i3r);
+ dr2 = cr2 - ci3;
+ dr3 = cr2 + ci3;
+ di2 = ci2 + cr3;
+ di3 = ci2 - cr3;
+
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+
+ long oidx1 = idx9 + idx1;
+ long oidx2 = idx9 + idx5;
+ long oidx3 = idx9 + idx6;
+
+ out.setFloat(oidx1 - 1, i1i + tr2);
+ out.setFloat(oidx1, i1r + ti2);
+ out.setFloat(oidx2 - 1, w1r * dr2 - w1i * di2);
+ out.setFloat(oidx2, w1r * di2 + w1i * dr2);
+ out.setFloat(oidx3 - 1, w2r * dr3 - w2i * di3);
+ out.setFloat(oidx3, w2r * di3 + w2i * dr3);
+ }
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radf4: Real FFT's forward processing of factor 4
+ -------------------------------------------------*/
+ void radf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float hsqt2 = 0.707106781186547572737310929369414225f;
+ int i, ic;
+ float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
+ int iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = offset + ido;
+ iw3 = iw2 + ido;
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 4 * idx1;
+ int idx3 = idx1 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = idx4 + idx0;
+ int idx6 = idx2 + ido;
+ float i1r = in[in_off + idx1];
+ float i2r = in[in_off + idx3];
+ float i3r = in[in_off + idx4];
+ float i4r = in[in_off + idx5];
+
+ tr1 = i2r + i4r;
+ tr2 = i1r + i3r;
+
+ int oidx1 = out_off + idx2;
+ int oidx2 = out_off + idx6 + ido;
+
+ out[oidx1] = tr1 + tr2;
+ out[oidx2 - 1 + ido + ido] = tr2 - tr1;
+ out[oidx2 - 1] = i1r - i3r;
+ out[oidx2] = i4r - i2r;
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = idx1 + idx0;
+ int idx3 = idx2 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = 4 * idx1;
+ int idx6 = idx5 + ido;
+ int idx7 = idx6 + ido;
+ int idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+ int widx3 = i - 1 + iw3;
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+ w3r = wtable_r[widx3 - 1];
+ w3i = wtable_r[widx3];
+
+ int idx9 = in_off + i;
+ int idx10 = out_off + i;
+ int idx11 = out_off + ic;
+ int iidx1 = idx9 + idx1;
+ int iidx2 = idx9 + idx2;
+ int iidx3 = idx9 + idx3;
+ int iidx4 = idx9 + idx4;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+
+ cr2 = w1r * i2i + w1i * i2r;
+ ci2 = w1r * i2r - w1i * i2i;
+ cr3 = w2r * i3i + w2i * i3r;
+ ci3 = w2r * i3r - w2i * i3i;
+ cr4 = w3r * i4i + w3i * i4r;
+ ci4 = w3r * i4r - w3i * i4i;
+ tr1 = cr2 + cr4;
+ tr4 = cr4 - cr2;
+ ti1 = ci2 + ci4;
+ ti4 = ci2 - ci4;
+ ti2 = i1r + ci3;
+ ti3 = i1r - ci3;
+ tr2 = i1i + cr3;
+ tr3 = i1i - cr3;
+
+ int oidx1 = idx10 + idx5;
+ int oidx2 = idx11 + idx6;
+ int oidx3 = idx10 + idx7;
+ int oidx4 = idx11 + idx8;
+
+ out[oidx1 - 1] = tr1 + tr2;
+ out[oidx4 - 1] = tr2 - tr1;
+ out[oidx1] = ti1 + ti2;
+ out[oidx4] = ti1 - ti2;
+ out[oidx3 - 1] = ti4 + tr3;
+ out[oidx2 - 1] = tr3 - ti4;
+ out[oidx3] = tr4 + ti3;
+ out[oidx2] = tr4 - ti3;
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 4 * idx1;
+ int idx3 = idx1 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = idx4 + idx0;
+ int idx6 = idx2 + ido;
+ int idx7 = idx6 + ido;
+ int idx8 = idx7 + ido;
+ int idx9 = in_off + ido;
+ int idx10 = out_off + ido;
+
+ float i1i = in[idx9 - 1 + idx1];
+ float i2i = in[idx9 - 1 + idx3];
+ float i3i = in[idx9 - 1 + idx4];
+ float i4i = in[idx9 - 1 + idx5];
+
+ ti1 = -hsqt2 * (i2i + i4i);
+ tr1 = hsqt2 * (i2i - i4i);
+
+ out[idx10 - 1 + idx2] = tr1 + i1i;
+ out[idx10 - 1 + idx7] = i1i - tr1;
+ out[out_off + idx6] = ti1 - i3i;
+ out[out_off + idx8] = ti1 + i3i;
+ }
+ }
+
+ /*-------------------------------------------------
+ radf4: Real FFT's forward processing of factor 4
+ -------------------------------------------------*/
+/*
+ void radf4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float hsqt2 = 0.707106781186547572737310929369414225f;
+ long i, ic;
+ float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
+ long iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = offset + ido;
+ iw3 = iw2 + ido;
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 4 * idx1;
+ long idx3 = idx1 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = idx4 + idx0;
+ long idx6 = idx2 + ido;
+ float i1r = in.getFloat(in_off + idx1);
+ float i2r = in.getFloat(in_off + idx3);
+ float i3r = in.getFloat(in_off + idx4);
+ float i4r = in.getFloat(in_off + idx5);
+
+ tr1 = i2r + i4r;
+ tr2 = i1r + i3r;
+
+ long oidx1 = out_off + idx2;
+ long oidx2 = out_off + idx6 + ido;
+
+ out.setFloat(oidx1, tr1 + tr2);
+ out.setFloat(oidx2 - 1 + ido + ido, tr2 - tr1);
+ out.setFloat(oidx2 - 1, i1r - i3r);
+ out.setFloat(oidx2, i4r - i2r);
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = idx1 + idx0;
+ long idx3 = idx2 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = 4 * idx1;
+ long idx6 = idx5 + ido;
+ long idx7 = idx6 + ido;
+ long idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+ long widx3 = i - 1 + iw3;
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+ w3r = wtable_rl.getFloat(widx3 - 1);
+ w3i = wtable_rl.getFloat(widx3);
+
+ long idx9 = in_off + i;
+ long idx10 = out_off + i;
+ long idx11 = out_off + ic;
+ long iidx1 = idx9 + idx1;
+ long iidx2 = idx9 + idx2;
+ long iidx3 = idx9 + idx3;
+ long iidx4 = idx9 + idx4;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+
+ cr2 = w1r * i2i + w1i * i2r;
+ ci2 = w1r * i2r - w1i * i2i;
+ cr3 = w2r * i3i + w2i * i3r;
+ ci3 = w2r * i3r - w2i * i3i;
+ cr4 = w3r * i4i + w3i * i4r;
+ ci4 = w3r * i4r - w3i * i4i;
+ tr1 = cr2 + cr4;
+ tr4 = cr4 - cr2;
+ ti1 = ci2 + ci4;
+ ti4 = ci2 - ci4;
+ ti2 = i1r + ci3;
+ ti3 = i1r - ci3;
+ tr2 = i1i + cr3;
+ tr3 = i1i - cr3;
+
+ long oidx1 = idx10 + idx5;
+ long oidx2 = idx11 + idx6;
+ long oidx3 = idx10 + idx7;
+ long oidx4 = idx11 + idx8;
+
+ out.setFloat(oidx1 - 1, tr1 + tr2);
+ out.setFloat(oidx4 - 1, tr2 - tr1);
+ out.setFloat(oidx1, ti1 + ti2);
+ out.setFloat(oidx4, ti1 - ti2);
+ out.setFloat(oidx3 - 1, ti4 + tr3);
+ out.setFloat(oidx2 - 1, tr3 - ti4);
+ out.setFloat(oidx3, tr4 + ti3);
+ out.setFloat(oidx2, tr4 - ti3);
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 4 * idx1;
+ long idx3 = idx1 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = idx4 + idx0;
+ long idx6 = idx2 + ido;
+ long idx7 = idx6 + ido;
+ long idx8 = idx7 + ido;
+ long idx9 = in_off + ido;
+ long idx10 = out_off + ido;
+
+ float i1i = in.getFloat(idx9 - 1 + idx1);
+ float i2i = in.getFloat(idx9 - 1 + idx3);
+ float i3i = in.getFloat(idx9 - 1 + idx4);
+ float i4i = in.getFloat(idx9 - 1 + idx5);
+
+ ti1 = -hsqt2 * (i2i + i4i);
+ tr1 = hsqt2 * (i2i - i4i);
+
+ out.setFloat(idx10 - 1 + idx2, tr1 + i1i);
+ out.setFloat(idx10 - 1 + idx7, i1i - tr1);
+ out.setFloat(out_off + idx6, ti1 - i3i);
+ out.setFloat(out_off + idx8, ti1 + i3i);
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radb4: Real FFT's backward processing of factor 4
+ -------------------------------------------------*/
+ void radb4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float sqrt2 = 1.41421356237309514547462185873882845f;
+ int i, ic;
+ float ci2, ci3, ci4, cr2, cr3, cr4;
+ float ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
+ int iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 4 * idx1;
+ int idx3 = idx1 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = idx4 + idx0;
+ int idx6 = idx2 + ido;
+ int idx7 = idx6 + ido;
+ int idx8 = idx7 + ido;
+
+ float i1r = in[in_off + idx2];
+ float i2r = in[in_off + idx7];
+ float i3r = in[in_off + ido - 1 + idx8];
+ float i4r = in[in_off + ido - 1 + idx6];
+
+ tr1 = i1r - i3r;
+ tr2 = i1r + i3r;
+ tr3 = i4r + i4r;
+ tr4 = i2r + i2r;
+
+ out[out_off + idx1] = tr2 + tr3;
+ out[out_off + idx3] = tr1 - tr4;
+ out[out_off + idx4] = tr2 - tr3;
+ out[out_off + idx5] = tr1 + tr4;
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (int k = 0; k < l1; ++k) {
+ int idx1 = k * ido;
+ int idx2 = idx1 + idx0;
+ int idx3 = idx2 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = 4 * idx1;
+ int idx6 = idx5 + ido;
+ int idx7 = idx6 + ido;
+ int idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+ int widx3 = i - 1 + iw3;
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+ w3r = wtable_r[widx3 - 1];
+ w3i = wtable_r[widx3];
+
+ int idx12 = in_off + i;
+ int idx13 = in_off + ic;
+ int idx14 = out_off + i;
+
+ int iidx1 = idx12 + idx5;
+ int iidx2 = idx13 + idx6;
+ int iidx3 = idx12 + idx7;
+ int iidx4 = idx13 + idx8;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+
+ ti1 = i1r + i4r;
+ ti2 = i1r - i4r;
+ ti3 = i3r - i2r;
+ tr4 = i3r + i2r;
+ tr1 = i1i - i4i;
+ tr2 = i1i + i4i;
+ ti4 = i3i - i2i;
+ tr3 = i3i + i2i;
+ cr3 = tr2 - tr3;
+ ci3 = ti2 - ti3;
+ cr2 = tr1 - tr4;
+ cr4 = tr1 + tr4;
+ ci2 = ti1 + ti4;
+ ci4 = ti1 - ti4;
+
+ int oidx1 = idx14 + idx1;
+ int oidx2 = idx14 + idx2;
+ int oidx3 = idx14 + idx3;
+ int oidx4 = idx14 + idx4;
+
+ out[oidx1 - 1] = tr2 + tr3;
+ out[oidx1] = ti2 + ti3;
+ out[oidx2 - 1] = w1r * cr2 - w1i * ci2;
+ out[oidx2] = w1r * ci2 + w1i * cr2;
+ out[oidx3 - 1] = w2r * cr3 - w2i * ci3;
+ out[oidx3] = w2r * ci3 + w2i * cr3;
+ out[oidx4 - 1] = w3r * cr4 - w3i * ci4;
+ out[oidx4] = w3r * ci4 + w3i * cr4;
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 4 * idx1;
+ int idx3 = idx1 + idx0;
+ int idx4 = idx3 + idx0;
+ int idx5 = idx4 + idx0;
+ int idx6 = idx2 + ido;
+ int idx7 = idx6 + ido;
+ int idx8 = idx7 + ido;
+ int idx9 = in_off + ido;
+ int idx10 = out_off + ido;
+
+ float i1r = in[idx9 - 1 + idx2];
+ float i2r = in[idx9 - 1 + idx7];
+ float i3r = in[in_off + idx6];
+ float i4r = in[in_off + idx8];
+
+ ti1 = i3r + i4r;
+ ti2 = i4r - i3r;
+ tr1 = i1r - i2r;
+ tr2 = i1r + i2r;
+
+ out[idx10 - 1 + idx1] = tr2 + tr2;
+ out[idx10 - 1 + idx3] = sqrt2 * (tr1 - ti1);
+ out[idx10 - 1 + idx4] = ti2 + ti2;
+ out[idx10 - 1 + idx5] = -sqrt2 * (tr1 + ti1);
+ }
+ }
+
+ /*-------------------------------------------------
+ radb4: Real FFT's backward processing of factor 4
+ -------------------------------------------------*/
+/*
+ void radb4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float sqrt2 = 1.41421356237309514547462185873882845f;
+ long i, ic;
+ float ci2, ci3, ci4, cr2, cr3, cr4;
+ float ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
+ long iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 4 * idx1;
+ long idx3 = idx1 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = idx4 + idx0;
+ long idx6 = idx2 + ido;
+ long idx7 = idx6 + ido;
+ long idx8 = idx7 + ido;
+
+ float i1r = in.getFloat(in_off + idx2);
+ float i2r = in.getFloat(in_off + idx7);
+ float i3r = in.getFloat(in_off + ido - 1 + idx8);
+ float i4r = in.getFloat(in_off + ido - 1 + idx6);
+
+ tr1 = i1r - i3r;
+ tr2 = i1r + i3r;
+ tr3 = i4r + i4r;
+ tr4 = i2r + i2r;
+
+ out.setFloat(out_off + idx1, tr2 + tr3);
+ out.setFloat(out_off + idx3, tr1 - tr4);
+ out.setFloat(out_off + idx4, tr2 - tr3);
+ out.setFloat(out_off + idx5, tr1 + tr4);
+ }
+ if (ido < 2) {
+ return;
+ }
+ if (ido != 2) {
+ for (long k = 0; k < l1; ++k) {
+ long idx1 = k * ido;
+ long idx2 = idx1 + idx0;
+ long idx3 = idx2 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = 4 * idx1;
+ long idx6 = idx5 + ido;
+ long idx7 = idx6 + ido;
+ long idx8 = idx7 + ido;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+ long widx3 = i - 1 + iw3;
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+ w3r = wtable_rl.getFloat(widx3 - 1);
+ w3i = wtable_rl.getFloat(widx3);
+
+ long idx12 = in_off + i;
+ long idx13 = in_off + ic;
+ long idx14 = out_off + i;
+
+ long iidx1 = idx12 + idx5;
+ long iidx2 = idx13 + idx6;
+ long iidx3 = idx12 + idx7;
+ long iidx4 = idx13 + idx8;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+
+ ti1 = i1r + i4r;
+ ti2 = i1r - i4r;
+ ti3 = i3r - i2r;
+ tr4 = i3r + i2r;
+ tr1 = i1i - i4i;
+ tr2 = i1i + i4i;
+ ti4 = i3i - i2i;
+ tr3 = i3i + i2i;
+ cr3 = tr2 - tr3;
+ ci3 = ti2 - ti3;
+ cr2 = tr1 - tr4;
+ cr4 = tr1 + tr4;
+ ci2 = ti1 + ti4;
+ ci4 = ti1 - ti4;
+
+ long oidx1 = idx14 + idx1;
+ long oidx2 = idx14 + idx2;
+ long oidx3 = idx14 + idx3;
+ long oidx4 = idx14 + idx4;
+
+ out.setFloat(oidx1 - 1, tr2 + tr3);
+ out.setFloat(oidx1, ti2 + ti3);
+ out.setFloat(oidx2 - 1, w1r * cr2 - w1i * ci2);
+ out.setFloat(oidx2, w1r * ci2 + w1i * cr2);
+ out.setFloat(oidx3 - 1, w2r * cr3 - w2i * ci3);
+ out.setFloat(oidx3, w2r * ci3 + w2i * cr3);
+ out.setFloat(oidx4 - 1, w3r * cr4 - w3i * ci4);
+ out.setFloat(oidx4, w3r * ci4 + w3i * cr4);
+ }
+ }
+ if (ido % 2 == 1) {
+ return;
+ }
+ }
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 4 * idx1;
+ long idx3 = idx1 + idx0;
+ long idx4 = idx3 + idx0;
+ long idx5 = idx4 + idx0;
+ long idx6 = idx2 + ido;
+ long idx7 = idx6 + ido;
+ long idx8 = idx7 + ido;
+ long idx9 = in_off + ido;
+ long idx10 = out_off + ido;
+
+ float i1r = in.getFloat(idx9 - 1 + idx2);
+ float i2r = in.getFloat(idx9 - 1 + idx7);
+ float i3r = in.getFloat(in_off + idx6);
+ float i4r = in.getFloat(in_off + idx8);
+
+ ti1 = i3r + i4r;
+ ti2 = i4r - i3r;
+ tr1 = i1r - i2r;
+ tr2 = i1r + i2r;
+
+ out.setFloat(idx10 - 1 + idx1, tr2 + tr2);
+ out.setFloat(idx10 - 1 + idx3, sqrt2 * (tr1 - ti1));
+ out.setFloat(idx10 - 1 + idx4, ti2 + ti2);
+ out.setFloat(idx10 - 1 + idx5, -sqrt2 * (tr1 + ti1));
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radf5: Real FFT's forward processing of factor 5
+ -------------------------------------------------*/
+ void radf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ int i, ic;
+ float ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
+ int iw1, iw2, iw3, iw4;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 5 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx3 + ido;
+ int idx5 = idx4 + ido;
+ int idx6 = idx5 + ido;
+ int idx7 = idx1 + idx0;
+ int idx8 = idx7 + idx0;
+ int idx9 = idx8 + idx0;
+ int idx10 = idx9 + idx0;
+ int idx11 = out_off + ido - 1;
+
+ float i1r = in[in_off + idx1];
+ float i2r = in[in_off + idx7];
+ float i3r = in[in_off + idx8];
+ float i4r = in[in_off + idx9];
+ float i5r = in[in_off + idx10];
+
+ cr2 = i5r + i2r;
+ ci5 = i5r - i2r;
+ cr3 = i4r + i3r;
+ ci4 = i4r - i3r;
+
+ out[out_off + idx2] = i1r + cr2 + cr3;
+ out[idx11 + idx3] = i1r + tr11 * cr2 + tr12 * cr3;
+ out[out_off + idx4] = ti11 * ci5 + ti12 * ci4;
+ out[idx11 + idx5] = i1r + tr12 * cr2 + tr11 * cr3;
+ out[out_off + idx6] = ti12 * ci5 - ti11 * ci4;
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (int k = 0; k < l1; ++k) {
+ int idx1 = k * ido;
+ int idx2 = 5 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx3 + ido;
+ int idx5 = idx4 + ido;
+ int idx6 = idx5 + ido;
+ int idx7 = idx1 + idx0;
+ int idx8 = idx7 + idx0;
+ int idx9 = idx8 + idx0;
+ int idx10 = idx9 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+ int widx3 = i - 1 + iw3;
+ int widx4 = i - 1 + iw4;
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+ w3r = wtable_r[widx3 - 1];
+ w3i = wtable_r[widx3];
+ w4r = wtable_r[widx4 - 1];
+ w4i = wtable_r[widx4];
+
+ ic = ido - i;
+ int idx15 = in_off + i;
+ int idx16 = out_off + i;
+ int idx17 = out_off + ic;
+
+ int iidx1 = idx15 + idx1;
+ int iidx2 = idx15 + idx7;
+ int iidx3 = idx15 + idx8;
+ int iidx4 = idx15 + idx9;
+ int iidx5 = idx15 + idx10;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+ float i5i = in[iidx5 - 1];
+ float i5r = in[iidx5];
+
+ dr2 = w1r * i2i + w1i * i2r;
+ di2 = w1r * i2r - w1i * i2i;
+ dr3 = w2r * i3i + w2i * i3r;
+ di3 = w2r * i3r - w2i * i3i;
+ dr4 = w3r * i4i + w3i * i4r;
+ di4 = w3r * i4r - w3i * i4i;
+ dr5 = w4r * i5i + w4i * i5r;
+ di5 = w4r * i5r - w4i * i5i;
+
+ cr2 = dr2 + dr5;
+ ci5 = dr5 - dr2;
+ cr5 = di2 - di5;
+ ci2 = di2 + di5;
+ cr3 = dr3 + dr4;
+ ci4 = dr4 - dr3;
+ cr4 = di3 - di4;
+ ci3 = di3 + di4;
+
+ tr2 = i1i + tr11 * cr2 + tr12 * cr3;
+ ti2 = i1r + tr11 * ci2 + tr12 * ci3;
+ tr3 = i1i + tr12 * cr2 + tr11 * cr3;
+ ti3 = i1r + tr12 * ci2 + tr11 * ci3;
+ tr5 = ti11 * cr5 + ti12 * cr4;
+ ti5 = ti11 * ci5 + ti12 * ci4;
+ tr4 = ti12 * cr5 - ti11 * cr4;
+ ti4 = ti12 * ci5 - ti11 * ci4;
+
+ int oidx1 = idx16 + idx2;
+ int oidx2 = idx17 + idx3;
+ int oidx3 = idx16 + idx4;
+ int oidx4 = idx17 + idx5;
+ int oidx5 = idx16 + idx6;
+
+ out[oidx1 - 1] = i1i + cr2 + cr3;
+ out[oidx1] = i1r + ci2 + ci3;
+ out[oidx3 - 1] = tr2 + tr5;
+ out[oidx2 - 1] = tr2 - tr5;
+ out[oidx3] = ti2 + ti5;
+ out[oidx2] = ti5 - ti2;
+ out[oidx5 - 1] = tr3 + tr4;
+ out[oidx4 - 1] = tr3 - tr4;
+ out[oidx5] = ti3 + ti4;
+ out[oidx4] = ti4 - ti3;
+ }
+ }
+ }
+
+ /*-------------------------------------------------
+ radf5: Real FFT's forward processing of factor 5
+ -------------------------------------------------*/
+/*
+ void radf5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ long i, ic;
+ float ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
+ long iw1, iw2, iw3, iw4;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 5 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx3 + ido;
+ long idx5 = idx4 + ido;
+ long idx6 = idx5 + ido;
+ long idx7 = idx1 + idx0;
+ long idx8 = idx7 + idx0;
+ long idx9 = idx8 + idx0;
+ long idx10 = idx9 + idx0;
+ long idx11 = out_off + ido - 1;
+
+ float i1r = in.getFloat(in_off + idx1);
+ float i2r = in.getFloat(in_off + idx7);
+ float i3r = in.getFloat(in_off + idx8);
+ float i4r = in.getFloat(in_off + idx9);
+ float i5r = in.getFloat(in_off + idx10);
+
+ cr2 = i5r + i2r;
+ ci5 = i5r - i2r;
+ cr3 = i4r + i3r;
+ ci4 = i4r - i3r;
+
+ out.setFloat(out_off + idx2, i1r + cr2 + cr3);
+ out.setFloat(idx11 + idx3, i1r + tr11 * cr2 + tr12 * cr3);
+ out.setFloat(out_off + idx4, ti11 * ci5 + ti12 * ci4);
+ out.setFloat(idx11 + idx5, i1r + tr12 * cr2 + tr11 * cr3);
+ out.setFloat(out_off + idx6, ti12 * ci5 - ti11 * ci4);
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (long k = 0; k < l1; ++k) {
+ long idx1 = k * ido;
+ long idx2 = 5 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx3 + ido;
+ long idx5 = idx4 + ido;
+ long idx6 = idx5 + ido;
+ long idx7 = idx1 + idx0;
+ long idx8 = idx7 + idx0;
+ long idx9 = idx8 + idx0;
+ long idx10 = idx9 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+ long widx3 = i - 1 + iw3;
+ long widx4 = i - 1 + iw4;
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+ w3r = wtable_rl.getFloat(widx3 - 1);
+ w3i = wtable_rl.getFloat(widx3);
+ w4r = wtable_rl.getFloat(widx4 - 1);
+ w4i = wtable_rl.getFloat(widx4);
+
+ ic = ido - i;
+ long idx15 = in_off + i;
+ long idx16 = out_off + i;
+ long idx17 = out_off + ic;
+
+ long iidx1 = idx15 + idx1;
+ long iidx2 = idx15 + idx7;
+ long iidx3 = idx15 + idx8;
+ long iidx4 = idx15 + idx9;
+ long iidx5 = idx15 + idx10;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+ float i5i = in.getFloat(iidx5 - 1);
+ float i5r = in.getFloat(iidx5);
+
+ dr2 = w1r * i2i + w1i * i2r;
+ di2 = w1r * i2r - w1i * i2i;
+ dr3 = w2r * i3i + w2i * i3r;
+ di3 = w2r * i3r - w2i * i3i;
+ dr4 = w3r * i4i + w3i * i4r;
+ di4 = w3r * i4r - w3i * i4i;
+ dr5 = w4r * i5i + w4i * i5r;
+ di5 = w4r * i5r - w4i * i5i;
+
+ cr2 = dr2 + dr5;
+ ci5 = dr5 - dr2;
+ cr5 = di2 - di5;
+ ci2 = di2 + di5;
+ cr3 = dr3 + dr4;
+ ci4 = dr4 - dr3;
+ cr4 = di3 - di4;
+ ci3 = di3 + di4;
+
+ tr2 = i1i + tr11 * cr2 + tr12 * cr3;
+ ti2 = i1r + tr11 * ci2 + tr12 * ci3;
+ tr3 = i1i + tr12 * cr2 + tr11 * cr3;
+ ti3 = i1r + tr12 * ci2 + tr11 * ci3;
+ tr5 = ti11 * cr5 + ti12 * cr4;
+ ti5 = ti11 * ci5 + ti12 * ci4;
+ tr4 = ti12 * cr5 - ti11 * cr4;
+ ti4 = ti12 * ci5 - ti11 * ci4;
+
+ long oidx1 = idx16 + idx2;
+ long oidx2 = idx17 + idx3;
+ long oidx3 = idx16 + idx4;
+ long oidx4 = idx17 + idx5;
+ long oidx5 = idx16 + idx6;
+
+ out.setFloat(oidx1 - 1, i1i + cr2 + cr3);
+ out.setFloat(oidx1, i1r + ci2 + ci3);
+ out.setFloat(oidx3 - 1, tr2 + tr5);
+ out.setFloat(oidx2 - 1, tr2 - tr5);
+ out.setFloat(oidx3, ti2 + ti5);
+ out.setFloat(oidx2, ti5 - ti2);
+ out.setFloat(oidx5 - 1, tr3 + tr4);
+ out.setFloat(oidx4 - 1, tr3 - tr4);
+ out.setFloat(oidx5, ti3 + ti4);
+ out.setFloat(oidx4, ti4 - ti3);
+ }
+ }
+ }
+*/
+ /*-------------------------------------------------
+ radb5: Real FFT's backward processing of factor 5
+ -------------------------------------------------*/
+ void radb5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ int i, ic;
+ float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
+ int iw1, iw2, iw3, iw4;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ int idx0 = l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = 5 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx3 + ido;
+ int idx5 = idx4 + ido;
+ int idx6 = idx5 + ido;
+ int idx7 = idx1 + idx0;
+ int idx8 = idx7 + idx0;
+ int idx9 = idx8 + idx0;
+ int idx10 = idx9 + idx0;
+ int idx11 = in_off + ido - 1;
+
+ float i1r = in[in_off + idx2];
+
+ ti5 = 2 * in[in_off + idx4];
+ ti4 = 2 * in[in_off + idx6];
+ tr2 = 2 * in[idx11 + idx3];
+ tr3 = 2 * in[idx11 + idx5];
+ cr2 = i1r + tr11 * tr2 + tr12 * tr3;
+ cr3 = i1r + tr12 * tr2 + tr11 * tr3;
+ ci5 = ti11 * ti5 + ti12 * ti4;
+ ci4 = ti12 * ti5 - ti11 * ti4;
+
+ out[out_off + idx1] = i1r + tr2 + tr3;
+ out[out_off + idx7] = cr2 - ci5;
+ out[out_off + idx8] = cr3 - ci4;
+ out[out_off + idx9] = cr3 + ci4;
+ out[out_off + idx10] = cr2 + ci5;
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (int k = 0; k < l1; ++k) {
+ int idx1 = k * ido;
+ int idx2 = 5 * idx1;
+ int idx3 = idx2 + ido;
+ int idx4 = idx3 + ido;
+ int idx5 = idx4 + ido;
+ int idx6 = idx5 + ido;
+ int idx7 = idx1 + idx0;
+ int idx8 = idx7 + idx0;
+ int idx9 = idx8 + idx0;
+ int idx10 = idx9 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int widx1 = i - 1 + iw1;
+ int widx2 = i - 1 + iw2;
+ int widx3 = i - 1 + iw3;
+ int widx4 = i - 1 + iw4;
+ w1r = wtable_r[widx1 - 1];
+ w1i = wtable_r[widx1];
+ w2r = wtable_r[widx2 - 1];
+ w2i = wtable_r[widx2];
+ w3r = wtable_r[widx3 - 1];
+ w3i = wtable_r[widx3];
+ w4r = wtable_r[widx4 - 1];
+ w4i = wtable_r[widx4];
+
+ int idx15 = in_off + i;
+ int idx16 = in_off + ic;
+ int idx17 = out_off + i;
+
+ int iidx1 = idx15 + idx2;
+ int iidx2 = idx16 + idx3;
+ int iidx3 = idx15 + idx4;
+ int iidx4 = idx16 + idx5;
+ int iidx5 = idx15 + idx6;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+ float i5i = in[iidx5 - 1];
+ float i5r = in[iidx5];
+
+ ti5 = i3r + i2r;
+ ti2 = i3r - i2r;
+ ti4 = i5r + i4r;
+ ti3 = i5r - i4r;
+ tr5 = i3i - i2i;
+ tr2 = i3i + i2i;
+ tr4 = i5i - i4i;
+ tr3 = i5i + i4i;
+
+ cr2 = i1i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i1r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i1i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i1r + tr12 * ti2 + tr11 * ti3;
+ cr5 = ti11 * tr5 + ti12 * tr4;
+ ci5 = ti11 * ti5 + ti12 * ti4;
+ cr4 = ti12 * tr5 - ti11 * tr4;
+ ci4 = ti12 * ti5 - ti11 * ti4;
+ dr3 = cr3 - ci4;
+ dr4 = cr3 + ci4;
+ di3 = ci3 + cr4;
+ di4 = ci3 - cr4;
+ dr5 = cr2 + ci5;
+ dr2 = cr2 - ci5;
+ di5 = ci2 - cr5;
+ di2 = ci2 + cr5;
+
+ int oidx1 = idx17 + idx1;
+ int oidx2 = idx17 + idx7;
+ int oidx3 = idx17 + idx8;
+ int oidx4 = idx17 + idx9;
+ int oidx5 = idx17 + idx10;
+
+ out[oidx1 - 1] = i1i + tr2 + tr3;
+ out[oidx1] = i1r + ti2 + ti3;
+ out[oidx2 - 1] = w1r * dr2 - w1i * di2;
+ out[oidx2] = w1r * di2 + w1i * dr2;
+ out[oidx3 - 1] = w2r * dr3 - w2i * di3;
+ out[oidx3] = w2r * di3 + w2i * dr3;
+ out[oidx4 - 1] = w3r * dr4 - w3i * di4;
+ out[oidx4] = w3r * di4 + w3i * dr4;
+ out[oidx5 - 1] = w4r * dr5 - w4i * di5;
+ out[oidx5] = w4r * di5 + w4i * dr5;
+ }
+ }
+ }
+
+ /*-------------------------------------------------
+ radb5: Real FFT's backward processing of factor 5
+ -------------------------------------------------*/
+/*
+ void radb5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ long i, ic;
+ float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
+ long iw1, iw2, iw3, iw4;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ long idx0 = l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = 5 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx3 + ido;
+ long idx5 = idx4 + ido;
+ long idx6 = idx5 + ido;
+ long idx7 = idx1 + idx0;
+ long idx8 = idx7 + idx0;
+ long idx9 = idx8 + idx0;
+ long idx10 = idx9 + idx0;
+ long idx11 = in_off + ido - 1;
+
+ float i1r = in.getFloat(in_off + idx2);
+
+ ti5 = 2 * in.getFloat(in_off + idx4);
+ ti4 = 2 * in.getFloat(in_off + idx6);
+ tr2 = 2 * in.getFloat(idx11 + idx3);
+ tr3 = 2 * in.getFloat(idx11 + idx5);
+ cr2 = i1r + tr11 * tr2 + tr12 * tr3;
+ cr3 = i1r + tr12 * tr2 + tr11 * tr3;
+ ci5 = ti11 * ti5 + ti12 * ti4;
+ ci4 = ti12 * ti5 - ti11 * ti4;
+
+ out.setFloat(out_off + idx1, i1r + tr2 + tr3);
+ out.setFloat(out_off + idx7, cr2 - ci5);
+ out.setFloat(out_off + idx8, cr3 - ci4);
+ out.setFloat(out_off + idx9, cr3 + ci4);
+ out.setFloat(out_off + idx10, cr2 + ci5);
+ }
+ if (ido == 1) {
+ return;
+ }
+ for (long k = 0; k < l1; ++k) {
+ long idx1 = k * ido;
+ long idx2 = 5 * idx1;
+ long idx3 = idx2 + ido;
+ long idx4 = idx3 + ido;
+ long idx5 = idx4 + ido;
+ long idx6 = idx5 + ido;
+ long idx7 = idx1 + idx0;
+ long idx8 = idx7 + idx0;
+ long idx9 = idx8 + idx0;
+ long idx10 = idx9 + idx0;
+ for (i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long widx1 = i - 1 + iw1;
+ long widx2 = i - 1 + iw2;
+ long widx3 = i - 1 + iw3;
+ long widx4 = i - 1 + iw4;
+ w1r = wtable_rl.getFloat(widx1 - 1);
+ w1i = wtable_rl.getFloat(widx1);
+ w2r = wtable_rl.getFloat(widx2 - 1);
+ w2i = wtable_rl.getFloat(widx2);
+ w3r = wtable_rl.getFloat(widx3 - 1);
+ w3i = wtable_rl.getFloat(widx3);
+ w4r = wtable_rl.getFloat(widx4 - 1);
+ w4i = wtable_rl.getFloat(widx4);
+
+ long idx15 = in_off + i;
+ long idx16 = in_off + ic;
+ long idx17 = out_off + i;
+
+ long iidx1 = idx15 + idx2;
+ long iidx2 = idx16 + idx3;
+ long iidx3 = idx15 + idx4;
+ long iidx4 = idx16 + idx5;
+ long iidx5 = idx15 + idx6;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+ float i5i = in.getFloat(iidx5 - 1);
+ float i5r = in.getFloat(iidx5);
+
+ ti5 = i3r + i2r;
+ ti2 = i3r - i2r;
+ ti4 = i5r + i4r;
+ ti3 = i5r - i4r;
+ tr5 = i3i - i2i;
+ tr2 = i3i + i2i;
+ tr4 = i5i - i4i;
+ tr3 = i5i + i4i;
+
+ cr2 = i1i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i1r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i1i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i1r + tr12 * ti2 + tr11 * ti3;
+ cr5 = ti11 * tr5 + ti12 * tr4;
+ ci5 = ti11 * ti5 + ti12 * ti4;
+ cr4 = ti12 * tr5 - ti11 * tr4;
+ ci4 = ti12 * ti5 - ti11 * ti4;
+ dr3 = cr3 - ci4;
+ dr4 = cr3 + ci4;
+ di3 = ci3 + cr4;
+ di4 = ci3 - cr4;
+ dr5 = cr2 + ci5;
+ dr2 = cr2 - ci5;
+ di5 = ci2 - cr5;
+ di2 = ci2 + cr5;
+
+ long oidx1 = idx17 + idx1;
+ long oidx2 = idx17 + idx7;
+ long oidx3 = idx17 + idx8;
+ long oidx4 = idx17 + idx9;
+ long oidx5 = idx17 + idx10;
+
+ out.setFloat(oidx1 - 1, i1i + tr2 + tr3);
+ out.setFloat(oidx1, i1r + ti2 + ti3);
+ out.setFloat(oidx2 - 1, w1r * dr2 - w1i * di2);
+ out.setFloat(oidx2, w1r * di2 + w1i * dr2);
+ out.setFloat(oidx3 - 1, w2r * dr3 - w2i * di3);
+ out.setFloat(oidx3, w2r * di3 + w2i * dr3);
+ out.setFloat(oidx4 - 1, w3r * dr4 - w3i * di4);
+ out.setFloat(oidx4, w3r * di4 + w3i * dr4);
+ out.setFloat(oidx5 - 1, w4r * dr5 - w4i * di5);
+ out.setFloat(oidx5, w4r * di5 + w4i * dr5);
+ }
+ }
+ }
+*/
+ /*---------------------------------------------------------
+ radfg: Real FFT's forward processing of general factor
+ --------------------------------------------------------*/
+ void radfg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ int idij, ipph, j2, ic, jc, lc, is, nbd;
+ float dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
+ int iw1 = offset;
+
+ arg = TWO_PI / (float) ip;
+ dcp = (float)Math.cos(arg);
+ dsp = (float)Math.sin(arg);
+ ipph = (ip + 1) / 2;
+ nbd = (ido - 1) / 2;
+ if (ido != 1) {
+ for (int ik = 0; ik < idl1; ik++) {
+ out[out_off + ik] = in[in_off + ik];
+ }
+ for (int j = 1; j < ip; j++) {
+ int idx1 = j * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx2 = k * ido + idx1;
+ out[out_off + idx2] = in[in_off + idx2];
+ }
+ }
+ if (nbd <= l1) {
+ is = -ido;
+ for (int j = 1; j < ip; j++) {
+ is += ido;
+ idij = is - 1;
+ int idx1 = j * l1 * ido;
+ for (int i = 2; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij + iw1;
+ int idx4 = in_off + i;
+ int idx5 = out_off + i;
+ w1r = wtable_r[idx2 - 1];
+ w1i = wtable_r[idx2];
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido + idx1;
+ int oidx1 = idx5 + idx3;
+ int iidx1 = idx4 + idx3;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+
+ out[oidx1 - 1] = w1r * i1i + w1i * i1r;
+ out[oidx1] = w1r * i1r - w1i * i1i;
+ }
+ }
+ }
+ } else {
+ is = -ido;
+ for (int j = 1; j < ip; j++) {
+ is += ido;
+ int idx1 = j * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ idij = is - 1;
+ int idx3 = k * ido + idx1;
+ for (int i = 2; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij + iw1;
+ w1r = wtable_r[idx2 - 1];
+ w1i = wtable_r[idx2];
+ int oidx1 = out_off + i + idx3;
+ int iidx1 = in_off + i + idx3;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+
+ out[oidx1 - 1] = w1r * i1i + w1i * i1r;
+ out[oidx1] = w1r * i1r - w1i * i1i;
+ }
+ }
+ }
+ }
+ if (nbd >= l1) {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido + idx1;
+ int idx4 = k * ido + idx2;
+ for (int i = 2; i < ido; i += 2) {
+ int idx5 = in_off + i;
+ int idx6 = out_off + i;
+ int iidx1 = idx5 + idx3;
+ int iidx2 = idx5 + idx4;
+ int oidx1 = idx6 + idx3;
+ int oidx2 = idx6 + idx4;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ float o2i = out[oidx2 - 1];
+ float o2r = out[oidx2];
+
+ in[iidx1 - 1] = o1i + o2i;
+ in[iidx1] = o1r + o2r;
+
+ in[iidx2 - 1] = o1r - o2r;
+ in[iidx2] = o2i - o1i;
+ }
+ }
+ }
+ } else {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int i = 2; i < ido; i += 2) {
+ int idx5 = in_off + i;
+ int idx6 = out_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido + idx1;
+ int idx4 = k * ido + idx2;
+ int iidx1 = idx5 + idx3;
+ int iidx2 = idx5 + idx4;
+ int oidx1 = idx6 + idx3;
+ int oidx2 = idx6 + idx4;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ float o2i = out[oidx2 - 1];
+ float o2r = out[oidx2];
+
+ in[iidx1 - 1] = o1i + o2i;
+ in[iidx1] = o1r + o2r;
+ in[iidx2 - 1] = o1r - o2r;
+ in[iidx2] = o2i - o1i;
+ }
+ }
+ }
+ }
+ } else {
+ System.arraycopy(out, out_off, in, in_off, idl1);
+ }
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido + idx1;
+ int idx4 = k * ido + idx2;
+ int oidx1 = out_off + idx3;
+ int oidx2 = out_off + idx4;
+ float o1r = out[oidx1];
+ float o2r = out[oidx2];
+
+ in[in_off + idx3] = o1r + o2r;
+ in[in_off + idx4] = o2r - o1r;
+ }
+ }
+
+ ar1 = 1;
+ ai1 = 0;
+ int idx0 = (ip - 1) * idl1;
+ for (int l = 1; l < ipph; l++) {
+ lc = ip - l;
+ ar1h = dcp * ar1 - dsp * ai1;
+ ai1 = dcp * ai1 + dsp * ar1;
+ ar1 = ar1h;
+ int idx1 = l * idl1;
+ int idx2 = lc * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx3 = out_off + ik;
+ int idx4 = in_off + ik;
+ out[idx3 + idx1] = in[idx4] + ar1 * in[idx4 + idl1];
+ out[idx3 + idx2] = ai1 * in[idx4 + idx0];
+ }
+ dc2 = ar1;
+ ds2 = ai1;
+ ar2 = ar1;
+ ai2 = ai1;
+ for (int j = 2; j < ipph; j++) {
+ jc = ip - j;
+ ar2h = dc2 * ar2 - ds2 * ai2;
+ ai2 = dc2 * ai2 + ds2 * ar2;
+ ar2 = ar2h;
+ int idx3 = j * idl1;
+ int idx4 = jc * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx5 = out_off + ik;
+ int idx6 = in_off + ik;
+ out[idx5 + idx1] += ar2 * in[idx6 + idx3];
+ out[idx5 + idx2] += ai2 * in[idx6 + idx4];
+ }
+ }
+ }
+ for (int j = 1; j < ipph; j++) {
+ int idx1 = j * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ out[out_off + ik] += in[in_off + ik + idx1];
+ }
+ }
+
+ if (ido >= l1) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = idx1 * ip;
+ for (int i = 0; i < ido; i++) {
+ in[in_off + i + idx2] = out[out_off + i + idx1];
+ }
+ }
+ } else {
+ for (int i = 0; i < ido; i++) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ in[in_off + i + idx1 * ip] = out[out_off + i + idx1];
+ }
+ }
+ }
+ int idx01 = ip * ido;
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = j2 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * ido;
+ int idx5 = idx4 + idx1;
+ int idx6 = idx4 + idx2;
+ int idx7 = k * idx01;
+ in[in_off + ido - 1 + idx3 - ido + idx7] = out[out_off + idx5];
+ in[in_off + idx3 + idx7] = out[out_off + idx6];
+ }
+ }
+ if (ido == 1) {
+ return;
+ }
+ if (nbd >= l1) {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = j2 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * idx01;
+ int idx5 = k * ido;
+ for (int i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx6 = in_off + i;
+ int idx7 = in_off + ic;
+ int idx8 = out_off + i;
+ int iidx1 = idx6 + idx3 + idx4;
+ int iidx2 = idx7 + idx3 - ido + idx4;
+ int oidx1 = idx8 + idx5 + idx1;
+ int oidx2 = idx8 + idx5 + idx2;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ float o2i = out[oidx2 - 1];
+ float o2r = out[oidx2];
+
+ in[iidx1 - 1] = o1i + o2i;
+ in[iidx2 - 1] = o1i - o2i;
+ in[iidx1] = o1r + o2r;
+ in[iidx2] = o2r - o1r;
+ }
+ }
+ }
+ } else {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = j2 * ido;
+ for (int i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx6 = in_off + i;
+ int idx7 = in_off + ic;
+ int idx8 = out_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * idx01;
+ int idx5 = k * ido;
+ int iidx1 = idx6 + idx3 + idx4;
+ int iidx2 = idx7 + idx3 - ido + idx4;
+ int oidx1 = idx8 + idx5 + idx1;
+ int oidx2 = idx8 + idx5 + idx2;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ float o2i = out[oidx2 - 1];
+ float o2r = out[oidx2];
+
+ in[iidx1 - 1] = o1i + o2i;
+ in[iidx2 - 1] = o1i - o2i;
+ in[iidx1] = o1r + o2r;
+ in[iidx2] = o2r - o1r;
+ }
+ }
+ }
+ }
+ }
+
+ /*---------------------------------------------------------
+ radfg: Real FFT's forward processing of general factor
+ --------------------------------------------------------*/
+/*
+ void radfg(final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ long idij, ipph, j2, ic, jc, lc, is, nbd;
+ float dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
+ long iw1 = offset;
+
+ arg = TWO_PI / (float) ip;
+ dcp = (float)Math.cos(arg);
+ dsp = (float)Math.sin(arg);
+ ipph = (ip + 1) / 2;
+ nbd = (ido - 1) / 2;
+ if (ido != 1) {
+ for (long ik = 0; ik < idl1; ik++) {
+ out.setFloat(out_off + ik, in.getFloat(in_off + ik));
+ }
+ for (long j = 1; j < ip; j++) {
+ long idx1 = j * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx2 = k * ido + idx1;
+ out.setFloat(out_off + idx2, in.getFloat(in_off + idx2));
+ }
+ }
+ if (nbd <= l1) {
+ is = -ido;
+ for (long j = 1; j < ip; j++) {
+ is += ido;
+ idij = is - 1;
+ long idx1 = j * l1 * ido;
+ for (long i = 2; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij + iw1;
+ long idx4 = in_off + i;
+ long idx5 = out_off + i;
+ w1r = wtable_rl.getFloat(idx2 - 1);
+ w1i = wtable_rl.getFloat(idx2);
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido + idx1;
+ long oidx1 = idx5 + idx3;
+ long iidx1 = idx4 + idx3;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+
+ out.setFloat(oidx1 - 1, w1r * i1i + w1i * i1r);
+ out.setFloat(oidx1, w1r * i1r - w1i * i1i);
+ }
+ }
+ }
+ } else {
+ is = -ido;
+ for (long j = 1; j < ip; j++) {
+ is += ido;
+ long idx1 = j * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ idij = is - 1;
+ long idx3 = k * ido + idx1;
+ for (long i = 2; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij + iw1;
+ w1r = wtable_rl.getFloat(idx2 - 1);
+ w1i = wtable_rl.getFloat(idx2);
+ long oidx1 = out_off + i + idx3;
+ long iidx1 = in_off + i + idx3;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+
+ out.setFloat(oidx1 - 1, w1r * i1i + w1i * i1r);
+ out.setFloat(oidx1, w1r * i1r - w1i * i1i);
+ }
+ }
+ }
+ }
+ if (nbd >= l1) {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido + idx1;
+ long idx4 = k * ido + idx2;
+ for (long i = 2; i < ido; i += 2) {
+ long idx5 = in_off + i;
+ long idx6 = out_off + i;
+ long iidx1 = idx5 + idx3;
+ long iidx2 = idx5 + idx4;
+ long oidx1 = idx6 + idx3;
+ long oidx2 = idx6 + idx4;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ float o2i = out.getFloat(oidx2 - 1);
+ float o2r = out.getFloat(oidx2);
+
+ in.setFloat(iidx1 - 1, o1i + o2i);
+ in.setFloat(iidx1, o1r + o2r);
+
+ in.setFloat(iidx2 - 1, o1r - o2r);
+ in.setFloat(iidx2, o2i - o1i);
+ }
+ }
+ }
+ } else {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long i = 2; i < ido; i += 2) {
+ long idx5 = in_off + i;
+ long idx6 = out_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido + idx1;
+ long idx4 = k * ido + idx2;
+ long iidx1 = idx5 + idx3;
+ long iidx2 = idx5 + idx4;
+ long oidx1 = idx6 + idx3;
+ long oidx2 = idx6 + idx4;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ float o2i = out.getFloat(oidx2 - 1);
+ float o2r = out.getFloat(oidx2);
+
+ in.setFloat(iidx1 - 1, o1i + o2i);
+ in.setFloat(iidx1, o1r + o2r);
+ in.setFloat(iidx2 - 1, o1r - o2r);
+ in.setFloat(iidx2, o2i - o1i);
+ }
+ }
+ }
+ }
+ } else {
+ Utilities.arraycopy(out, out_off, in, in_off, idl1);
+ }
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido + idx1;
+ long idx4 = k * ido + idx2;
+ long oidx1 = out_off + idx3;
+ long oidx2 = out_off + idx4;
+ float o1r = out.getFloat(oidx1);
+ float o2r = out.getFloat(oidx2);
+
+ in.setFloat(in_off + idx3, o1r + o2r);
+ in.setFloat(in_off + idx4, o2r - o1r);
+ }
+ }
+
+ ar1 = 1;
+ ai1 = 0;
+ long idx0 = (ip - 1) * idl1;
+ for (long l = 1; l < ipph; l++) {
+ lc = ip - l;
+ ar1h = dcp * ar1 - dsp * ai1;
+ ai1 = dcp * ai1 + dsp * ar1;
+ ar1 = ar1h;
+ long idx1 = l * idl1;
+ long idx2 = lc * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx3 = out_off + ik;
+ long idx4 = in_off + ik;
+ out.setFloat(idx3 + idx1, in.getFloat(idx4) + ar1 * in.getFloat(idx4 + idl1));
+ out.setFloat(idx3 + idx2, ai1 * in.getFloat(idx4 + idx0));
+ }
+ dc2 = ar1;
+ ds2 = ai1;
+ ar2 = ar1;
+ ai2 = ai1;
+ for (long j = 2; j < ipph; j++) {
+ jc = ip - j;
+ ar2h = dc2 * ar2 - ds2 * ai2;
+ ai2 = dc2 * ai2 + ds2 * ar2;
+ ar2 = ar2h;
+ long idx3 = j * idl1;
+ long idx4 = jc * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx5 = out_off + ik;
+ long idx6 = in_off + ik;
+ out.setFloat(idx5 + idx1, out.getFloat(idx5 + idx1) + ar2 * in.getFloat(idx6 + idx3));
+ out.setFloat(idx5 + idx2, out.getFloat(idx5 + idx2) + ai2 * in.getFloat(idx6 + idx4));
+ }
+ }
+ }
+ for (long j = 1; j < ipph; j++) {
+ long idx1 = j * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ out.setFloat(out_off + ik, out.getFloat(out_off + ik) + in.getFloat(in_off + ik + idx1));
+ }
+ }
+
+ if (ido >= l1) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = idx1 * ip;
+ for (long i = 0; i < ido; i++) {
+ in.setFloat(in_off + i + idx2, out.getFloat(out_off + i + idx1));
+ }
+ }
+ } else {
+ for (long i = 0; i < ido; i++) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ in.setFloat(in_off + i + idx1 * ip, out.getFloat(out_off + i + idx1));
+ }
+ }
+ }
+ long idx01 = ip * ido;
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = j2 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * ido;
+ long idx5 = idx4 + idx1;
+ long idx6 = idx4 + idx2;
+ long idx7 = k * idx01;
+ in.setFloat(in_off + ido - 1 + idx3 - ido + idx7, out.getFloat(out_off + idx5));
+ in.setFloat(in_off + idx3 + idx7, out.getFloat(out_off + idx6));
+ }
+ }
+ if (ido == 1) {
+ return;
+ }
+ if (nbd >= l1) {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = j2 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * idx01;
+ long idx5 = k * ido;
+ for (long i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx6 = in_off + i;
+ long idx7 = in_off + ic;
+ long idx8 = out_off + i;
+ long iidx1 = idx6 + idx3 + idx4;
+ long iidx2 = idx7 + idx3 - ido + idx4;
+ long oidx1 = idx8 + idx5 + idx1;
+ long oidx2 = idx8 + idx5 + idx2;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ float o2i = out.getFloat(oidx2 - 1);
+ float o2r = out.getFloat(oidx2);
+
+ in.setFloat(iidx1 - 1, o1i + o2i);
+ in.setFloat(iidx2 - 1, o1i - o2i);
+ in.setFloat(iidx1, o1r + o2r);
+ in.setFloat(iidx2, o2r - o1r);
+ }
+ }
+ }
+ } else {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = j2 * ido;
+ for (long i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx6 = in_off + i;
+ long idx7 = in_off + ic;
+ long idx8 = out_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * idx01;
+ long idx5 = k * ido;
+ long iidx1 = idx6 + idx3 + idx4;
+ long iidx2 = idx7 + idx3 - ido + idx4;
+ long oidx1 = idx8 + idx5 + idx1;
+ long oidx2 = idx8 + idx5 + idx2;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ float o2i = out.getFloat(oidx2 - 1);
+ float o2r = out.getFloat(oidx2);
+
+ in.setFloat(iidx1 - 1, o1i + o2i);
+ in.setFloat(iidx2 - 1, o1i - o2i);
+ in.setFloat(iidx1, o1r + o2r);
+ in.setFloat(iidx2, o2r - o1r);
+ }
+ }
+ }
+ }
+ }
+*/
+ /*---------------------------------------------------------
+ radbg: Real FFT's backward processing of general factor
+ --------------------------------------------------------*/
+ void radbg(final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset) {
+ int idij, ipph, j2, ic, jc, lc, is;
+ float dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
+ int nbd;
+ float dcp, arg, dsp, ar1h, ar2h;
+ int iw1 = offset;
+
+ arg = TWO_PI / (float) ip;
+ dcp = (float)Math.cos(arg);
+ dsp = (float)Math.sin(arg);
+ nbd = (ido - 1) / 2;
+ ipph = (ip + 1) / 2;
+ int idx0 = ip * ido;
+ if (ido >= l1) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = k * idx0;
+ for (int i = 0; i < ido; i++) {
+ out[out_off + i + idx1] = in[in_off + i + idx2];
+ }
+ }
+ } else {
+ for (int i = 0; i < ido; i++) {
+ int idx1 = out_off + i;
+ int idx2 = in_off + i;
+ for (int k = 0; k < l1; k++) {
+ out[idx1 + k * ido] = in[idx2 + k * idx0];
+ }
+ }
+ }
+ int iidx0 = in_off + ido - 1;
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = j2 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * ido;
+ int idx5 = idx4 * ip;
+ int iidx1 = iidx0 + idx3 + idx5 - ido;
+ int iidx2 = in_off + idx3 + idx5;
+ float i1r = in[iidx1];
+ float i2r = in[iidx2];
+
+ out[out_off + idx4 + idx1] = i1r + i1r;
+ out[out_off + idx4 + idx2] = i2r + i2r;
+ }
+ }
+
+ if (ido != 1) {
+ if (nbd >= l1) {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = 2 * j * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * ido + idx1;
+ int idx5 = k * ido + idx2;
+ int idx6 = k * ip * ido + idx3;
+ for (int i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx7 = out_off + i;
+ int idx8 = in_off + ic;
+ int idx9 = in_off + i;
+ int oidx1 = idx7 + idx4;
+ int oidx2 = idx7 + idx5;
+ int iidx1 = idx9 + idx6;
+ int iidx2 = idx8 + idx6 - ido;
+ float a1i = in[iidx1 - 1];
+ float a1r = in[iidx1];
+ float a2i = in[iidx2 - 1];
+ float a2r = in[iidx2];
+
+ out[oidx1 - 1] = a1i + a2i;
+ out[oidx2 - 1] = a1i - a2i;
+ out[oidx1] = a1r - a2r;
+ out[oidx2] = a1r + a2r;
+ }
+ }
+ }
+ } else {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ int idx3 = 2 * j * ido;
+ for (int i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ int idx7 = out_off + i;
+ int idx8 = in_off + ic;
+ int idx9 = in_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx4 = k * ido + idx1;
+ int idx5 = k * ido + idx2;
+ int idx6 = k * ip * ido + idx3;
+ int oidx1 = idx7 + idx4;
+ int oidx2 = idx7 + idx5;
+ int iidx1 = idx9 + idx6;
+ int iidx2 = idx8 + idx6 - ido;
+ float a1i = in[iidx1 - 1];
+ float a1r = in[iidx1];
+ float a2i = in[iidx2 - 1];
+ float a2r = in[iidx2];
+
+ out[oidx1 - 1] = a1i + a2i;
+ out[oidx2 - 1] = a1i - a2i;
+ out[oidx1] = a1r - a2r;
+ out[oidx2] = a1r + a2r;
+ }
+ }
+ }
+ }
+ }
+
+ ar1 = 1;
+ ai1 = 0;
+ int idx01 = (ip - 1) * idl1;
+ for (int l = 1; l < ipph; l++) {
+ lc = ip - l;
+ ar1h = dcp * ar1 - dsp * ai1;
+ ai1 = dcp * ai1 + dsp * ar1;
+ ar1 = ar1h;
+ int idx1 = l * idl1;
+ int idx2 = lc * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx3 = in_off + ik;
+ int idx4 = out_off + ik;
+ in[idx3 + idx1] = out[idx4] + ar1 * out[idx4 + idl1];
+ in[idx3 + idx2] = ai1 * out[idx4 + idx01];
+ }
+ dc2 = ar1;
+ ds2 = ai1;
+ ar2 = ar1;
+ ai2 = ai1;
+ for (int j = 2; j < ipph; j++) {
+ jc = ip - j;
+ ar2h = dc2 * ar2 - ds2 * ai2;
+ ai2 = dc2 * ai2 + ds2 * ar2;
+ ar2 = ar2h;
+ int idx5 = j * idl1;
+ int idx6 = jc * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx7 = in_off + ik;
+ int idx8 = out_off + ik;
+ in[idx7 + idx1] += ar2 * out[idx8 + idx5];
+ in[idx7 + idx2] += ai2 * out[idx8 + idx6];
+ }
+ }
+ }
+ for (int j = 1; j < ipph; j++) {
+ int idx1 = j * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx2 = out_off + ik;
+ out[idx2] += out[idx2 + idx1];
+ }
+ }
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido;
+ int oidx1 = out_off + idx3;
+ int iidx1 = in_off + idx3 + idx1;
+ int iidx2 = in_off + idx3 + idx2;
+ float i1r = in[iidx1];
+ float i2r = in[iidx2];
+
+ out[oidx1 + idx1] = i1r - i2r;
+ out[oidx1 + idx2] = i1r + i2r;
+ }
+ }
+
+ if (ido == 1) {
+ return;
+ }
+ if (nbd >= l1) {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido;
+ for (int i = 2; i < ido; i += 2) {
+ int idx4 = out_off + i;
+ int idx5 = in_off + i;
+ int oidx1 = idx4 + idx3 + idx1;
+ int oidx2 = idx4 + idx3 + idx2;
+ int iidx1 = idx5 + idx3 + idx1;
+ int iidx2 = idx5 + idx3 + idx2;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+
+ out[oidx1 - 1] = i1i - i2r;
+ out[oidx2 - 1] = i1i + i2r;
+ out[oidx1] = i1r + i2i;
+ out[oidx2] = i1r - i2i;
+ }
+ }
+ }
+ } else {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * l1 * ido;
+ int idx2 = jc * l1 * ido;
+ for (int i = 2; i < ido; i += 2) {
+ int idx4 = out_off + i;
+ int idx5 = in_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido;
+ int oidx1 = idx4 + idx3 + idx1;
+ int oidx2 = idx4 + idx3 + idx2;
+ int iidx1 = idx5 + idx3 + idx1;
+ int iidx2 = idx5 + idx3 + idx2;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+
+ out[oidx1 - 1] = i1i - i2r;
+ out[oidx2 - 1] = i1i + i2r;
+ out[oidx1] = i1r + i2i;
+ out[oidx2] = i1r - i2i;
+ }
+ }
+ }
+ }
+ System.arraycopy(out, out_off, in, in_off, idl1);
+ for (int j = 1; j < ip; j++) {
+ int idx1 = j * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx2 = k * ido + idx1;
+ in[in_off + idx2] = out[out_off + idx2];
+ }
+ }
+ if (nbd <= l1) {
+ is = -ido;
+ for (int j = 1; j < ip; j++) {
+ is += ido;
+ idij = is - 1;
+ int idx1 = j * l1 * ido;
+ for (int i = 2; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij + iw1;
+ w1r = wtable_r[idx2 - 1];
+ w1i = wtable_r[idx2];
+ int idx4 = in_off + i;
+ int idx5 = out_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido + idx1;
+ int iidx1 = idx4 + idx3;
+ int oidx1 = idx5 + idx3;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+
+ in[iidx1 - 1] = w1r * o1i - w1i * o1r;
+ in[iidx1] = w1r * o1r + w1i * o1i;
+ }
+ }
+ }
+ } else {
+ is = -ido;
+ for (int j = 1; j < ip; j++) {
+ is += ido;
+ int idx1 = j * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ idij = is - 1;
+ int idx3 = k * ido + idx1;
+ for (int i = 2; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij + iw1;
+ w1r = wtable_r[idx2 - 1];
+ w1i = wtable_r[idx2];
+ int idx4 = in_off + i;
+ int idx5 = out_off + i;
+ int iidx1 = idx4 + idx3;
+ int oidx1 = idx5 + idx3;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+
+ in[iidx1 - 1] = w1r * o1i - w1i * o1r;
+ in[iidx1] = w1r * o1r + w1i * o1i;
+
+ }
+ }
+ }
+ }
+ }
+
+ /*---------------------------------------------------------
+ radbg: Real FFT's backward processing of general factor
+ --------------------------------------------------------*/
+/*
+ void radbg(final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset) {
+ long idij, ipph, j2, ic, jc, lc, is;
+ float dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
+ long nbd;
+ float dcp, arg, dsp, ar1h, ar2h;
+ long iw1 = offset;
+
+ arg = TWO_PI / (float) ip;
+ dcp = (float)Math.cos(arg);
+ dsp = (float)Math.sin(arg);
+ nbd = (ido - 1) / 2;
+ ipph = (ip + 1) / 2;
+ long idx0 = ip * ido;
+ if (ido >= l1) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = k * idx0;
+ for (long i = 0; i < ido; i++) {
+ out.setFloat(out_off + i + idx1, in.getFloat(in_off + i + idx2));
+ }
+ }
+ } else {
+ for (long i = 0; i < ido; i++) {
+ long idx1 = out_off + i;
+ long idx2 = in_off + i;
+ for (long k = 0; k < l1; k++) {
+ out.setFloat(idx1 + k * ido, in.getFloat(idx2 + k * idx0));
+ }
+ }
+ }
+ long iidx0 = in_off + ido - 1;
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ j2 = 2 * j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = j2 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * ido;
+ long idx5 = idx4 * ip;
+ long iidx1 = iidx0 + idx3 + idx5 - ido;
+ long iidx2 = in_off + idx3 + idx5;
+ float i1r = in.getFloat(iidx1);
+ float i2r = in.getFloat(iidx2);
+
+ out.setFloat(out_off + idx4 + idx1, i1r + i1r);
+ out.setFloat(out_off + idx4 + idx2, i2r + i2r);
+ }
+ }
+
+ if (ido != 1) {
+ if (nbd >= l1) {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = 2 * j * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * ido + idx1;
+ long idx5 = k * ido + idx2;
+ long idx6 = k * ip * ido + idx3;
+ for (long i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx7 = out_off + i;
+ long idx8 = in_off + ic;
+ long idx9 = in_off + i;
+ long oidx1 = idx7 + idx4;
+ long oidx2 = idx7 + idx5;
+ long iidx1 = idx9 + idx6;
+ long iidx2 = idx8 + idx6 - ido;
+ float a1i = in.getFloat(iidx1 - 1);
+ float a1r = in.getFloat(iidx1);
+ float a2i = in.getFloat(iidx2 - 1);
+ float a2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1 - 1, a1i + a2i);
+ out.setFloat(oidx2 - 1, a1i - a2i);
+ out.setFloat(oidx1, a1r - a2r);
+ out.setFloat(oidx2, a1r + a2r);
+ }
+ }
+ }
+ } else {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ long idx3 = 2 * j * ido;
+ for (long i = 2; i < ido; i += 2) {
+ ic = ido - i;
+ long idx7 = out_off + i;
+ long idx8 = in_off + ic;
+ long idx9 = in_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx4 = k * ido + idx1;
+ long idx5 = k * ido + idx2;
+ long idx6 = k * ip * ido + idx3;
+ long oidx1 = idx7 + idx4;
+ long oidx2 = idx7 + idx5;
+ long iidx1 = idx9 + idx6;
+ long iidx2 = idx8 + idx6 - ido;
+ float a1i = in.getFloat(iidx1 - 1);
+ float a1r = in.getFloat(iidx1);
+ float a2i = in.getFloat(iidx2 - 1);
+ float a2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1 - 1, a1i + a2i);
+ out.setFloat(oidx2 - 1, a1i - a2i);
+ out.setFloat(oidx1, a1r - a2r);
+ out.setFloat(oidx2, a1r + a2r);
+ }
+ }
+ }
+ }
+ }
+
+ ar1 = 1;
+ ai1 = 0;
+ long idx01 = (ip - 1) * idl1;
+ for (long l = 1; l < ipph; l++) {
+ lc = ip - l;
+ ar1h = dcp * ar1 - dsp * ai1;
+ ai1 = dcp * ai1 + dsp * ar1;
+ ar1 = ar1h;
+ long idx1 = l * idl1;
+ long idx2 = lc * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx3 = in_off + ik;
+ long idx4 = out_off + ik;
+ in.setFloat(idx3 + idx1, out.getFloat(idx4) + ar1 * out.getFloat(idx4 + idl1));
+ in.setFloat(idx3 + idx2, ai1 * out.getFloat(idx4 + idx01));
+ }
+ dc2 = ar1;
+ ds2 = ai1;
+ ar2 = ar1;
+ ai2 = ai1;
+ for (long j = 2; j < ipph; j++) {
+ jc = ip - j;
+ ar2h = dc2 * ar2 - ds2 * ai2;
+ ai2 = dc2 * ai2 + ds2 * ar2;
+ ar2 = ar2h;
+ long idx5 = j * idl1;
+ long idx6 = jc * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx7 = in_off + ik;
+ long idx8 = out_off + ik;
+ in.setFloat(idx7 + idx1, in.getFloat(idx7 + idx1) + ar2 * out.getFloat(idx8 + idx5));
+ in.setFloat(idx7 + idx2, in.getFloat(idx7 + idx2) + ai2 * out.getFloat(idx8 + idx6));
+ }
+ }
+ }
+ for (long j = 1; j < ipph; j++) {
+ long idx1 = j * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx2 = out_off + ik;
+ out.setFloat(idx2, out.getFloat(idx2) + out.getFloat(idx2 + idx1));
+ }
+ }
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido;
+ long oidx1 = out_off + idx3;
+ long iidx1 = in_off + idx3 + idx1;
+ long iidx2 = in_off + idx3 + idx2;
+ float i1r = in.getFloat(iidx1);
+ float i2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1 + idx1, i1r - i2r);
+ out.setFloat(oidx1 + idx2, i1r + i2r);
+ }
+ }
+
+ if (ido == 1) {
+ return;
+ }
+ if (nbd >= l1) {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido;
+ for (long i = 2; i < ido; i += 2) {
+ long idx4 = out_off + i;
+ long idx5 = in_off + i;
+ long oidx1 = idx4 + idx3 + idx1;
+ long oidx2 = idx4 + idx3 + idx2;
+ long iidx1 = idx5 + idx3 + idx1;
+ long iidx2 = idx5 + idx3 + idx2;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1 - 1, i1i - i2r);
+ out.setFloat(oidx2 - 1, i1i + i2r);
+ out.setFloat(oidx1, i1r + i2i);
+ out.setFloat(oidx2, i1r - i2i);
+ }
+ }
+ }
+ } else {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * l1 * ido;
+ long idx2 = jc * l1 * ido;
+ for (long i = 2; i < ido; i += 2) {
+ long idx4 = out_off + i;
+ long idx5 = in_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido;
+ long oidx1 = idx4 + idx3 + idx1;
+ long oidx2 = idx4 + idx3 + idx2;
+ long iidx1 = idx5 + idx3 + idx1;
+ long iidx2 = idx5 + idx3 + idx2;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+
+ out.setFloat(oidx1 - 1, i1i - i2r);
+ out.setFloat(oidx2 - 1, i1i + i2r);
+ out.setFloat(oidx1, i1r + i2i);
+ out.setFloat(oidx2, i1r - i2i);
+ }
+ }
+ }
+ }
+ Utilities.arraycopy(out, out_off, in, in_off, idl1);
+ for (long j = 1; j < ip; j++) {
+ long idx1 = j * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx2 = k * ido + idx1;
+ in.setFloat(in_off + idx2, out.getFloat(out_off + idx2));
+ }
+ }
+ if (nbd <= l1) {
+ is = -ido;
+ for (long j = 1; j < ip; j++) {
+ is += ido;
+ idij = is - 1;
+ long idx1 = j * l1 * ido;
+ for (long i = 2; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij + iw1;
+ w1r = wtable_rl.getFloat(idx2 - 1);
+ w1i = wtable_rl.getFloat(idx2);
+ long idx4 = in_off + i;
+ long idx5 = out_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido + idx1;
+ long iidx1 = idx4 + idx3;
+ long oidx1 = idx5 + idx3;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+
+ in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
+ in.setFloat(iidx1, w1r * o1r + w1i * o1i);
+ }
+ }
+ }
+ } else {
+ is = -ido;
+ for (long j = 1; j < ip; j++) {
+ is += ido;
+ long idx1 = j * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ idij = is - 1;
+ long idx3 = k * ido + idx1;
+ for (long i = 2; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij + iw1;
+ w1r = wtable_rl.getFloat(idx2 - 1);
+ w1i = wtable_rl.getFloat(idx2);
+ long idx4 = in_off + i;
+ long idx5 = out_off + i;
+ long iidx1 = idx4 + idx3;
+ long oidx1 = idx5 + idx3;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+
+ in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
+ in.setFloat(iidx1, w1r * o1r + w1i * o1i);
+
+ }
+ }
+ }
+ }
+ }
+*/
+ /*---------------------------------------------------------
+ cfftf1: further processing of Complex forward FFT
+ --------------------------------------------------------*/
+ void cfftf(float a[], int offa, int isign) {
+ int idot;
+ int l1, l2;
+ int na, nf, ipll, iw, ido, idl1;
+ int[] nac = new int[1];
+ final int twon = 2 * n;
+
+ int iw1, iw2;
+ float[] ch = new float[twon];
+
+ iw1 = twon;
+ iw2 = 4 * n;
+ nac[0] = 0;
+ nf = (int) wtable[1 + iw2];
+ na = 0;
+ l1 = 1;
+ iw = iw1;
+ for (int k1 = 2; k1 <= nf + 1; k1++) {
+ ipll = (int) wtable[k1 + iw2];
+ l2 = ipll * l1;
+ ido = n / l2;
+ idot = ido + ido;
+ idl1 = idot * l1;
+ switch (ipll) {
+ case 4:
+ if (na == 0) {
+ passf4(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf4(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 2:
+ if (na == 0) {
+ passf2(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf2(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 3:
+ if (na == 0) {
+ passf3(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf3(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 5:
+ if (na == 0) {
+ passf5(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf5(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ default:
+ if (na == 0) {
+ passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
+ } else {
+ passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
+ }
+ if (nac[0] != 0) {
+ na = 1 - na;
+ }
+ break;
+ }
+ l1 = l2;
+ iw += (ipll - 1) * idot;
+ }
+ if (na == 0) {
+ return;
+ }
+ System.arraycopy(ch, 0, a, offa, twon);
+
+ }
+
+ /*---------------------------------------------------------
+ cfftf1: further processing of Complex forward FFT
+ --------------------------------------------------------*/
+/*
+ void cfftf(FloatLargeArray a, long offa, int isign) {
+ long idot;
+ long l1, l2;
+ long na, nf, iw, ido, idl1;
+ int[] nac = new int[1];
+ final long twon = 2 * nl;
+ int ipll;
+
+ long iw1, iw2;
+ FloatLargeArray ch = new FloatLargeArray(twon, false);
+
+ iw1 = twon;
+ iw2 = 4 * nl;
+ nac[0] = 0;
+ nf = (long) wtablel.getFloat(1 + iw2);
+ na = 0;
+ l1 = 1;
+ iw = iw1;
+ for (long k1 = 2; k1 <= nf + 1; k1++) {
+ ipll = (int) wtablel.getFloat(k1 + iw2);
+ l2 = ipll * l1;
+ ido = nl / l2;
+ idot = ido + ido;
+ idl1 = idot * l1;
+ switch (ipll) {
+ case 4:
+ if (na == 0) {
+ passf4(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf4(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 2:
+ if (na == 0) {
+ passf2(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf2(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 3:
+ if (na == 0) {
+ passf3(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf3(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ case 5:
+ if (na == 0) {
+ passf5(idot, l1, a, offa, ch, 0, iw, isign);
+ } else {
+ passf5(idot, l1, ch, 0, a, offa, iw, isign);
+ }
+ na = 1 - na;
+ break;
+ default:
+ if (na == 0) {
+ passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
+ } else {
+ passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
+ }
+ if (nac[0] != 0) {
+ na = 1 - na;
+ }
+ break;
+ }
+ l1 = l2;
+ iw += (ipll - 1) * idot;
+ }
+ if (na == 0) {
+ return;
+ }
+ Utilities.arraycopy(ch, 0, a, offa, twon);
+
+ }
+*/
+ /*----------------------------------------------------------------------
+ passf2: Complex FFT's forward/backward processing of factor 2;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+ void passf2(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
+ float t1i, t1r;
+ int iw1;
+ iw1 = offset;
+ int idx = ido * l1;
+ if (ido <= 2) {
+ for (int k = 0; k < l1; k++) {
+ int idx0 = k * ido;
+ int iidx1 = in_off + 2 * idx0;
+ int iidx2 = iidx1 + ido;
+ float a1r = in[iidx1];
+ float a1i = in[iidx1 + 1];
+ float a2r = in[iidx2];
+ float a2i = in[iidx2 + 1];
+
+ int oidx1 = out_off + idx0;
+ int oidx2 = oidx1 + idx;
+ out[oidx1] = a1r + a2r;
+ out[oidx1 + 1] = a1i + a2i;
+ out[oidx2] = a1r - a2r;
+ out[oidx2 + 1] = a1i - a2i;
+ }
+ } else {
+ for (int k = 0; k < l1; k++) {
+ for (int i = 0; i < ido - 1; i += 2) {
+ int idx0 = k * ido;
+ int iidx1 = in_off + i + 2 * idx0;
+ int iidx2 = iidx1 + ido;
+ float i1r = in[iidx1];
+ float i1i = in[iidx1 + 1];
+ float i2r = in[iidx2];
+ float i2i = in[iidx2 + 1];
+
+ int widx1 = i + iw1;
+ float w1r = wtable[widx1];
+ float w1i = isign * wtable[widx1 + 1];
+
+ t1r = i1r - i2r;
+ t1i = i1i - i2i;
+
+ int oidx1 = out_off + i + idx0;
+ int oidx2 = oidx1 + idx;
+ out[oidx1] = i1r + i2r;
+ out[oidx1 + 1] = i1i + i2i;
+ out[oidx2] = w1r * t1r - w1i * t1i;
+ out[oidx2 + 1] = w1r * t1i + w1i * t1r;
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ passf2: Complex FFT's forward/backward processing of factor 2;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+/*
+ void passf2(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
+ float t1i, t1r;
+ long iw1;
+ iw1 = offset;
+ long idx = ido * l1;
+ if (ido <= 2) {
+ for (long k = 0; k < l1; k++) {
+ long idx0 = k * ido;
+ long iidx1 = in_off + 2 * idx0;
+ long iidx2 = iidx1 + ido;
+ float a1r = in.getFloat(iidx1);
+ float a1i = in.getFloat(iidx1 + 1);
+ float a2r = in.getFloat(iidx2);
+ float a2i = in.getFloat(iidx2 + 1);
+
+ long oidx1 = out_off + idx0;
+ long oidx2 = oidx1 + idx;
+ out.setFloat(oidx1, a1r + a2r);
+ out.setFloat(oidx1 + 1, a1i + a2i);
+ out.setFloat(oidx2, a1r - a2r);
+ out.setFloat(oidx2 + 1, a1i - a2i);
+ }
+ } else {
+ for (long k = 0; k < l1; k++) {
+ for (long i = 0; i < ido - 1; i += 2) {
+ long idx0 = k * ido;
+ long iidx1 = in_off + i + 2 * idx0;
+ long iidx2 = iidx1 + ido;
+ float i1r = in.getFloat(iidx1);
+ float i1i = in.getFloat(iidx1 + 1);
+ float i2r = in.getFloat(iidx2);
+ float i2i = in.getFloat(iidx2 + 1);
+
+ long widx1 = i + iw1;
+ float w1r = wtablel.getFloat(widx1);
+ float w1i = isign * wtablel.getFloat(widx1 + 1);
+
+ t1r = i1r - i2r;
+ t1i = i1i - i2i;
+
+ long oidx1 = out_off + i + idx0;
+ long oidx2 = oidx1 + idx;
+ out.setFloat(oidx1, i1r + i2r);
+ out.setFloat(oidx1 + 1, i1i + i2i);
+ out.setFloat(oidx2, w1r * t1r - w1i * t1i);
+ out.setFloat(oidx2 + 1, w1r * t1i + w1i * t1r);
+ }
+ }
+ }
+ }
+*/
+ /*----------------------------------------------------------------------
+ passf3: Complex FFT's forward/backward processing of factor 3;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+ void passf3(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+ int iw1, iw2;
+
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ final int idxt = l1 * ido;
+
+ if (ido == 2) {
+ for (int k = 1; k <= l1; k++) {
+ int iidx1 = in_off + (3 * k - 2) * ido;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx1 - ido;
+ float i1r = in[iidx1];
+ float i1i = in[iidx1 + 1];
+ float i2r = in[iidx2];
+ float i2i = in[iidx2 + 1];
+ float i3r = in[iidx3];
+ float i3i = in[iidx3 + 1];
+
+ tr2 = i1r + i2r;
+ cr2 = i3r + taur * tr2;
+ ti2 = i1i + i2i;
+ ci2 = i3i + taur * ti2;
+ cr3 = isign * taui * (i1r - i2r);
+ ci3 = isign * taui * (i1i - i2i);
+
+ int oidx1 = out_off + (k - 1) * ido;
+ int oidx2 = oidx1 + idxt;
+ int oidx3 = oidx2 + idxt;
+ out[oidx1] = in[iidx3] + tr2;
+ out[oidx1 + 1] = i3i + ti2;
+ out[oidx2] = cr2 - ci3;
+ out[oidx2 + 1] = ci2 + cr3;
+ out[oidx3] = cr2 + ci3;
+ out[oidx3 + 1] = ci2 - cr3;
+ }
+ } else {
+ for (int k = 1; k <= l1; k++) {
+ int idx1 = in_off + (3 * k - 2) * ido;
+ int idx2 = out_off + (k - 1) * ido;
+ for (int i = 0; i < ido - 1; i += 2) {
+ int iidx1 = i + idx1;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx1 - ido;
+ float a1r = in[iidx1];
+ float a1i = in[iidx1 + 1];
+ float a2r = in[iidx2];
+ float a2i = in[iidx2 + 1];
+ float a3r = in[iidx3];
+ float a3i = in[iidx3 + 1];
+
+ tr2 = a1r + a2r;
+ cr2 = a3r + taur * tr2;
+ ti2 = a1i + a2i;
+ ci2 = a3i + taur * ti2;
+ cr3 = isign * taui * (a1r - a2r);
+ ci3 = isign * taui * (a1i - a2i);
+ dr2 = cr2 - ci3;
+ dr3 = cr2 + ci3;
+ di2 = ci2 + cr3;
+ di3 = ci2 - cr3;
+
+ int widx1 = i + iw1;
+ int widx2 = i + iw2;
+ float w1r = wtable[widx1];
+ float w1i = isign * wtable[widx1 + 1];
+ float w2r = wtable[widx2];
+ float w2i = isign * wtable[widx2 + 1];
+
+ int oidx1 = i + idx2;
+ int oidx2 = oidx1 + idxt;
+ int oidx3 = oidx2 + idxt;
+ out[oidx1] = a3r + tr2;
+ out[oidx1 + 1] = a3i + ti2;
+ out[oidx2] = w1r * dr2 - w1i * di2;
+ out[oidx2 + 1] = w1r * di2 + w1i * dr2;
+ out[oidx3] = w2r * dr3 - w2i * di3;
+ out[oidx3 + 1] = w2r * di3 + w2i * dr3;
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ passf3: Complex FFT's forward/backward processing of factor 3;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+/*
+ void passf3(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
+ final float taur = -0.5f;
+ final float taui = 0.866025403784438707610604524234076962f;
+ float ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
+ long iw1, iw2;
+
+ iw1 = offset;
+ iw2 = iw1 + ido;
+
+ final long idxt = l1 * ido;
+
+ if (ido == 2) {
+ for (long k = 1; k <= l1; k++) {
+ long iidx1 = in_off + (3 * k - 2) * ido;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx1 - ido;
+ float i1r = in.getFloat(iidx1);
+ float i1i = in.getFloat(iidx1 + 1);
+ float i2r = in.getFloat(iidx2);
+ float i2i = in.getFloat(iidx2 + 1);
+ float i3r = in.getFloat(iidx3);
+ float i3i = in.getFloat(iidx3 + 1);
+
+ tr2 = i1r + i2r;
+ cr2 = i3r + taur * tr2;
+ ti2 = i1i + i2i;
+ ci2 = i3i + taur * ti2;
+ cr3 = isign * taui * (i1r - i2r);
+ ci3 = isign * taui * (i1i - i2i);
+
+ long oidx1 = out_off + (k - 1) * ido;
+ long oidx2 = oidx1 + idxt;
+ long oidx3 = oidx2 + idxt;
+ out.setFloat(oidx1, in.getFloat(iidx3) + tr2);
+ out.setFloat(oidx1 + 1, i3i + ti2);
+ out.setFloat(oidx2, cr2 - ci3);
+ out.setFloat(oidx2 + 1, ci2 + cr3);
+ out.setFloat(oidx3, cr2 + ci3);
+ out.setFloat(oidx3 + 1, ci2 - cr3);
+ }
+ } else {
+ for (long k = 1; k <= l1; k++) {
+ long idx1 = in_off + (3 * k - 2) * ido;
+ long idx2 = out_off + (k - 1) * ido;
+ for (long i = 0; i < ido - 1; i += 2) {
+ long iidx1 = i + idx1;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx1 - ido;
+ float a1r = in.getFloat(iidx1);
+ float a1i = in.getFloat(iidx1 + 1);
+ float a2r = in.getFloat(iidx2);
+ float a2i = in.getFloat(iidx2 + 1);
+ float a3r = in.getFloat(iidx3);
+ float a3i = in.getFloat(iidx3 + 1);
+
+ tr2 = a1r + a2r;
+ cr2 = a3r + taur * tr2;
+ ti2 = a1i + a2i;
+ ci2 = a3i + taur * ti2;
+ cr3 = isign * taui * (a1r - a2r);
+ ci3 = isign * taui * (a1i - a2i);
+ dr2 = cr2 - ci3;
+ dr3 = cr2 + ci3;
+ di2 = ci2 + cr3;
+ di3 = ci2 - cr3;
+
+ long widx1 = i + iw1;
+ long widx2 = i + iw2;
+ float w1r = wtablel.getFloat(widx1);
+ float w1i = isign * wtablel.getFloat(widx1 + 1);
+ float w2r = wtablel.getFloat(widx2);
+ float w2i = isign * wtablel.getFloat(widx2 + 1);
+
+ long oidx1 = i + idx2;
+ long oidx2 = oidx1 + idxt;
+ long oidx3 = oidx2 + idxt;
+ out.setFloat(oidx1, a3r + tr2);
+ out.setFloat(oidx1 + 1, a3i + ti2);
+ out.setFloat(oidx2, w1r * dr2 - w1i * di2);
+ out.setFloat(oidx2 + 1, w1r * di2 + w1i * dr2);
+ out.setFloat(oidx3, w2r * dr3 - w2i * di3);
+ out.setFloat(oidx3 + 1, w2r * di3 + w2i * dr3);
+ }
+ }
+ }
+ }
+*/
+ /*----------------------------------------------------------------------
+ passf4: Complex FFT's forward/backward processing of factor 4;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+ void passf4(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
+ float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
+ int iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+
+ int idx0 = l1 * ido;
+ if (ido == 2) {
+ for (int k = 0; k < l1; k++) {
+ int idxt1 = k * ido;
+ int iidx1 = in_off + 4 * idxt1 + 1;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx2 + ido;
+ int iidx4 = iidx3 + ido;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+
+ ti1 = i1r - i3r;
+ ti2 = i1r + i3r;
+ tr4 = i4r - i2r;
+ ti3 = i2r + i4r;
+ tr1 = i1i - i3i;
+ tr2 = i1i + i3i;
+ ti4 = i2i - i4i;
+ tr3 = i2i + i4i;
+
+ int oidx1 = out_off + idxt1;
+ int oidx2 = oidx1 + idx0;
+ int oidx3 = oidx2 + idx0;
+ int oidx4 = oidx3 + idx0;
+ out[oidx1] = tr2 + tr3;
+ out[oidx1 + 1] = ti2 + ti3;
+ out[oidx2] = tr1 + isign * tr4;
+ out[oidx2 + 1] = ti1 + isign * ti4;
+ out[oidx3] = tr2 - tr3;
+ out[oidx3 + 1] = ti2 - ti3;
+ out[oidx4] = tr1 - isign * tr4;
+ out[oidx4 + 1] = ti1 - isign * ti4;
+ }
+ } else {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = in_off + 1 + 4 * idx1;
+ for (int i = 0; i < ido - 1; i += 2) {
+ int iidx1 = i + idx2;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx2 + ido;
+ int iidx4 = iidx3 + ido;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+
+ ti1 = i1r - i3r;
+ ti2 = i1r + i3r;
+ ti3 = i2r + i4r;
+ tr4 = i4r - i2r;
+ tr1 = i1i - i3i;
+ tr2 = i1i + i3i;
+ ti4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr3 = tr2 - tr3;
+ ci3 = ti2 - ti3;
+ cr2 = tr1 + isign * tr4;
+ cr4 = tr1 - isign * tr4;
+ ci2 = ti1 + isign * ti4;
+ ci4 = ti1 - isign * ti4;
+
+ int widx1 = i + iw1;
+ int widx2 = i + iw2;
+ int widx3 = i + iw3;
+ float w1r = wtable[widx1];
+ float w1i = isign * wtable[widx1 + 1];
+ float w2r = wtable[widx2];
+ float w2i = isign * wtable[widx2 + 1];
+ float w3r = wtable[widx3];
+ float w3i = isign * wtable[widx3 + 1];
+
+ int oidx1 = out_off + i + idx1;
+ int oidx2 = oidx1 + idx0;
+ int oidx3 = oidx2 + idx0;
+ int oidx4 = oidx3 + idx0;
+ out[oidx1] = tr2 + tr3;
+ out[oidx1 + 1] = ti2 + ti3;
+ out[oidx2] = w1r * cr2 - w1i * ci2;
+ out[oidx2 + 1] = w1r * ci2 + w1i * cr2;
+ out[oidx3] = w2r * cr3 - w2i * ci3;
+ out[oidx3 + 1] = w2r * ci3 + w2i * cr3;
+ out[oidx4] = w3r * cr4 - w3i * ci4;
+ out[oidx4 + 1] = w3r * ci4 + w3i * cr4;
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ passf4: Complex FFT's forward/backward processing of factor 4;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+/*
+ void passf4(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final int isign) {
+ float ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
+ long iw1, iw2, iw3;
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+
+ long idx0 = l1 * ido;
+ if (ido == 2) {
+ for (long k = 0; k < l1; k++) {
+ long idxt1 = k * ido;
+ long iidx1 = in_off + 4 * idxt1 + 1;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx2 + ido;
+ long iidx4 = iidx3 + ido;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+
+ ti1 = i1r - i3r;
+ ti2 = i1r + i3r;
+ tr4 = i4r - i2r;
+ ti3 = i2r + i4r;
+ tr1 = i1i - i3i;
+ tr2 = i1i + i3i;
+ ti4 = i2i - i4i;
+ tr3 = i2i + i4i;
+
+ long oidx1 = out_off + idxt1;
+ long oidx2 = oidx1 + idx0;
+ long oidx3 = oidx2 + idx0;
+ long oidx4 = oidx3 + idx0;
+ out.setFloat(oidx1, tr2 + tr3);
+ out.setFloat(oidx1 + 1, ti2 + ti3);
+ out.setFloat(oidx2, tr1 + isign * tr4);
+ out.setFloat(oidx2 + 1, ti1 + isign * ti4);
+ out.setFloat(oidx3, tr2 - tr3);
+ out.setFloat(oidx3 + 1, ti2 - ti3);
+ out.setFloat(oidx4, tr1 - isign * tr4);
+ out.setFloat(oidx4 + 1, ti1 - isign * ti4);
+ }
+ } else {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = in_off + 1 + 4 * idx1;
+ for (long i = 0; i < ido - 1; i += 2) {
+ long iidx1 = i + idx2;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx2 + ido;
+ long iidx4 = iidx3 + ido;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+
+ ti1 = i1r - i3r;
+ ti2 = i1r + i3r;
+ ti3 = i2r + i4r;
+ tr4 = i4r - i2r;
+ tr1 = i1i - i3i;
+ tr2 = i1i + i3i;
+ ti4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr3 = tr2 - tr3;
+ ci3 = ti2 - ti3;
+ cr2 = tr1 + isign * tr4;
+ cr4 = tr1 - isign * tr4;
+ ci2 = ti1 + isign * ti4;
+ ci4 = ti1 - isign * ti4;
+
+ long widx1 = i + iw1;
+ long widx2 = i + iw2;
+ long widx3 = i + iw3;
+ float w1r = wtablel.getFloat(widx1);
+ float w1i = isign * wtablel.getFloat(widx1 + 1);
+ float w2r = wtablel.getFloat(widx2);
+ float w2i = isign * wtablel.getFloat(widx2 + 1);
+ float w3r = wtablel.getFloat(widx3);
+ float w3i = isign * wtablel.getFloat(widx3 + 1);
+
+ long oidx1 = out_off + i + idx1;
+ long oidx2 = oidx1 + idx0;
+ long oidx3 = oidx2 + idx0;
+ long oidx4 = oidx3 + idx0;
+ out.setFloat(oidx1, tr2 + tr3);
+ out.setFloat(oidx1 + 1, ti2 + ti3);
+ out.setFloat(oidx2, w1r * cr2 - w1i * ci2);
+ out.setFloat(oidx2 + 1, w1r * ci2 + w1i * cr2);
+ out.setFloat(oidx3, w2r * cr3 - w2i * ci3);
+ out.setFloat(oidx3 + 1, w2r * ci3 + w2i * cr3);
+ out.setFloat(oidx4, w3r * cr4 - w3i * ci4);
+ out.setFloat(oidx4 + 1, w3r * ci4 + w3i * cr4);
+ }
+ }
+ }
+ }
+*/
+ /*----------------------------------------------------------------------
+ passf5: Complex FFT's forward/backward processing of factor 5;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+ void passf5(final int ido, final int l1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) /* isign==-1 for forward transform and+1 for backward transform */ {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+ int iw1, iw2, iw3, iw4;
+
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ int idx0 = l1 * ido;
+
+ if (ido == 2) {
+ for (int k = 1; k <= l1; ++k) {
+ int iidx1 = in_off + (5 * k - 4) * ido + 1;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx1 - ido;
+ int iidx4 = iidx2 + ido;
+ int iidx5 = iidx4 + ido;
+
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+ float i5i = in[iidx5 - 1];
+ float i5r = in[iidx5];
+
+ ti5 = i1r - i5r;
+ ti2 = i1r + i5r;
+ ti4 = i2r - i4r;
+ ti3 = i2r + i4r;
+ tr5 = i1i - i5i;
+ tr2 = i1i + i5i;
+ tr4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr2 = i3i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i3r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i3i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i3r + tr12 * ti2 + tr11 * ti3;
+ cr5 = isign * (ti11 * tr5 + ti12 * tr4);
+ ci5 = isign * (ti11 * ti5 + ti12 * ti4);
+ cr4 = isign * (ti12 * tr5 - ti11 * tr4);
+ ci4 = isign * (ti12 * ti5 - ti11 * ti4);
+
+ int oidx1 = out_off + (k - 1) * ido;
+ int oidx2 = oidx1 + idx0;
+ int oidx3 = oidx2 + idx0;
+ int oidx4 = oidx3 + idx0;
+ int oidx5 = oidx4 + idx0;
+ out[oidx1] = i3i + tr2 + tr3;
+ out[oidx1 + 1] = i3r + ti2 + ti3;
+ out[oidx2] = cr2 - ci5;
+ out[oidx2 + 1] = ci2 + cr5;
+ out[oidx3] = cr3 - ci4;
+ out[oidx3 + 1] = ci3 + cr4;
+ out[oidx4] = cr3 + ci4;
+ out[oidx4 + 1] = ci3 - cr4;
+ out[oidx5] = cr2 + ci5;
+ out[oidx5 + 1] = ci2 - cr5;
+ }
+ } else {
+ for (int k = 1; k <= l1; k++) {
+ int idx1 = in_off + 1 + (k * 5 - 4) * ido;
+ int idx2 = out_off + (k - 1) * ido;
+ for (int i = 0; i < ido - 1; i += 2) {
+ int iidx1 = i + idx1;
+ int iidx2 = iidx1 + ido;
+ int iidx3 = iidx1 - ido;
+ int iidx4 = iidx2 + ido;
+ int iidx5 = iidx4 + ido;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+ float i3i = in[iidx3 - 1];
+ float i3r = in[iidx3];
+ float i4i = in[iidx4 - 1];
+ float i4r = in[iidx4];
+ float i5i = in[iidx5 - 1];
+ float i5r = in[iidx5];
+
+ ti5 = i1r - i5r;
+ ti2 = i1r + i5r;
+ ti4 = i2r - i4r;
+ ti3 = i2r + i4r;
+ tr5 = i1i - i5i;
+ tr2 = i1i + i5i;
+ tr4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr2 = i3i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i3r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i3i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i3r + tr12 * ti2 + tr11 * ti3;
+ cr5 = isign * (ti11 * tr5 + ti12 * tr4);
+ ci5 = isign * (ti11 * ti5 + ti12 * ti4);
+ cr4 = isign * (ti12 * tr5 - ti11 * tr4);
+ ci4 = isign * (ti12 * ti5 - ti11 * ti4);
+ dr3 = cr3 - ci4;
+ dr4 = cr3 + ci4;
+ di3 = ci3 + cr4;
+ di4 = ci3 - cr4;
+ dr5 = cr2 + ci5;
+ dr2 = cr2 - ci5;
+ di5 = ci2 - cr5;
+ di2 = ci2 + cr5;
+
+ int widx1 = i + iw1;
+ int widx2 = i + iw2;
+ int widx3 = i + iw3;
+ int widx4 = i + iw4;
+ float w1r = wtable[widx1];
+ float w1i = isign * wtable[widx1 + 1];
+ float w2r = wtable[widx2];
+ float w2i = isign * wtable[widx2 + 1];
+ float w3r = wtable[widx3];
+ float w3i = isign * wtable[widx3 + 1];
+ float w4r = wtable[widx4];
+ float w4i = isign * wtable[widx4 + 1];
+
+ int oidx1 = i + idx2;
+ int oidx2 = oidx1 + idx0;
+ int oidx3 = oidx2 + idx0;
+ int oidx4 = oidx3 + idx0;
+ int oidx5 = oidx4 + idx0;
+ out[oidx1] = i3i + tr2 + tr3;
+ out[oidx1 + 1] = i3r + ti2 + ti3;
+ out[oidx2] = w1r * dr2 - w1i * di2;
+ out[oidx2 + 1] = w1r * di2 + w1i * dr2;
+ out[oidx3] = w2r * dr3 - w2i * di3;
+ out[oidx3 + 1] = w2r * di3 + w2i * dr3;
+ out[oidx4] = w3r * dr4 - w3i * di4;
+ out[oidx4 + 1] = w3r * di4 + w3i * dr4;
+ out[oidx5] = w4r * dr5 - w4i * di5;
+ out[oidx5 + 1] = w4r * di5 + w4i * dr5;
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ passf5: Complex FFT's forward/backward processing of factor 5;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+/*
+ void passf5(final long ido, final long l1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) // isign==-1 for forward transform and+1 for backward transform {
+ final float tr11 = 0.309016994374947451262869435595348477f;
+ final float ti11 = 0.951056516295153531181938433292089030f;
+ final float tr12 = -0.809016994374947340240566973079694435f;
+ final float ti12 = 0.587785252292473248125759255344746634f;
+ float ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
+ long iw1, iw2, iw3, iw4;
+
+ iw1 = offset;
+ iw2 = iw1 + ido;
+ iw3 = iw2 + ido;
+ iw4 = iw3 + ido;
+
+ long idx0 = l1 * ido;
+
+ if (ido == 2) {
+ for (long k = 1; k <= l1; ++k) {
+ long iidx1 = in_off + (5 * k - 4) * ido + 1;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx1 - ido;
+ long iidx4 = iidx2 + ido;
+ long iidx5 = iidx4 + ido;
+
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+ float i5i = in.getFloat(iidx5 - 1);
+ float i5r = in.getFloat(iidx5);
+
+ ti5 = i1r - i5r;
+ ti2 = i1r + i5r;
+ ti4 = i2r - i4r;
+ ti3 = i2r + i4r;
+ tr5 = i1i - i5i;
+ tr2 = i1i + i5i;
+ tr4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr2 = i3i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i3r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i3i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i3r + tr12 * ti2 + tr11 * ti3;
+ cr5 = isign * (ti11 * tr5 + ti12 * tr4);
+ ci5 = isign * (ti11 * ti5 + ti12 * ti4);
+ cr4 = isign * (ti12 * tr5 - ti11 * tr4);
+ ci4 = isign * (ti12 * ti5 - ti11 * ti4);
+
+ long oidx1 = out_off + (k - 1) * ido;
+ long oidx2 = oidx1 + idx0;
+ long oidx3 = oidx2 + idx0;
+ long oidx4 = oidx3 + idx0;
+ long oidx5 = oidx4 + idx0;
+ out.setFloat(oidx1, i3i + tr2 + tr3);
+ out.setFloat(oidx1 + 1, i3r + ti2 + ti3);
+ out.setFloat(oidx2, cr2 - ci5);
+ out.setFloat(oidx2 + 1, ci2 + cr5);
+ out.setFloat(oidx3, cr3 - ci4);
+ out.setFloat(oidx3 + 1, ci3 + cr4);
+ out.setFloat(oidx4, cr3 + ci4);
+ out.setFloat(oidx4 + 1, ci3 - cr4);
+ out.setFloat(oidx5, cr2 + ci5);
+ out.setFloat(oidx5 + 1, ci2 - cr5);
+ }
+ } else {
+ for (long k = 1; k <= l1; k++) {
+ long idx1 = in_off + 1 + (k * 5 - 4) * ido;
+ long idx2 = out_off + (k - 1) * ido;
+ for (long i = 0; i < ido - 1; i += 2) {
+ long iidx1 = i + idx1;
+ long iidx2 = iidx1 + ido;
+ long iidx3 = iidx1 - ido;
+ long iidx4 = iidx2 + ido;
+ long iidx5 = iidx4 + ido;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+ float i3i = in.getFloat(iidx3 - 1);
+ float i3r = in.getFloat(iidx3);
+ float i4i = in.getFloat(iidx4 - 1);
+ float i4r = in.getFloat(iidx4);
+ float i5i = in.getFloat(iidx5 - 1);
+ float i5r = in.getFloat(iidx5);
+
+ ti5 = i1r - i5r;
+ ti2 = i1r + i5r;
+ ti4 = i2r - i4r;
+ ti3 = i2r + i4r;
+ tr5 = i1i - i5i;
+ tr2 = i1i + i5i;
+ tr4 = i2i - i4i;
+ tr3 = i2i + i4i;
+ cr2 = i3i + tr11 * tr2 + tr12 * tr3;
+ ci2 = i3r + tr11 * ti2 + tr12 * ti3;
+ cr3 = i3i + tr12 * tr2 + tr11 * tr3;
+ ci3 = i3r + tr12 * ti2 + tr11 * ti3;
+ cr5 = isign * (ti11 * tr5 + ti12 * tr4);
+ ci5 = isign * (ti11 * ti5 + ti12 * ti4);
+ cr4 = isign * (ti12 * tr5 - ti11 * tr4);
+ ci4 = isign * (ti12 * ti5 - ti11 * ti4);
+ dr3 = cr3 - ci4;
+ dr4 = cr3 + ci4;
+ di3 = ci3 + cr4;
+ di4 = ci3 - cr4;
+ dr5 = cr2 + ci5;
+ dr2 = cr2 - ci5;
+ di5 = ci2 - cr5;
+ di2 = ci2 + cr5;
+
+ long widx1 = i + iw1;
+ long widx2 = i + iw2;
+ long widx3 = i + iw3;
+ long widx4 = i + iw4;
+ float w1r = wtablel.getFloat(widx1);
+ float w1i = isign * wtablel.getFloat(widx1 + 1);
+ float w2r = wtablel.getFloat(widx2);
+ float w2i = isign * wtablel.getFloat(widx2 + 1);
+ float w3r = wtablel.getFloat(widx3);
+ float w3i = isign * wtablel.getFloat(widx3 + 1);
+ float w4r = wtablel.getFloat(widx4);
+ float w4i = isign * wtablel.getFloat(widx4 + 1);
+
+ long oidx1 = i + idx2;
+ long oidx2 = oidx1 + idx0;
+ long oidx3 = oidx2 + idx0;
+ long oidx4 = oidx3 + idx0;
+ long oidx5 = oidx4 + idx0;
+ out.setFloat(oidx1, i3i + tr2 + tr3);
+ out.setFloat(oidx1 + 1, i3r + ti2 + ti3);
+ out.setFloat(oidx2, w1r * dr2 - w1i * di2);
+ out.setFloat(oidx2 + 1, w1r * di2 + w1i * dr2);
+ out.setFloat(oidx3, w2r * dr3 - w2i * di3);
+ out.setFloat(oidx3 + 1, w2r * di3 + w2i * dr3);
+ out.setFloat(oidx4, w3r * dr4 - w3i * di4);
+ out.setFloat(oidx4 + 1, w3r * di4 + w3i * dr4);
+ out.setFloat(oidx5, w4r * dr5 - w4i * di5);
+ out.setFloat(oidx5 + 1, w4r * di5 + w4i * dr5);
+ }
+ }
+ }
+ }
+*/
+ /*----------------------------------------------------------------------
+ passfg: Complex FFT's forward/backward processing of general factor;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+ void passfg(final int nac[], final int ido, final int ip, final int l1, final int idl1, final float in[], final int in_off, final float out[], final int out_off, final int offset, final int isign) {
+ int idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
+ float w1r, w1i, w2i, w2r;
+ int iw1;
+
+ iw1 = offset;
+ idot = ido / 2;
+ ipph = (ip + 1) / 2;
+ idp = ip * ido;
+ if (ido >= l1) {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * ido;
+ int idx2 = jc * ido;
+ for (int k = 0; k < l1; k++) {
+ int idx3 = k * ido;
+ int idx4 = idx3 + idx1 * l1;
+ int idx5 = idx3 + idx2 * l1;
+ int idx6 = idx3 * ip;
+ for (int i = 0; i < ido; i++) {
+ int oidx1 = out_off + i;
+ float i1r = in[in_off + i + idx1 + idx6];
+ float i2r = in[in_off + i + idx2 + idx6];
+ out[oidx1 + idx4] = i1r + i2r;
+ out[oidx1 + idx5] = i1r - i2r;
+ }
+ }
+ }
+ for (int k = 0; k < l1; k++) {
+ int idxt1 = k * ido;
+ int idxt2 = idxt1 * ip;
+ for (int i = 0; i < ido; i++) {
+ out[out_off + i + idxt1] = in[in_off + i + idxt2];
+ }
+ }
+ } else {
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idxt1 = j * l1 * ido;
+ int idxt2 = jc * l1 * ido;
+ int idxt3 = j * ido;
+ int idxt4 = jc * ido;
+ for (int i = 0; i < ido; i++) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ int idx2 = idx1 * ip;
+ int idx3 = out_off + i;
+ int idx4 = in_off + i;
+ float i1r = in[idx4 + idxt3 + idx2];
+ float i2r = in[idx4 + idxt4 + idx2];
+ out[idx3 + idx1 + idxt1] = i1r + i2r;
+ out[idx3 + idx1 + idxt2] = i1r - i2r;
+ }
+ }
+ }
+ for (int i = 0; i < ido; i++) {
+ for (int k = 0; k < l1; k++) {
+ int idx1 = k * ido;
+ out[out_off + i + idx1] = in[in_off + i + idx1 * ip];
+ }
+ }
+ }
+
+ idl = 2 - ido;
+ inc = 0;
+ int idxt0 = (ip - 1) * idl1;
+ for (l = 1; l < ipph; l++) {
+ lc = ip - l;
+ idl += ido;
+ int idxt1 = l * idl1;
+ int idxt2 = lc * idl1;
+ int idxt3 = idl + iw1;
+ w1r = wtable[idxt3 - 2];
+ w1i = isign * wtable[idxt3 - 1];
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx1 = in_off + ik;
+ int idx2 = out_off + ik;
+ in[idx1 + idxt1] = out[idx2] + w1r * out[idx2 + idl1];
+ in[idx1 + idxt2] = w1i * out[idx2 + idxt0];
+ }
+ idlj = idl;
+ inc += ido;
+ for (int j = 2; j < ipph; j++) {
+ jc = ip - j;
+ idlj += inc;
+ if (idlj > idp) {
+ idlj -= idp;
+ }
+ int idxt4 = idlj + iw1;
+ w2r = wtable[idxt4 - 2];
+ w2i = isign * wtable[idxt4 - 1];
+ int idxt5 = j * idl1;
+ int idxt6 = jc * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx1 = in_off + ik;
+ int idx2 = out_off + ik;
+ in[idx1 + idxt1] += w2r * out[idx2 + idxt5];
+ in[idx1 + idxt2] += w2i * out[idx2 + idxt6];
+ }
+ }
+ }
+ for (int j = 1; j < ipph; j++) {
+ int idxt1 = j * idl1;
+ for (int ik = 0; ik < idl1; ik++) {
+ int idx1 = out_off + ik;
+ out[idx1] += out[idx1 + idxt1];
+ }
+ }
+ for (int j = 1; j < ipph; j++) {
+ jc = ip - j;
+ int idx1 = j * idl1;
+ int idx2 = jc * idl1;
+ for (int ik = 1; ik < idl1; ik += 2) {
+ int idx3 = out_off + ik;
+ int idx4 = in_off + ik;
+ int iidx1 = idx4 + idx1;
+ int iidx2 = idx4 + idx2;
+ float i1i = in[iidx1 - 1];
+ float i1r = in[iidx1];
+ float i2i = in[iidx2 - 1];
+ float i2r = in[iidx2];
+
+ int oidx1 = idx3 + idx1;
+ int oidx2 = idx3 + idx2;
+ out[oidx1 - 1] = i1i - i2r;
+ out[oidx2 - 1] = i1i + i2r;
+ out[oidx1] = i1r + i2i;
+ out[oidx2] = i1r - i2i;
+ }
+ }
+ nac[0] = 1;
+ if (ido == 2) {
+ return;
+ }
+ nac[0] = 0;
+ System.arraycopy(out, out_off, in, in_off, idl1);
+ int idx0 = l1 * ido;
+ for (int j = 1; j < ip; j++) {
+ int idx1 = j * idx0;
+ for (int k = 0; k < l1; k++) {
+ int idx2 = k * ido;
+ int oidx1 = out_off + idx2 + idx1;
+ int iidx1 = in_off + idx2 + idx1;
+ in[iidx1] = out[oidx1];
+ in[iidx1 + 1] = out[oidx1 + 1];
+ }
+ }
+ if (idot <= l1) {
+ idij = 0;
+ for (int j = 1; j < ip; j++) {
+ idij += 2;
+ int idx1 = j * l1 * ido;
+ for (int i = 3; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij + iw1 - 1;
+ w1r = wtable[idx2 - 1];
+ w1i = isign * wtable[idx2];
+ int idx3 = in_off + i;
+ int idx4 = out_off + i;
+ for (int k = 0; k < l1; k++) {
+ int idx5 = k * ido + idx1;
+ int iidx1 = idx3 + idx5;
+ int oidx1 = idx4 + idx5;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ in[iidx1 - 1] = w1r * o1i - w1i * o1r;
+ in[iidx1] = w1r * o1r + w1i * o1i;
+ }
+ }
+ }
+ } else {
+ idj = 2 - ido;
+ for (int j = 1; j < ip; j++) {
+ idj += ido;
+ int idx1 = j * l1 * ido;
+ for (int k = 0; k < l1; k++) {
+ idij = idj;
+ int idx3 = k * ido + idx1;
+ for (int i = 3; i < ido; i += 2) {
+ idij += 2;
+ int idx2 = idij - 1 + iw1;
+ w1r = wtable[idx2 - 1];
+ w1i = isign * wtable[idx2];
+ int iidx1 = in_off + i + idx3;
+ int oidx1 = out_off + i + idx3;
+ float o1i = out[oidx1 - 1];
+ float o1r = out[oidx1];
+ in[iidx1 - 1] = w1r * o1i - w1i * o1r;
+ in[iidx1] = w1r * o1r + w1i * o1i;
+ }
+ }
+ }
+ }
+ }
+
+ /*----------------------------------------------------------------------
+ passfg: Complex FFT's forward/backward processing of general factor;
+ isign is +1 for backward and -1 for forward transforms
+ ----------------------------------------------------------------------*/
+/*
+ void passfg(final int nac[], final long ido, final long ip, final long l1, final long idl1, final FloatLargeArray in, final long in_off, final FloatLargeArray out, final long out_off, final long offset, final long isign) {
+ long idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
+ float w1r, w1i, w2i, w2r;
+ long iw1;
+
+ iw1 = offset;
+ idot = ido / 2;
+ ipph = (ip + 1) / 2;
+ idp = ip * ido;
+ if (ido >= l1) {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * ido;
+ long idx2 = jc * ido;
+ for (long k = 0; k < l1; k++) {
+ long idx3 = k * ido;
+ long idx4 = idx3 + idx1 * l1;
+ long idx5 = idx3 + idx2 * l1;
+ long idx6 = idx3 * ip;
+ for (long i = 0; i < ido; i++) {
+ long oidx1 = out_off + i;
+ float i1r = in.getFloat(in_off + i + idx1 + idx6);
+ float i2r = in.getFloat(in_off + i + idx2 + idx6);
+ out.setFloat(oidx1 + idx4, i1r + i2r);
+ out.setFloat(oidx1 + idx5, i1r - i2r);
+ }
+ }
+ }
+ for (long k = 0; k < l1; k++) {
+ long idxt1 = k * ido;
+ long idxt2 = idxt1 * ip;
+ for (long i = 0; i < ido; i++) {
+ out.setFloat(out_off + i + idxt1, in.getFloat(in_off + i + idxt2));
+ }
+ }
+ } else {
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idxt1 = j * l1 * ido;
+ long idxt2 = jc * l1 * ido;
+ long idxt3 = j * ido;
+ long idxt4 = jc * ido;
+ for (long i = 0; i < ido; i++) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ long idx2 = idx1 * ip;
+ long idx3 = out_off + i;
+ long idx4 = in_off + i;
+ float i1r = in.getFloat(idx4 + idxt3 + idx2);
+ float i2r = in.getFloat(idx4 + idxt4 + idx2);
+ out.setFloat(idx3 + idx1 + idxt1, i1r + i2r);
+ out.setFloat(idx3 + idx1 + idxt2, i1r - i2r);
+ }
+ }
+ }
+ for (long i = 0; i < ido; i++) {
+ for (long k = 0; k < l1; k++) {
+ long idx1 = k * ido;
+ out.setFloat(out_off + i + idx1, in.getFloat(in_off + i + idx1 * ip));
+ }
+ }
+ }
+
+ idl = 2 - ido;
+ inc = 0;
+ long idxt0 = (ip - 1) * idl1;
+ for (l = 1; l < ipph; l++) {
+ lc = ip - l;
+ idl += ido;
+ long idxt1 = l * idl1;
+ long idxt2 = lc * idl1;
+ long idxt3 = idl + iw1;
+ w1r = wtablel.getFloat(idxt3 - 2);
+ w1i = isign * wtablel.getFloat(idxt3 - 1);
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx1 = in_off + ik;
+ long idx2 = out_off + ik;
+ in.setFloat(idx1 + idxt1, out.getFloat(idx2) + w1r * out.getFloat(idx2 + idl1));
+ in.setFloat(idx1 + idxt2, w1i * out.getFloat(idx2 + idxt0));
+ }
+ idlj = idl;
+ inc += ido;
+ for (long j = 2; j < ipph; j++) {
+ jc = ip - j;
+ idlj += inc;
+ if (idlj > idp) {
+ idlj -= idp;
+ }
+ long idxt4 = idlj + iw1;
+ w2r = wtablel.getFloat(idxt4 - 2);
+ w2i = isign * wtablel.getFloat(idxt4 - 1);
+ long idxt5 = j * idl1;
+ long idxt6 = jc * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx1 = in_off + ik;
+ long idx2 = out_off + ik;
+ in.setFloat(idx1 + idxt1, in.getFloat(idx1 + idxt1) + w2r * out.getFloat(idx2 + idxt5));
+ in.setFloat(idx1 + idxt2, in.getFloat(idx1 + idxt2) + w2i * out.getFloat(idx2 + idxt6));
+ }
+ }
+ }
+ for (long j = 1; j < ipph; j++) {
+ long idxt1 = j * idl1;
+ for (long ik = 0; ik < idl1; ik++) {
+ long idx1 = out_off + ik;
+ out.setFloat(idx1, out.getFloat(idx1) + out.getFloat(idx1 + idxt1));
+ }
+ }
+ for (long j = 1; j < ipph; j++) {
+ jc = ip - j;
+ long idx1 = j * idl1;
+ long idx2 = jc * idl1;
+ for (long ik = 1; ik < idl1; ik += 2) {
+ long idx3 = out_off + ik;
+ long idx4 = in_off + ik;
+ long iidx1 = idx4 + idx1;
+ long iidx2 = idx4 + idx2;
+ float i1i = in.getFloat(iidx1 - 1);
+ float i1r = in.getFloat(iidx1);
+ float i2i = in.getFloat(iidx2 - 1);
+ float i2r = in.getFloat(iidx2);
+
+ long oidx1 = idx3 + idx1;
+ long oidx2 = idx3 + idx2;
+ out.setFloat(oidx1 - 1, i1i - i2r);
+ out.setFloat(oidx2 - 1, i1i + i2r);
+ out.setFloat(oidx1, i1r + i2i);
+ out.setFloat(oidx2, i1r - i2i);
+ }
+ }
+ nac[0] = 1;
+ if (ido == 2) {
+ return;
+ }
+ nac[0] = 0;
+ Utilities.arraycopy(out, out_off, in, in_off, idl1);
+ long idx0 = l1 * ido;
+ for (long j = 1; j < ip; j++) {
+ long idx1 = j * idx0;
+ for (long k = 0; k < l1; k++) {
+ long idx2 = k * ido;
+ long oidx1 = out_off + idx2 + idx1;
+ long iidx1 = in_off + idx2 + idx1;
+ in.setFloat(iidx1, out.getFloat(oidx1));
+ in.setFloat(iidx1 + 1, out.getFloat(oidx1 + 1));
+ }
+ }
+ if (idot <= l1) {
+ idij = 0;
+ for (long j = 1; j < ip; j++) {
+ idij += 2;
+ long idx1 = j * l1 * ido;
+ for (long i = 3; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij + iw1 - 1;
+ w1r = wtablel.getFloat(idx2 - 1);
+ w1i = isign * wtablel.getFloat(idx2);
+ long idx3 = in_off + i;
+ long idx4 = out_off + i;
+ for (long k = 0; k < l1; k++) {
+ long idx5 = k * ido + idx1;
+ long iidx1 = idx3 + idx5;
+ long oidx1 = idx4 + idx5;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
+ in.setFloat(iidx1, w1r * o1r + w1i * o1i);
+ }
+ }
+ }
+ } else {
+ idj = 2 - ido;
+ for (long j = 1; j < ip; j++) {
+ idj += ido;
+ long idx1 = j * l1 * ido;
+ for (long k = 0; k < l1; k++) {
+ idij = idj;
+ long idx3 = k * ido + idx1;
+ for (long i = 3; i < ido; i += 2) {
+ idij += 2;
+ long idx2 = idij - 1 + iw1;
+ w1r = wtablel.getFloat(idx2 - 1);
+ w1i = isign * wtablel.getFloat(idx2);
+ long iidx1 = in_off + i + idx3;
+ long oidx1 = out_off + i + idx3;
+ float o1i = out.getFloat(oidx1 - 1);
+ float o1r = out.getFloat(oidx1);
+ in.setFloat(iidx1 - 1, w1r * o1i - w1i * o1r);
+ in.setFloat(iidx1, w1r * o1r + w1i * o1i);
+ }
+ }
+ }
+ }
+ }
+*/
+}
diff --git a/src/main/java/org/jtransforms/fft/FloatFFT_2D.java b/org/fairsim/extern/jtransforms/FloatFFT_2D.java
similarity index 97%
rename from src/main/java/org/jtransforms/fft/FloatFFT_2D.java
rename to org/fairsim/extern/jtransforms/FloatFFT_2D.java
index a294bd1..b78d38b 100644
--- a/src/main/java/org/jtransforms/fft/FloatFFT_2D.java
+++ b/org/fairsim/extern/jtransforms/FloatFFT_2D.java
@@ -1,3770 +1,3777 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 2D Discrete Fourier Transform (DFT) of complex and real, single
- * precision data. The sizes of both dimensions can be arbitrary numbers. This
- * is a parallel implementation of split-radix and mixed-radix algorithms
- * optimized for SMP systems. a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two float values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - */ - public void complexForward(final float[] a) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, r * columns); - } - cdft2d_sub(-1, a, true); - } - columns = columns / 2; - } else { - final int rowStride = 2 * columns; - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a, r * rowStride); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - float[] temp = new float[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx0 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - temp[idx1] = a[idx2]; - temp[idx1 + 1] = a[idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - a[idx2] = temp[idx1]; - a[idx2 + 1] = temp[idx1 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, r * rowStride); - } - float[] temp = new float[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx0 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - temp[idx1] = a[idx2]; - temp[idx1 + 1] = a[idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - a[idx2] = temp[idx1]; - a[idx2 + 1] = temp[idx1 + 1]; - } - } - } - } - } - - /** - * Computes 2D forward DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two float values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - */ - public void complexForward(final FloatLargeArray a) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columnsl = 2 * columnsl; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, r * columnsl); - } - cdft2d_sub(-1, a, true); - } - columnsl = columnsl / 2; - } else { - final long rowStride = 2 * columnsl; - if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (long r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a, r * rowStride); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columnsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstColumn = l * p; - final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); - for (long c = firstColumn; c < lastColumn; c++) { - long idx0 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - temp.setDouble(idx1, a.getFloat(idx2)); - temp.setDouble(idx1 + 1, a.getFloat(idx2 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - a.setDouble(idx2, temp.getFloat(idx1)); - a.setDouble(idx2 + 1, temp.getFloat(idx1 + 1)); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (long r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, r * rowStride); - } - FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); - for (long c = 0; c < columnsl; c++) { - long idx0 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - temp.setDouble(idx1, a.getFloat(idx2)); - temp.setDouble(idx1 + 1, a.getFloat(idx2 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - a.setDouble(idx2, temp.getFloat(idx1)); - a.setDouble(idx2 + 1, temp.getFloat(idx1 + 1)); - } - } - } - } - } - - /** - * Computes 2D forward DFT of complex data leaving the result in - *
a. The data is stored in 2D array. Complex data is
- * represented by 2 float values in sequence: the real and imaginary part,
- * i.e. the input array must be of size rows by 2*columns. The physical
- * layout of the input data has to be as follows:- * a[k1][2*k2] = Re[k1][k2], - * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - */ - public void complexForward(final float[][] a) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[r]); - } - cdft2d_sub(-1, a, true); - } - columns = columns / 2; - } else { - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a[r]); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - float[] temp = new float[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[r]); - } - float[] temp = new float[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two float values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - * - */ - public void complexInverse(final float[] a, final boolean scale) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, r * columns, scale); - } - cdft2d_sub(1, a, scale); - } - columns = columns / 2; - } else { - final int rowspan = 2 * columns; - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - float[] temp = new float[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - temp[idx2] = a[idx3]; - temp[idx2 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - a[idx3] = temp[idx2]; - a[idx3 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - float[] temp = new float[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - temp[idx2] = a[idx3]; - temp[idx2 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - a[idx3] = temp[idx2]; - a[idx3 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two float values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - * - */ - public void complexInverse(final FloatLargeArray a, final boolean scale) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columnsl = 2 * columnsl; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, r * columnsl, scale); - } - cdft2d_sub(1, a, scale); - } - columnsl = columnsl / 2; - } else { - final long rowspan = 2 * columnsl; - if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (long r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columnsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstColumn = l * p; - final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); - for (long c = firstColumn; c < lastColumn; c++) { - long idx1 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - temp.setDouble(idx2, a.getFloat(idx3)); - temp.setDouble(idx2 + 1, a.getFloat(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - a.setDouble(idx3, temp.getFloat(idx2)); - a.setDouble(idx3 + 1, temp.getFloat(idx2 + 1)); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); - for (long c = 0; c < columnsl; c++) { - long idx1 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - temp.setDouble(idx2, a.getFloat(idx3)); - temp.setDouble(idx2 + 1, a.getFloat(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - a.setDouble(idx3, temp.getFloat(idx2)); - a.setDouble(idx3 + 1, temp.getFloat(idx2 + 1)); - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 2D array. Complex data is
- * represented by 2 float values in sequence: the real and imaginary part,
- * i.e. the input array must be of size rows by 2*columns. The physical
- * layout of the input data has to be as follows:- * a[k1][2*k2] = Re[k1][k2], - * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - * - */ - public void complexInverse(final float[][] a, final boolean scale) { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[r], scale); - } - cdft2d_sub(1, a, scale); - } - columns = columns / 2; - } else { - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a[r], scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() { - public void run() { - float[] temp = new float[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[r], scale); - } - float[] temp = new float[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D forward DFT of real data leaving the result in
a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(float[] a) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(FloatLargeArray a) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * * - * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1][0] = Re[k1][0] = Re[rows-k1][0], - * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], - * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0][0] = Re[0][0], - * a[0][1] = Re[0][columns/2], - * a[rows/2][0] = Re[rows/2][0], - * a[rows/2][1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(float[][] a) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data. To get back the original data, use
- * complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(float[] a) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data. To get back the original data, use
- * complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(FloatLargeArray a) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows by 2*columns, with only the first rows by
- * columns elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(float[][] a) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(float[] a, boolean scale) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a, r * columns, scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(FloatLargeArray a, boolean scale) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse(a, r * columnsl, scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * * - * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1][0] = Re[k1][0] = Re[rows-k1][0], - * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], - * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0][0] = Re[0][0], - * a[0][1] = Re[0][columns/2], - * a[rows/2][0] = Re[rows/2][0], - * a[rows/2][1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(float[][] a, boolean scale) {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a[r], scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(float[] a, boolean scale) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(FloatLargeArray a, boolean scale) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows by 2*columns, with only the first rows by
- * columns elements filled with real data.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(float[][] a, boolean scale) {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- private void mixedRadixRealForwardFull(final float[][] a) {
- final int n2d2 = columns / 2 + 1;
- final float[][] temp = new float[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a[i]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
-
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
-
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealForwardFull(final float[] a) {
- final int rowStride = 2 * columns;
- final int n2d2 = columns / 2 + 1;
- final float[][] temp = new float[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a, i * columns);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealForwardFull(final FloatLargeArray a) {
- final long rowStride = 2 * columnsl;
- final long n2d2 = columnsl / 2 + 1;
- final FloatLargeArray temp = new FloatLargeArray(n2d2 * 2 * rowsl, false);
- final long temp_stride = 2 * rowsl;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a, i * columnsl);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
- }
- fftRows.realForwardFull(temp);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = 1 + l * p;
- final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long c = firstColumn; c < lastColumn; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexForward(temp, c * temp_stride);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
- }
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = 1 + l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getFloat(idx2));
- a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getFloat(idx4));
- a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
- }
- fftRows.realForwardFull(temp);
-
- for (long c = 1; c < n2d2 - 1; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexForward(temp, c * temp_stride);
- }
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
- }
-
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
- }
- }
-
- //fill symmetric
- for (long r = 1; r < rowsl; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getFloat(idx2));
- a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getFloat(idx4));
- a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final float[][] a, final boolean scale) {
- final int n2d2 = columns / 2 + 1;
- final float[][] temp = new float[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a[i], 0, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
-
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
-
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final float[] a, final boolean scale) {
- final int rowStride = 2 * columns;
- final int n2d2 = columns / 2 + 1;
- final float[][] temp = new float[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final FloatLargeArray a, final boolean scale) {
- final long rowStride = 2 * columnsl;
- final long n2d2 = columnsl / 2 + 1;
- final FloatLargeArray temp = new FloatLargeArray(n2d2 * 2 * rowsl, false);
- final long temp_stride = 2 * rowsl;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
- }
- fftRows.realInverseFull(temp, scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = 1 + l * p;
- final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long c = firstColumn; c < lastColumn; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexInverse(temp, c * temp_stride, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
- }
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = 1 + l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getFloat(idx2));
- a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getFloat(idx4));
- a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
- }
- fftRows.realInverseFull(temp, scale);
-
- for (long c = 1; c < n2d2 - 1; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexInverse(temp, c * temp_stride, scale);
- }
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
- }
- fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
- }
-
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
- }
- }
-
- //fill symmetric
- for (long r = 1; r < rowsl; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getFloat(idx2));
- a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getFloat(idx4));
- a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
- }
- }
- }
- }
-
- private void rdft2d_sub(int isgn, float[] a) {
- int n1h, j;
- float xi;
- int idx1, idx2;
-
- n1h = rows >> 1;
- if (isgn < 0) {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- idx1 = i * columns;
- idx2 = j * columns;
- xi = a[idx1] - a[idx2];
- a[idx1] += a[idx2];
- a[idx2] = xi;
- xi = a[idx2 + 1] - a[idx1 + 1];
- a[idx1 + 1] += a[idx2 + 1];
- a[idx2 + 1] = xi;
- }
- } else {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- idx1 = i * columns;
- idx2 = j * columns;
- a[idx2] = 0.5f * (a[idx1] - a[idx2]);
- a[idx1] -= a[idx2];
- a[idx2 + 1] = 0.5f * (a[idx1 + 1] + a[idx2 + 1]);
- a[idx1 + 1] -= a[idx2 + 1];
- }
- }
- }
-
- private void rdft2d_sub(int isgn, FloatLargeArray a) {
- long n1h, j;
- float xi;
- long idx1, idx2;
-
- n1h = rowsl >> 1;
- if (isgn < 0) {
- for (long i = 1; i < n1h; i++) {
- j = rowsl - i;
- idx1 = i * columnsl;
- idx2 = j * columnsl;
- xi = a.getFloat(idx1) - a.getFloat(idx2);
- a.setDouble(idx1, a.getFloat(idx1) + a.getFloat(idx2));
- a.setDouble(idx2, xi);
- xi = a.getFloat(idx2 + 1) - a.getFloat(idx1 + 1);
- a.setDouble(idx1 + 1, a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1));
- a.setDouble(idx2 + 1, xi);
- }
- } else {
- for (long i = 1; i < n1h; i++) {
- j = rowsl - i;
- idx1 = i * columnsl;
- idx2 = j * columnsl;
- a.setDouble(idx2, 0.5f * (a.getFloat(idx1) - a.getFloat(idx2)));
- a.setDouble(idx1, a.getFloat(idx1) - a.getFloat(idx2));
- a.setDouble(idx2 + 1, 0.5f * (a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1)));
- a.setDouble(idx1 + 1, a.getFloat(idx1 + 1) - a.getFloat(idx2 + 1));
- }
- }
- }
-
- private void rdft2d_sub(int isgn, float[][] a) {
- int n1h, j;
- float xi;
-
- n1h = rows >> 1;
- if (isgn < 0) {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- xi = a[i][0] - a[j][0];
- a[i][0] += a[j][0];
- a[j][0] = xi;
- xi = a[j][1] - a[i][1];
- a[i][1] += a[j][1];
- a[j][1] = xi;
- }
- } else {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- a[j][0] = 0.5f * (a[i][0] - a[j][0]);
- a[i][0] -= a[j][0];
- a[j][1] = 0.5f * (a[i][1] + a[j][1]);
- a[i][1] -= a[j][1];
- }
- }
- }
-
- private void cdft2d_sub(int isgn, float[] a, boolean scale) {
- int idx1, idx2, idx3, idx4, idx5;
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
-
- private void cdft2d_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx1, idx2, idx3, idx4, idx5;
- long nt = 8 * rowsl;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- t.setDouble(idx4, a.getFloat(idx1 + 4));
- t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
- t.setDouble(idx5, a.getFloat(idx1 + 6));
- t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- a.setDouble(idx1 + 4, t.getFloat(idx4));
- a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
- a.setDouble(idx1 + 6, t.getFloat(idx5));
- a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- }
- }
- } else {
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- t.setDouble(idx4, a.getFloat(idx1 + 4));
- t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
- t.setDouble(idx5, a.getFloat(idx1 + 6));
- t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- a.setDouble(idx1 + 4, t.getFloat(idx4));
- a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
- a.setDouble(idx1 + 6, t.getFloat(idx5));
- a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- }
- }
- }
- }
-
- private void cdft2d_sub(int isgn, float[][] a, boolean scale) {
- int idx2, idx3, idx4, idx5;
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- t[idx3] = a[r][2];
- t[idx3 + 1] = a[r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- a[r][2] = t[idx3];
- a[r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- t[idx3] = a[r][2];
- t[idx3 + 1] = a[r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- a[r][2] = t[idx3];
- a[r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- }
- }
- }
- }
-
- private void xdft2d0_subth1(final int icr, final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a, r * columns, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse(a, r * columns, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth1(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexInverse(a, r * columnsl, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realInverse(a, r * columnsl, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final int icr, final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a, r * columns, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexInverse(a, r * columnsl, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth1(final int icr, final int isgn, final float[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a[r], scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse(a[r], scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final int icr, final int isgn, final float[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a[r], scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final float[] a, final boolean scale) {
- int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2, idx3, idx4, idx5;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl / 2, ConcurrencyUtils.getNumberOfThreads());
- long nt = 8 * rowsl;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthread; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2, idx3, idx4, idx5;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 4 * nthreads) {
- for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- t.setDouble(idx4, a.getFloat(idx1 + 4));
- t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
- t.setDouble(idx5, a.getFloat(idx1 + 6));
- t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- a.setDouble(idx1 + 4, t.getFloat(idx4));
- a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
- a.setDouble(idx1 + 6, t.getFloat(idx5));
- a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
- }
- }
- } else if (columnsl == 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- }
- } else if (columnsl == 2 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- }
- }
- } else {
- if (columnsl > 4 * nthreads) {
- for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- t.setDouble(idx4, a.getFloat(idx1 + 4));
- t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
- t.setDouble(idx5, a.getFloat(idx1 + 6));
- t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- a.setDouble(idx1 + 4, t.getFloat(idx4));
- a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
- a.setDouble(idx1 + 6, t.getFloat(idx5));
- a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
- }
- }
- } else if (columnsl == 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- t.setDouble(idx3, a.getFloat(idx1 + 2));
- t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- a.setDouble(idx1 + 2, t.getFloat(idx3));
- a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
- }
- } else if (columnsl == 2 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getFloat(idx1));
- t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getFloat(idx2));
- a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final float[][] a, final boolean scale) {
- int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2, idx3, idx4, idx5;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][4 * n0];
- t[idx2 + 1] = a[r][4 * n0 + 1];
- t[idx3] = a[r][4 * n0 + 2];
- t[idx3 + 1] = a[r][4 * n0 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][4 * n0] = t[idx2];
- a[r][4 * n0 + 1] = t[idx2 + 1];
- a[r][4 * n0 + 2] = t[idx3];
- a[r][4 * n0 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + 1] = a[r][2 * n0 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][4 * n0];
- t[idx2 + 1] = a[r][4 * n0 + 1];
- t[idx3] = a[r][4 * n0 + 2];
- t[idx3 + 1] = a[r][4 * n0 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][4 * n0] = t[idx2];
- a[r][4 * n0 + 1] = t[idx2 + 1];
- a[r][4 * n0 + 2] = t[idx3];
- a[r][4 * n0 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + 1] = a[r][2 * n0 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void fillSymmetric(final float[] a) {
- final int twon2 = 2 * columns;
- int idx1, idx2, idx3, idx4;
- int n1d2 = rows / 2;
-
- for (int r = (rows - 1); r >= 1; r--) {
- idx1 = r * columns;
- idx2 = 2 * idx1;
- for (int c = 0; c < columns; c += 2) {
- a[idx2 + c] = a[idx1 + c];
- a[idx1 + c] = 0;
- a[idx2 + c + 1] = a[idx1 + c + 1];
- a[idx1 + c + 1] = 0;
- }
- }
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int l1k = n1d2 / nthreads;
- final int newn2 = 2 * columns;
- for (int i = 0; i < nthreads; i++) {
- final int l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0) {
- l1offa = i * l1k + 1;
- } else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2, idx3, idx4;
-
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx2 = (rows - r) * newn2;
- idx3 = idx1 + columns;
- a[idx3] = a[idx2 + 1];
- a[idx3 + 1] = -a[idx2];
- }
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx3 = (rows - r + 1) * newn2;
- for (int c = columns + 2; c < newn2; c += 2) {
- idx2 = idx3 - c;
- idx4 = idx1 + c;
- a[idx4] = a[idx2];
- a[idx4 + 1] = -a[idx2 + 1];
-
- }
- }
- for (int r = l2offa; r < l2stopa; r++) {
- idx3 = ((rows - r) % rows) * newn2;
- idx4 = r * newn2;
- for (int c = 0; c < newn2; c += 2) {
- idx1 = idx3 + (newn2 - c) % newn2;
- idx2 = idx4 + c;
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rows - r) * twon2;
- a[idx2 + columns] = a[idx3 + 1];
- a[idx2 + columns + 1] = -a[idx3];
- }
-
- for (int r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rows - r + 1) * twon2;
- for (int c = columns + 2; c < twon2; c += 2) {
- a[idx2 + c] = a[idx3 - c];
- a[idx2 + c + 1] = -a[idx3 - c + 1];
-
- }
- }
- for (int r = 0; r <= rows / 2; r++) {
- idx1 = r * twon2;
- idx4 = ((rows - r) % rows) * twon2;
- for (int c = 0; c < twon2; c += 2) {
- idx2 = idx1 + c;
- idx3 = idx4 + (twon2 - c) % twon2;
- a[idx3] = a[idx2];
- a[idx3 + 1] = -a[idx2 + 1];
- }
- }
- }
- a[columns] = -a[1];
- a[1] = 0;
- idx1 = n1d2 * twon2;
- a[idx1 + columns] = -a[idx1 + 1];
- a[idx1 + 1] = 0;
- a[idx1 + columns + 1] = 0;
- }
-
- private void fillSymmetric(final FloatLargeArray a) {
- final long twon2 = 2 * columnsl;
- long idx1, idx2, idx3, idx4;
- long n1d2 = rowsl / 2;
-
- for (long r = (rowsl - 1); r >= 1; r--) {
- idx1 = r * columnsl;
- idx2 = 2 * idx1;
- for (long c = 0; c < columnsl; c += 2) {
- a.setDouble(idx2 + c, a.getFloat(idx1 + c));
- a.setDouble(idx1 + c, 0);
- a.setDouble(idx2 + c + 1, a.getFloat(idx1 + c + 1));
- a.setDouble(idx1 + c + 1, 0);
- }
- }
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long l1k = n1d2 / nthreads;
- final long newn2 = 2 * columnsl;
- for (int i = 0; i < nthreads; i++) {
- final long l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0) {
- l1offa = i * l1k + 1;
- } else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2, idx3, idx4;
-
- for (long r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx2 = (rowsl - r) * newn2;
- idx3 = idx1 + columnsl;
- a.setDouble(idx3, a.getFloat(idx2 + 1));
- a.setDouble(idx3 + 1, -a.getFloat(idx2));
- }
- for (long r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx3 = (rowsl - r + 1) * newn2;
- for (long c = columnsl + 2; c < newn2; c += 2) {
- idx2 = idx3 - c;
- idx4 = idx1 + c;
- a.setDouble(idx4, a.getFloat(idx2));
- a.setDouble(idx4 + 1, -a.getFloat(idx2 + 1));
-
- }
- }
- for (long r = l2offa; r < l2stopa; r++) {
- idx3 = ((rowsl - r) % rowsl) * newn2;
- idx4 = r * newn2;
- for (long c = 0; c < newn2; c += 2) {
- idx1 = idx3 + (newn2 - c) % newn2;
- idx2 = idx4 + c;
- a.setDouble(idx1, a.getFloat(idx2));
- a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rowsl - r) * twon2;
- a.setDouble(idx2 + columnsl, a.getFloat(idx3 + 1));
- a.setDouble(idx2 + columnsl + 1, -a.getFloat(idx3));
- }
-
- for (long r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rowsl - r + 1) * twon2;
- for (long c = columnsl + 2; c < twon2; c += 2) {
- a.setDouble(idx2 + c, a.getFloat(idx3 - c));
- a.setDouble(idx2 + c + 1, -a.getFloat(idx3 - c + 1));
-
- }
- }
- for (long r = 0; r <= rowsl / 2; r++) {
- idx1 = r * twon2;
- idx4 = ((rowsl - r) % rowsl) * twon2;
- for (long c = 0; c < twon2; c += 2) {
- idx2 = idx1 + c;
- idx3 = idx4 + (twon2 - c) % twon2;
- a.setDouble(idx3, a.getFloat(idx2));
- a.setDouble(idx3 + 1, -a.getFloat(idx2 + 1));
- }
- }
- }
- a.setDouble(columnsl, -a.getFloat(1));
- a.setDouble(1, 0);
- idx1 = n1d2 * twon2;
- a.setDouble(idx1 + columnsl, -a.getFloat(idx1 + 1));
- a.setDouble(idx1 + 1, 0);
- a.setDouble(idx1 + columnsl + 1, 0);
- }
-
- private void fillSymmetric(final float[][] a) {
- final int newn2 = 2 * columns;
- int n1d2 = rows / 2;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int l1k = n1d2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0) {
- l1offa = i * l1k + 1;
- } else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = rows - r;
- a[r][columns] = a[idx1][1];
- a[r][columns + 1] = -a[idx1][0];
- }
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = rows - r;
- for (int c = columns + 2; c < newn2; c += 2) {
- idx2 = newn2 - c;
- a[r][c] = a[idx1][idx2];
- a[r][c + 1] = -a[idx1][idx2 + 1];
-
- }
- }
- for (int r = l2offa; r < l2stopa; r++) {
- idx1 = (rows - r) % rows;
- for (int c = 0; c < newn2; c = c + 2) {
- idx2 = (newn2 - c) % newn2;
- a[idx1][idx2] = a[r][c];
- a[idx1][idx2 + 1] = -a[r][c + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int r = 1; r < n1d2; r++) {
- int idx1 = rows - r;
- a[r][columns] = a[idx1][1];
- a[r][columns + 1] = -a[idx1][0];
- }
- for (int r = 1; r < n1d2; r++) {
- int idx1 = rows - r;
- for (int c = columns + 2; c < newn2; c += 2) {
- int idx2 = newn2 - c;
- a[r][c] = a[idx1][idx2];
- a[r][c + 1] = -a[idx1][idx2 + 1];
- }
- }
- for (int r = 0; r <= rows / 2; r++) {
- int idx1 = (rows - r) % rows;
- for (int c = 0; c < newn2; c += 2) {
- int idx2 = (newn2 - c) % newn2;
- a[idx1][idx2] = a[r][c];
- a[idx1][idx2 + 1] = -a[r][c + 1];
- }
- }
- }
- a[0][columns] = -a[0][1];
- a[0][1] = 0;
- a[n1d2][columns] = -a[n1d2][1];
- a[n1d2][1] = 0;
- a[n1d2][columns + 1] = 0;
- }
-}
+/* ***** BEGIN LICENSE BLOCK *****
+ * JTransforms
+ * Copyright (c) 2007 onward, Piotr Wendykier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Code modified for inclusion with fairSIM:
+// - changed package name
+// - Commented out all dependence on ...LargeArray
+// - based on JTransforms 3.1, git ede249c9824262bd9b5f571e56f7a0fa596f6f20
+
+package org.fairsim.extern.jtransforms;
+
+import java.util.concurrent.Future;
+//import org.jtransforms.utils.ConcurrencyUtils;
+//import pl.edu.icm.jlargearrays.FloatLargeArray;
+
+/**
+ * Computes 2D Discrete Fourier Transform (DFT) of complex and real, single
+ * precision data. The sizes of both dimensions can be arbitrary numbers. This
+ * is a parallel implementation of split-radix and mixed-radix algorithms
+ * optimized for SMP systems. a. The data is stored in 1D array in row-major order.
+ * Complex number is stored as two float values in sequence: the real and
+ * imaginary part, i.e. the input array must be of size rows*2*columns. The
+ * physical layout of the input data has to be as follows:+ * a[k1*2*columns+2*k2] = Re[k1][k2], + * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + */ + public void complexForward(final float[] a) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columns = 2 * columns; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, -1, a, true); + cdft2d_subth(-1, a, true); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexForward(a, r * columns); + } + cdft2d_sub(-1, a, true); + } + columns = columns / 2; + } else { + final int rowStride = 2 * columns; + if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { + Future>[] futures = new Future[nthreads]; + int p = rows / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstRow = l * p; + final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (int r = firstRow; r < lastRow; r++) { + fftColumns.complexForward(a, r * rowStride); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columns / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstColumn = l * p; + final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + float[] temp = new float[2 * rows]; + for (int c = firstColumn; c < lastColumn; c++) { + int idx0 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx1 = 2 * r; + int idx2 = r * rowStride + idx0; + temp[idx1] = a[idx2]; + temp[idx1 + 1] = a[idx2 + 1]; + } + fftRows.complexForward(temp); + for (int r = 0; r < rows; r++) { + int idx1 = 2 * r; + int idx2 = r * rowStride + idx0; + a[idx2] = temp[idx1]; + a[idx2 + 1] = temp[idx1 + 1]; + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexForward(a, r * rowStride); + } + float[] temp = new float[2 * rows]; + for (int c = 0; c < columns; c++) { + int idx0 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx1 = 2 * r; + int idx2 = r * rowStride + idx0; + temp[idx1] = a[idx2]; + temp[idx1 + 1] = a[idx2 + 1]; + } + fftRows.complexForward(temp); + for (int r = 0; r < rows; r++) { + int idx1 = 2 * r; + int idx2 = r * rowStride + idx0; + a[idx2] = temp[idx1]; + a[idx2 + 1] = temp[idx1 + 1]; + } + } + } + } + } + + /** + * Computes 2D forward DFT of complex data leaving the result in + *
a. The data is stored in 1D array in row-major order.
+ * Complex number is stored as two float values in sequence: the real and
+ * imaginary part, i.e. the input array must be of size rows*2*columns. The
+ * physical layout of the input data has to be as follows:+ * a[k1*2*columns+2*k2] = Re[k1][k2], + * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + * + public void complexForward(final FloatLargeArray a) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columnsl = 2 * columnsl; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, -1, a, true); + cdft2d_subth(-1, a, true); + } else { + for (int r = 0; r < rowsl; r++) { + fftColumns.complexForward(a, r * columnsl); + } + cdft2d_sub(-1, a, true); + } + columnsl = columnsl / 2; + } else { + final long rowStride = 2 * columnsl; + if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { + Future>[] futures = new Future[nthreads]; + long p = rowsl / nthreads; + for (int l = 0; l < nthreads; l++) { + final long firstRow = l * p; + final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (long r = firstRow; r < lastRow; r++) { + fftColumns.complexForward(a, r * rowStride); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columnsl / nthreads; + for (int l = 0; l < nthreads; l++) { + final long firstColumn = l * p; + final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); + for (long c = firstColumn; c < lastColumn; c++) { + long idx0 = 2 * c; + for (long r = 0; r < rowsl; r++) { + long idx1 = 2 * r; + long idx2 = r * rowStride + idx0; + temp.setDouble(idx1, a.getFloat(idx2)); + temp.setDouble(idx1 + 1, a.getFloat(idx2 + 1)); + } + fftRows.complexForward(temp); + for (long r = 0; r < rowsl; r++) { + long idx1 = 2 * r; + long idx2 = r * rowStride + idx0; + a.setDouble(idx2, temp.getFloat(idx1)); + a.setDouble(idx2 + 1, temp.getFloat(idx1 + 1)); + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (long r = 0; r < rowsl; r++) { + fftColumns.complexForward(a, r * rowStride); + } + FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); + for (long c = 0; c < columnsl; c++) { + long idx0 = 2 * c; + for (long r = 0; r < rowsl; r++) { + long idx1 = 2 * r; + long idx2 = r * rowStride + idx0; + temp.setDouble(idx1, a.getFloat(idx2)); + temp.setDouble(idx1 + 1, a.getFloat(idx2 + 1)); + } + fftRows.complexForward(temp); + for (long r = 0; r < rowsl; r++) { + long idx1 = 2 * r; + long idx2 = r * rowStride + idx0; + a.setDouble(idx2, temp.getFloat(idx1)); + a.setDouble(idx2 + 1, temp.getFloat(idx1 + 1)); + } + } + } + } + } */ + + /** + * Computes 2D forward DFT of complex data leaving the result in + *
a. The data is stored in 2D array. Complex data is
+ * represented by 2 float values in sequence: the real and imaginary part,
+ * i.e. the input array must be of size rows by 2*columns. The physical
+ * layout of the input data has to be as follows:+ * a[k1][2*k2] = Re[k1][k2], + * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + */ + public void complexForward(final float[][] a) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columns = 2 * columns; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, -1, a, true); + cdft2d_subth(-1, a, true); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexForward(a[r]); + } + cdft2d_sub(-1, a, true); + } + columns = columns / 2; + } else { + if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { + Future>[] futures = new Future[nthreads]; + int p = rows / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstRow = l * p; + final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (int r = firstRow; r < lastRow; r++) { + fftColumns.complexForward(a[r]); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columns / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstColumn = l * p; + final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + float[] temp = new float[2 * rows]; + for (int c = firstColumn; c < lastColumn; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + temp[idx2] = a[r][idx1]; + temp[idx2 + 1] = a[r][idx1 + 1]; + } + fftRows.complexForward(temp); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + a[r][idx1] = temp[idx2]; + a[r][idx1 + 1] = temp[idx2 + 1]; + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexForward(a[r]); + } + float[] temp = new float[2 * rows]; + for (int c = 0; c < columns; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + temp[idx2] = a[r][idx1]; + temp[idx2 + 1] = a[r][idx1 + 1]; + } + fftRows.complexForward(temp); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + a[r][idx1] = temp[idx2]; + a[r][idx1 + 1] = temp[idx2 + 1]; + } + } + } + } + } + + /** + * Computes 2D inverse DFT of complex data leaving the result in + *
a. The data is stored in 1D array in row-major order.
+ * Complex number is stored as two float values in sequence: the real and
+ * imaginary part, i.e. the input array must be of size rows*2*columns. The
+ * physical layout of the input data has to be as follows:+ * a[k1*2*columns+2*k2] = Re[k1][k2], + * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + * @param scale if true then scaling is performed + * + */ + public void complexInverse(final float[] a, final boolean scale) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columns = 2 * columns; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, 1, a, scale); + cdft2d_subth(1, a, scale); + } else { + + for (int r = 0; r < rows; r++) { + fftColumns.complexInverse(a, r * columns, scale); + } + cdft2d_sub(1, a, scale); + } + columns = columns / 2; + } else { + final int rowspan = 2 * columns; + if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { + Future>[] futures = new Future[nthreads]; + int p = rows / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstRow = l * p; + final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (int r = firstRow; r < lastRow; r++) { + fftColumns.complexInverse(a, r * rowspan, scale); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columns / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstColumn = l * p; + final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + float[] temp = new float[2 * rows]; + for (int c = firstColumn; c < lastColumn; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + int idx3 = r * rowspan + idx1; + temp[idx2] = a[idx3]; + temp[idx2 + 1] = a[idx3 + 1]; + } + fftRows.complexInverse(temp, scale); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + int idx3 = r * rowspan + idx1; + a[idx3] = temp[idx2]; + a[idx3 + 1] = temp[idx2 + 1]; + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexInverse(a, r * rowspan, scale); + } + float[] temp = new float[2 * rows]; + for (int c = 0; c < columns; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + int idx3 = r * rowspan + idx1; + temp[idx2] = a[idx3]; + temp[idx2 + 1] = a[idx3 + 1]; + } + fftRows.complexInverse(temp, scale); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + int idx3 = r * rowspan + idx1; + a[idx3] = temp[idx2]; + a[idx3 + 1] = temp[idx2 + 1]; + } + } + } + } + } + + /** + * Computes 2D inverse DFT of complex data leaving the result in + *
a. The data is stored in 1D array in row-major order.
+ * Complex number is stored as two float values in sequence: the real and
+ * imaginary part, i.e. the input array must be of size rows*2*columns. The
+ * physical layout of the input data has to be as follows:+ * a[k1*2*columns+2*k2] = Re[k1][k2], + * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + * @param scale if true then scaling is performed + * + * + public void complexInverse(final FloatLargeArray a, final boolean scale) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columnsl = 2 * columnsl; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, 1, a, scale); + cdft2d_subth(1, a, scale); + } else { + + for (long r = 0; r < rowsl; r++) { + fftColumns.complexInverse(a, r * columnsl, scale); + } + cdft2d_sub(1, a, scale); + } + columnsl = columnsl / 2; + } else { + final long rowspan = 2 * columnsl; + if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { + Future>[] futures = new Future[nthreads]; + long p = rowsl / nthreads; + for (int l = 0; l < nthreads; l++) { + final long firstRow = l * p; + final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (long r = firstRow; r < lastRow; r++) { + fftColumns.complexInverse(a, r * rowspan, scale); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columnsl / nthreads; + for (int l = 0; l < nthreads; l++) { + final long firstColumn = l * p; + final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); + for (long c = firstColumn; c < lastColumn; c++) { + long idx1 = 2 * c; + for (long r = 0; r < rowsl; r++) { + long idx2 = 2 * r; + long idx3 = r * rowspan + idx1; + temp.setDouble(idx2, a.getFloat(idx3)); + temp.setDouble(idx2 + 1, a.getFloat(idx3 + 1)); + } + fftRows.complexInverse(temp, scale); + for (long r = 0; r < rowsl; r++) { + long idx2 = 2 * r; + long idx3 = r * rowspan + idx1; + a.setDouble(idx3, temp.getFloat(idx2)); + a.setDouble(idx3 + 1, temp.getFloat(idx2 + 1)); + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (long r = 0; r < rowsl; r++) { + fftColumns.complexInverse(a, r * rowspan, scale); + } + FloatLargeArray temp = new FloatLargeArray(2 * rowsl, false); + for (long c = 0; c < columnsl; c++) { + long idx1 = 2 * c; + for (long r = 0; r < rowsl; r++) { + long idx2 = 2 * r; + long idx3 = r * rowspan + idx1; + temp.setDouble(idx2, a.getFloat(idx3)); + temp.setDouble(idx2 + 1, a.getFloat(idx3 + 1)); + } + fftRows.complexInverse(temp, scale); + for (long r = 0; r < rowsl; r++) { + long idx2 = 2 * r; + long idx3 = r * rowspan + idx1; + a.setDouble(idx3, temp.getFloat(idx2)); + a.setDouble(idx3 + 1, temp.getFloat(idx2 + 1)); + } + } + } + } + } */ + + /** + * Computes 2D inverse DFT of complex data leaving the result in + *
a. The data is stored in 2D array. Complex data is
+ * represented by 2 float values in sequence: the real and imaginary part,
+ * i.e. the input array must be of size rows by 2*columns. The physical
+ * layout of the input data has to be as follows:+ * a[k1][2*k2] = Re[k1][k2], + * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, + *+ * + * @param a data to transform + * @param scale if true then scaling is performed + * + */ + public void complexInverse(final float[][] a, final boolean scale) { + int nthreads = ConcurrencyUtils.getNumberOfThreads(); + if (isPowerOfTwo) { + columns = 2 * columns; + if ((nthreads > 1) && useThreads) { + xdft2d0_subth1(0, 1, a, scale); + cdft2d_subth(1, a, scale); + } else { + + for (int r = 0; r < rows; r++) { + fftColumns.complexInverse(a[r], scale); + } + cdft2d_sub(1, a, scale); + } + columns = columns / 2; + } else { + if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { + Future>[] futures = new Future[nthreads]; + int p = rows / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstRow = l * p; + final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + for (int r = firstRow; r < lastRow; r++) { + fftColumns.complexInverse(a[r], scale); + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + p = columns / nthreads; + for (int l = 0; l < nthreads; l++) { + final int firstColumn = l * p; + final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; + futures[l] = ConcurrencyUtils.submit(new Runnable() { + public void run() { + float[] temp = new float[2 * rows]; + for (int c = firstColumn; c < lastColumn; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + temp[idx2] = a[r][idx1]; + temp[idx2 + 1] = a[r][idx1 + 1]; + } + fftRows.complexInverse(temp, scale); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + a[r][idx1] = temp[idx2]; + a[r][idx1 + 1] = temp[idx2 + 1]; + } + } + } + }); + } + ConcurrencyUtils.waitForCompletion(futures); + } else { + for (int r = 0; r < rows; r++) { + fftColumns.complexInverse(a[r], scale); + } + float[] temp = new float[2 * rows]; + for (int c = 0; c < columns; c++) { + int idx1 = 2 * c; + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + temp[idx2] = a[r][idx1]; + temp[idx2 + 1] = a[r][idx1 + 1]; + } + fftRows.complexInverse(temp, scale); + for (int r = 0; r < rows; r++) { + int idx2 = 2 * r; + a[r][idx1] = temp[idx2]; + a[r][idx1 + 1] = temp[idx2 + 1]; + } + } + } + } + } + + /** + * Computes 2D forward DFT of real data leaving the result in
a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the output data is as
+ * follows:
+ *
+ * * + * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], + * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], + * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0] = Re[0][0], + * a[1] = Re[0][columns/2], + * a[(rows/2)*columns] = Re[rows/2][0], + * a[(rows/2)*columns+1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForward(float[] a) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a, r * columns);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ }
+ }
+
+ /**
+ * Computes 2D forward DFT of real data leaving the result in a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the output data is as
+ * follows:
+ *
+ * * + * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], + * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], + * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0] = Re[0][0], + * a[1] = Re[0][columns/2], + * a[(rows/2)*columns] = Re[rows/2][0], + * a[(rows/2)*columns+1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ *
+ public void realForward(FloatLargeArray a) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realForward(a, r * columnsl);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ }
+ } */
+
+ /**
+ * Computes 2D forward DFT of real data leaving the result in a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the output data is as
+ * follows:
+ *
+ * * + * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1][0] = Re[k1][0] = Re[rows-k1][0], + * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], + * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0][0] = Re[0][0], + * a[0][1] = Re[0][columns/2], + * a[rows/2][0] = Re[rows/2][0], + * a[rows/2][1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * forward transform, use
realForwardFull. To get back the
+ * original data, use realInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForward(float[][] a) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a[r]);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ }
+ }
+
+ /**
+ * Computes 2D forward DFT of real data leaving the result in a
+ * . This method computes full real forward transform, i.e. you will get the
+ * same result as from complexForward called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows*2*columns, with only the first rows*columns
+ * elements filled with real data. To get back the original data, use
+ * complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForwardFull(float[] a) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a, r * columns);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealForwardFull(a);
+ }
+ }
+
+ /**
+ * Computes 2D forward DFT of real data leaving the result in a
+ * . This method computes full real forward transform, i.e. you will get the
+ * same result as from complexForward called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows*2*columns, with only the first rows*columns
+ * elements filled with real data. To get back the original data, use
+ * complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ *
+ public void realForwardFull(FloatLargeArray a) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realForward(a, r * columnsl);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealForwardFull(a);
+ }
+ } */
+
+ /**
+ * Computes 2D forward DFT of real data leaving the result in a
+ * . This method computes full real forward transform, i.e. you will get the
+ * same result as from complexForward called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows by 2*columns, with only the first rows by
+ * columns elements filled with real data. To get back the original data,
+ * use complexInverse on the output of this method.
+ *
+ * @param a data to transform
+ */
+ public void realForwardFull(float[][] a) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth1(1, 1, a, true);
+ cdft2d_subth(-1, a, true);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a[r]);
+ }
+ cdft2d_sub(-1, a, true);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealForwardFull(a);
+ }
+ }
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the input data has to be as
+ * follows:
+ *
+ * * + * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], + * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], + * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0] = Re[0][0], + * a[1] = Re[0][columns/2], + * a[(rows/2)*columns] = Re[rows/2][0], + * a[(rows/2)*columns+1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ */
+ public void realInverse(float[] a, boolean scale) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ rdft2d_sub(-1, a);
+ cdft2d_subth(1, a, scale);
+ xdft2d0_subth1(1, -1, a, scale);
+ } else {
+ rdft2d_sub(-1, a);
+ cdft2d_sub(1, a, scale);
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse(a, r * columns, scale);
+ }
+ }
+ }
+ }
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the input data has to be as
+ * follows:
+ *
+ * * + * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], + * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], + * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0] = Re[0][0], + * a[1] = Re[0][columns/2], + * a[(rows/2)*columns] = Re[rows/2][0], + * a[(rows/2)*columns+1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ *
+ public void realInverse(FloatLargeArray a, boolean scale) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ rdft2d_sub(-1, a);
+ cdft2d_subth(1, a, scale);
+ xdft2d0_subth1(1, -1, a, scale);
+ } else {
+ rdft2d_sub(-1, a);
+ cdft2d_sub(1, a, scale);
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realInverse(a, r * columnsl, scale);
+ }
+ }
+ }
+ } */
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method only works when the sizes of both dimensions are
+ * power-of-two numbers. The physical layout of the input data has to be as
+ * follows:
+ *
+ * * + * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], + * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], + * 0<k1<rows, 0<k2<columns/2, + * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], + * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], + * 0<k2<columns/2, + * a[k1][0] = Re[k1][0] = Re[rows-k1][0], + * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], + * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], + * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], + * 0<k1<rows/2, + * a[0][0] = Re[0][0], + * a[0][1] = Re[0][columns/2], + * a[rows/2][0] = Re[rows/2][0], + * a[rows/2][1] = Re[rows/2][columns/2] + *+ * + * This method computes only half of the elements of the real transform. The + * other half satisfies the symmetry condition. If you want the full real + * inverse transform, use
realInverseFull.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ */
+ public void realInverse(float[][] a, boolean scale) {
+ if (isPowerOfTwo == false) {
+ throw new IllegalArgumentException("rows and columns must be power of two numbers");
+ } else {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ rdft2d_sub(-1, a);
+ cdft2d_subth(1, a, scale);
+ xdft2d0_subth1(1, -1, a, scale);
+ } else {
+ rdft2d_sub(-1, a);
+ cdft2d_sub(1, a, scale);
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse(a[r], scale);
+ }
+ }
+ }
+ }
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method computes full real inverse transform, i.e. you will get the
+ * same result as from complexInverse called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows*2*columns, with only the first rows*columns
+ * elements filled with real data.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ */
+ public void realInverseFull(float[] a, boolean scale) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth2(1, -1, a, scale);
+ cdft2d_subth(1, a, scale);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse2(a, r * columns, scale);
+ }
+ cdft2d_sub(1, a, scale);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealInverseFull(a, scale);
+ }
+ }
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method computes full real inverse transform, i.e. you will get the
+ * same result as from complexInverse called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows*2*columns, with only the first rows*columns
+ * elements filled with real data.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ *
+ public void realInverseFull(FloatLargeArray a, boolean scale) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth2(1, -1, a, scale);
+ cdft2d_subth(1, a, scale);
+ rdft2d_sub(1, a);
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realInverse2(a, r * columnsl, scale);
+ }
+ cdft2d_sub(1, a, scale);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealInverseFull(a, scale);
+ }
+ } */
+
+ /**
+ * Computes 2D inverse DFT of real data leaving the result in a
+ * . This method computes full real inverse transform, i.e. you will get the
+ * same result as from complexInverse called with all imaginary
+ * part equal 0. Because the result is stored in a, the input
+ * array must be of size rows by 2*columns, with only the first rows by
+ * columns elements filled with real data.
+ *
+ * @param a data to transform
+ *
+ * @param scale if true then scaling is performed
+ */
+ public void realInverseFull(float[][] a, boolean scale) {
+ if (isPowerOfTwo) {
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads) {
+ xdft2d0_subth2(1, -1, a, scale);
+ cdft2d_subth(1, a, scale);
+ rdft2d_sub(1, a);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse2(a[r], 0, scale);
+ }
+ cdft2d_sub(1, a, scale);
+ rdft2d_sub(1, a);
+ }
+ fillSymmetric(a);
+ } else {
+ mixedRadixRealInverseFull(a, scale);
+ }
+ }
+
+ private void mixedRadixRealForwardFull(final float[][] a) {
+ final int n2d2 = columns / 2 + 1;
+ final float[][] temp = new float[n2d2][2 * rows];
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstRow; i < lastRow; i++) {
+ fftColumns.realForward(a[i]);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r][0]; //first column is always real
+ }
+ fftRows.realForwardFull(temp[0]);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstColumn = 1 + l * p;
+ final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int c = firstColumn; c < lastColumn; c++) {
+ int idx2 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ temp[c][idx1] = a[r][idx2];
+ temp[c][idx1 + 1] = a[r][idx2 + 1];
+ }
+ fftRows.complexForward(temp[c]);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r][1];
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp[n2d2 - 1]);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = n2d2 - 1;
+ temp[idx2][idx1] = a[r][2 * idx2];
+ temp[idx2][idx1 + 1] = a[r][1];
+ }
+ fftRows.complexForward(temp[n2d2 - 1]);
+
+ }
+
+ p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx2 = 2 * c;
+ a[r][idx2] = temp[c][idx1];
+ a[r][idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = 1 + l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx3 = rows - r;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[0][idx1] = a[0][idx2];
+ a[0][idx1 + 1] = -a[0][idx2 + 1];
+ a[r][idx1] = a[idx3][idx2];
+ a[r][idx1 + 1] = -a[idx3][idx2 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a[r]);
+ }
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r][0]; //first column is always real
+ }
+ fftRows.realForwardFull(temp[0]);
+
+ for (int c = 1; c < n2d2 - 1; c++) {
+ int idx2 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ temp[c][idx1] = a[r][idx2];
+ temp[c][idx1 + 1] = a[r][idx2 + 1];
+ }
+ fftRows.complexForward(temp[c]);
+ }
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r][1];
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp[n2d2 - 1]);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = n2d2 - 1;
+ temp[idx2][idx1] = a[r][2 * idx2];
+ temp[idx2][idx1 + 1] = a[r][1];
+ }
+ fftRows.complexForward(temp[n2d2 - 1]);
+
+ }
+
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx2 = 2 * c;
+ a[r][idx2] = temp[c][idx1];
+ a[r][idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+
+ //fill symmetric
+ for (int r = 1; r < rows; r++) {
+ int idx3 = rows - r;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[0][idx1] = a[0][idx2];
+ a[0][idx1 + 1] = -a[0][idx2 + 1];
+ a[r][idx1] = a[idx3][idx2];
+ a[r][idx1 + 1] = -a[idx3][idx2 + 1];
+ }
+ }
+ }
+ }
+
+ private void mixedRadixRealForwardFull(final float[] a) {
+ final int rowStride = 2 * columns;
+ final int n2d2 = columns / 2 + 1;
+ final float[][] temp = new float[n2d2][2 * rows];
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstRow; i < lastRow; i++) {
+ fftColumns.realForward(a, i * columns);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r * columns]; //first column is always real
+ }
+ fftRows.realForwardFull(temp[0]);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstColumn = 1 + l * p;
+ final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int c = firstColumn; c < lastColumn; c++) {
+ int idx0 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns + idx0;
+ temp[c][idx1] = a[idx2];
+ temp[c][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexForward(temp[c]);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r * columns + 1];
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp[n2d2 - 1]);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns;
+ int idx3 = n2d2 - 1;
+ temp[idx3][idx1] = a[idx2 + 2 * idx3];
+ temp[idx3][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexForward(temp[n2d2 - 1]);
+ }
+
+ p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx0 = 2 * c;
+ int idx2 = r * rowStride + idx0;
+ a[idx2] = temp[c][idx1];
+ a[idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = 1 + l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx5 = r * rowStride;
+ int idx6 = (rows - r + 1) * rowStride;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[idx1] = a[idx2];
+ a[idx1 + 1] = -a[idx2 + 1];
+ int idx3 = idx5 + idx1;
+ int idx4 = idx6 - idx1;
+ a[idx3] = a[idx4];
+ a[idx3 + 1] = -a[idx4 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realForward(a, r * columns);
+ }
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r * columns]; //first column is always real
+ }
+ fftRows.realForwardFull(temp[0]);
+
+ for (int c = 1; c < n2d2 - 1; c++) {
+ int idx0 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns + idx0;
+ temp[c][idx1] = a[idx2];
+ temp[c][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexForward(temp[c]);
+ }
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r * columns + 1];
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp[n2d2 - 1]);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns;
+ int idx3 = n2d2 - 1;
+ temp[idx3][idx1] = a[idx2 + 2 * idx3];
+ temp[idx3][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexForward(temp[n2d2 - 1]);
+ }
+
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx0 = 2 * c;
+ int idx2 = r * rowStride + idx0;
+ a[idx2] = temp[c][idx1];
+ a[idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+
+ //fill symmetric
+ for (int r = 1; r < rows; r++) {
+ int idx5 = r * rowStride;
+ int idx6 = (rows - r + 1) * rowStride;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[idx1] = a[idx2];
+ a[idx1 + 1] = -a[idx2 + 1];
+ int idx3 = idx5 + idx1;
+ int idx4 = idx6 - idx1;
+ a[idx3] = a[idx4];
+ a[idx3 + 1] = -a[idx4 + 1];
+ }
+ }
+ }
+ }
+/*
+ private void mixedRadixRealForwardFull(final FloatLargeArray a) {
+ final long rowStride = 2 * columnsl;
+ final long n2d2 = columnsl / 2 + 1;
+ final FloatLargeArray temp = new FloatLargeArray(n2d2 * 2 * rowsl, false);
+ final long temp_stride = 2 * rowsl;
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ long p = rowsl / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstRow; i < lastRow; i++) {
+ fftColumns.realForward(a, i * columnsl);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
+ }
+ fftRows.realForwardFull(temp);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstColumn = 1 + l * p;
+ final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long c = firstColumn; c < lastColumn; c++) {
+ long idx0 = 2 * c;
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl + idx0;
+ temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
+ temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexForward(temp, c * temp_stride);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columnsl % 2) == 0) {
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
+
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl;
+ long idx3 = n2d2 - 1;
+ temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
+ temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
+ }
+
+ p = rowsl / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long r = firstRow; r < lastRow; r++) {
+ long idx1 = 2 * r;
+ for (long c = 0; c < n2d2; c++) {
+ long idx0 = 2 * c;
+ long idx2 = r * rowStride + idx0;
+ a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
+ a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = 1 + l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long r = firstRow; r < lastRow; r++) {
+ long idx5 = r * rowStride;
+ long idx6 = (rowsl - r + 1) * rowStride;
+ for (long c = n2d2; c < columnsl; c++) {
+ long idx1 = 2 * c;
+ long idx2 = 2 * (columnsl - c);
+ a.setDouble(idx1, a.getFloat(idx2));
+ a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
+ long idx3 = idx5 + idx1;
+ long idx4 = idx6 - idx1;
+ a.setDouble(idx3, a.getFloat(idx4));
+ a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realForward(a, r * columnsl);
+ }
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
+ }
+ fftRows.realForwardFull(temp);
+
+ for (long c = 1; c < n2d2 - 1; c++) {
+ long idx0 = 2 * c;
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl + idx0;
+ temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
+ temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexForward(temp, c * temp_stride);
+ }
+
+ if ((columnsl % 2) == 0) {
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
+ //imaginary part = 0;
+ }
+ fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
+
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl;
+ long idx3 = n2d2 - 1;
+ temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
+ temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
+ }
+
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ for (long c = 0; c < n2d2; c++) {
+ long idx0 = 2 * c;
+ long idx2 = r * rowStride + idx0;
+ a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
+ a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
+ }
+ }
+
+ //fill symmetric
+ for (long r = 1; r < rowsl; r++) {
+ long idx5 = r * rowStride;
+ long idx6 = (rowsl - r + 1) * rowStride;
+ for (long c = n2d2; c < columnsl; c++) {
+ long idx1 = 2 * c;
+ long idx2 = 2 * (columnsl - c);
+ a.setDouble(idx1, a.getFloat(idx2));
+ a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
+ long idx3 = idx5 + idx1;
+ long idx4 = idx6 - idx1;
+ a.setDouble(idx3, a.getFloat(idx4));
+ a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
+ }
+ }
+ }
+ }
+*/
+ private void mixedRadixRealInverseFull(final float[][] a, final boolean scale) {
+ final int n2d2 = columns / 2 + 1;
+ final float[][] temp = new float[n2d2][2 * rows];
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstRow; i < lastRow; i++) {
+ fftColumns.realInverse2(a[i], 0, scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r][0]; //first column is always real
+ }
+ fftRows.realInverseFull(temp[0], scale);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstColumn = 1 + l * p;
+ final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int c = firstColumn; c < lastColumn; c++) {
+ int idx2 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ temp[c][idx1] = a[r][idx2];
+ temp[c][idx1 + 1] = a[r][idx2 + 1];
+ }
+ fftRows.complexInverse(temp[c], scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r][1];
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp[n2d2 - 1], scale);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = n2d2 - 1;
+ temp[idx2][idx1] = a[r][2 * idx2];
+ temp[idx2][idx1 + 1] = a[r][1];
+ }
+ fftRows.complexInverse(temp[n2d2 - 1], scale);
+
+ }
+
+ p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx2 = 2 * c;
+ a[r][idx2] = temp[c][idx1];
+ a[r][idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = 1 + l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx3 = rows - r;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[0][idx1] = a[0][idx2];
+ a[0][idx1 + 1] = -a[0][idx2 + 1];
+ a[r][idx1] = a[idx3][idx2];
+ a[r][idx1 + 1] = -a[idx3][idx2 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse2(a[r], 0, scale);
+ }
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r][0]; //first column is always real
+ }
+ fftRows.realInverseFull(temp[0], scale);
+
+ for (int c = 1; c < n2d2 - 1; c++) {
+ int idx2 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ temp[c][idx1] = a[r][idx2];
+ temp[c][idx1 + 1] = a[r][idx2 + 1];
+ }
+ fftRows.complexInverse(temp[c], scale);
+ }
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r][1];
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp[n2d2 - 1], scale);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = n2d2 - 1;
+ temp[idx2][idx1] = a[r][2 * idx2];
+ temp[idx2][idx1 + 1] = a[r][1];
+ }
+ fftRows.complexInverse(temp[n2d2 - 1], scale);
+
+ }
+
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx2 = 2 * c;
+ a[r][idx2] = temp[c][idx1];
+ a[r][idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+
+ //fill symmetric
+ for (int r = 1; r < rows; r++) {
+ int idx3 = rows - r;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[0][idx1] = a[0][idx2];
+ a[0][idx1 + 1] = -a[0][idx2 + 1];
+ a[r][idx1] = a[idx3][idx2];
+ a[r][idx1 + 1] = -a[idx3][idx2 + 1];
+ }
+ }
+ }
+ }
+
+ private void mixedRadixRealInverseFull(final float[] a, final boolean scale) {
+ final int rowStride = 2 * columns;
+ final int n2d2 = columns / 2 + 1;
+ final float[][] temp = new float[n2d2][2 * rows];
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int i = firstRow; i < lastRow; i++) {
+ fftColumns.realInverse2(a, i * columns, scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r * columns]; //first column is always real
+ }
+ fftRows.realInverseFull(temp[0], scale);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstColumn = 1 + l * p;
+ final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int c = firstColumn; c < lastColumn; c++) {
+ int idx0 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns + idx0;
+ temp[c][idx1] = a[idx2];
+ temp[c][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexInverse(temp[c], scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r * columns + 1];
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp[n2d2 - 1], scale);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns;
+ int idx3 = n2d2 - 1;
+ temp[idx3][idx1] = a[idx2 + 2 * idx3];
+ temp[idx3][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexInverse(temp[n2d2 - 1], scale);
+ }
+
+ p = rows / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx0 = 2 * c;
+ int idx2 = r * rowStride + idx0;
+ a[idx2] = temp[c][idx1];
+ a[idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final int firstRow = 1 + l * p;
+ final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (int r = firstRow; r < lastRow; r++) {
+ int idx5 = r * rowStride;
+ int idx6 = (rows - r + 1) * rowStride;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[idx1] = a[idx2];
+ a[idx1 + 1] = -a[idx2 + 1];
+ int idx3 = idx5 + idx1;
+ int idx4 = idx6 - idx1;
+ a[idx3] = a[idx4];
+ a[idx3 + 1] = -a[idx4 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ for (int r = 0; r < rows; r++) {
+ fftColumns.realInverse2(a, r * columns, scale);
+ }
+ for (int r = 0; r < rows; r++) {
+ temp[0][r] = a[r * columns]; //first column is always real
+ }
+ fftRows.realInverseFull(temp[0], scale);
+
+ for (int c = 1; c < n2d2 - 1; c++) {
+ int idx0 = 2 * c;
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns + idx0;
+ temp[c][idx1] = a[idx2];
+ temp[c][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexInverse(temp[c], scale);
+ }
+
+ if ((columns % 2) == 0) {
+ for (int r = 0; r < rows; r++) {
+ temp[n2d2 - 1][r] = a[r * columns + 1];
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp[n2d2 - 1], scale);
+
+ } else {
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ int idx2 = r * columns;
+ int idx3 = n2d2 - 1;
+ temp[idx3][idx1] = a[idx2 + 2 * idx3];
+ temp[idx3][idx1 + 1] = a[idx2 + 1];
+ }
+ fftRows.complexInverse(temp[n2d2 - 1], scale);
+ }
+
+ for (int r = 0; r < rows; r++) {
+ int idx1 = 2 * r;
+ for (int c = 0; c < n2d2; c++) {
+ int idx0 = 2 * c;
+ int idx2 = r * rowStride + idx0;
+ a[idx2] = temp[c][idx1];
+ a[idx2 + 1] = temp[c][idx1 + 1];
+ }
+ }
+
+ //fill symmetric
+ for (int r = 1; r < rows; r++) {
+ int idx5 = r * rowStride;
+ int idx6 = (rows - r + 1) * rowStride;
+ for (int c = n2d2; c < columns; c++) {
+ int idx1 = 2 * c;
+ int idx2 = 2 * (columns - c);
+ a[idx1] = a[idx2];
+ a[idx1 + 1] = -a[idx2 + 1];
+ int idx3 = idx5 + idx1;
+ int idx4 = idx6 - idx1;
+ a[idx3] = a[idx4];
+ a[idx3 + 1] = -a[idx4 + 1];
+ }
+ }
+ }
+ }
+/*
+ private void mixedRadixRealInverseFull(final FloatLargeArray a, final boolean scale) {
+ final long rowStride = 2 * columnsl;
+ final long n2d2 = columnsl / 2 + 1;
+ final FloatLargeArray temp = new FloatLargeArray(n2d2 * 2 * rowsl, false);
+ final long temp_stride = 2 * rowsl;
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ long p = rowsl / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long i = firstRow; i < lastRow; i++) {
+ fftColumns.realInverse2(a, i * columnsl, scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
+ }
+ fftRows.realInverseFull(temp, scale);
+
+ p = (n2d2 - 2) / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstColumn = 1 + l * p;
+ final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long c = firstColumn; c < lastColumn; c++) {
+ long idx0 = 2 * c;
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl + idx0;
+ temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
+ temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexInverse(temp, c * temp_stride, scale);
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ if ((columnsl % 2) == 0) {
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
+
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl;
+ long idx3 = n2d2 - 1;
+ temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
+ temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
+ }
+
+ p = rowsl / nthreads;
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long r = firstRow; r < lastRow; r++) {
+ long idx1 = 2 * r;
+ for (long c = 0; c < n2d2; c++) {
+ long idx0 = 2 * c;
+ long idx2 = r * rowStride + idx0;
+ a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
+ a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ for (int l = 0; l < nthreads; l++) {
+ final long firstRow = 1 + l * p;
+ final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
+ futures[l] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ for (long r = firstRow; r < lastRow; r++) {
+ long idx5 = r * rowStride;
+ long idx6 = (rowsl - r + 1) * rowStride;
+ for (long c = n2d2; c < columnsl; c++) {
+ long idx1 = 2 * c;
+ long idx2 = 2 * (columnsl - c);
+ a.setDouble(idx1, a.getFloat(idx2));
+ a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
+ long idx3 = idx5 + idx1;
+ long idx4 = idx6 - idx1;
+ a.setDouble(idx3, a.getFloat(idx4));
+ a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ fftColumns.realInverse2(a, r * columnsl, scale);
+ }
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble(r, a.getFloat(r * columnsl)); //first column is always real
+ }
+ fftRows.realInverseFull(temp, scale);
+
+ for (long c = 1; c < n2d2 - 1; c++) {
+ long idx0 = 2 * c;
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl + idx0;
+ temp.setDouble(c * temp_stride + idx1, a.getFloat(idx2));
+ temp.setDouble(c * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexInverse(temp, c * temp_stride, scale);
+ }
+
+ if ((columnsl % 2) == 0) {
+ for (long r = 0; r < rowsl; r++) {
+ temp.setDouble((n2d2 - 1) * temp_stride + r, a.getFloat(r * columnsl + 1));
+ //imaginary part = 0;
+ }
+ fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
+
+ } else {
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ long idx2 = r * columnsl;
+ long idx3 = n2d2 - 1;
+ temp.setDouble(idx3 * temp_stride + idx1, a.getFloat(idx2 + 2 * idx3));
+ temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getFloat(idx2 + 1));
+ }
+ fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
+ }
+
+ for (long r = 0; r < rowsl; r++) {
+ long idx1 = 2 * r;
+ for (long c = 0; c < n2d2; c++) {
+ long idx0 = 2 * c;
+ long idx2 = r * rowStride + idx0;
+ a.setDouble(idx2, temp.getFloat(c * temp_stride + idx1));
+ a.setDouble(idx2 + 1, temp.getFloat(c * temp_stride + idx1 + 1));
+ }
+ }
+
+ //fill symmetric
+ for (long r = 1; r < rowsl; r++) {
+ long idx5 = r * rowStride;
+ long idx6 = (rowsl - r + 1) * rowStride;
+ for (long c = n2d2; c < columnsl; c++) {
+ long idx1 = 2 * c;
+ long idx2 = 2 * (columnsl - c);
+ a.setDouble(idx1, a.getFloat(idx2));
+ a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
+ long idx3 = idx5 + idx1;
+ long idx4 = idx6 - idx1;
+ a.setDouble(idx3, a.getFloat(idx4));
+ a.setDouble(idx3 + 1, -a.getFloat(idx4 + 1));
+ }
+ }
+ }
+ }
+*/
+ private void rdft2d_sub(int isgn, float[] a) {
+ int n1h, j;
+ float xi;
+ int idx1, idx2;
+
+ n1h = rows >> 1;
+ if (isgn < 0) {
+ for (int i = 1; i < n1h; i++) {
+ j = rows - i;
+ idx1 = i * columns;
+ idx2 = j * columns;
+ xi = a[idx1] - a[idx2];
+ a[idx1] += a[idx2];
+ a[idx2] = xi;
+ xi = a[idx2 + 1] - a[idx1 + 1];
+ a[idx1 + 1] += a[idx2 + 1];
+ a[idx2 + 1] = xi;
+ }
+ } else {
+ for (int i = 1; i < n1h; i++) {
+ j = rows - i;
+ idx1 = i * columns;
+ idx2 = j * columns;
+ a[idx2] = 0.5f * (a[idx1] - a[idx2]);
+ a[idx1] -= a[idx2];
+ a[idx2 + 1] = 0.5f * (a[idx1 + 1] + a[idx2 + 1]);
+ a[idx1 + 1] -= a[idx2 + 1];
+ }
+ }
+ }
+/*
+ private void rdft2d_sub(int isgn, FloatLargeArray a) {
+ long n1h, j;
+ float xi;
+ long idx1, idx2;
+
+ n1h = rowsl >> 1;
+ if (isgn < 0) {
+ for (long i = 1; i < n1h; i++) {
+ j = rowsl - i;
+ idx1 = i * columnsl;
+ idx2 = j * columnsl;
+ xi = a.getFloat(idx1) - a.getFloat(idx2);
+ a.setDouble(idx1, a.getFloat(idx1) + a.getFloat(idx2));
+ a.setDouble(idx2, xi);
+ xi = a.getFloat(idx2 + 1) - a.getFloat(idx1 + 1);
+ a.setDouble(idx1 + 1, a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1));
+ a.setDouble(idx2 + 1, xi);
+ }
+ } else {
+ for (long i = 1; i < n1h; i++) {
+ j = rowsl - i;
+ idx1 = i * columnsl;
+ idx2 = j * columnsl;
+ a.setDouble(idx2, 0.5f * (a.getFloat(idx1) - a.getFloat(idx2)));
+ a.setDouble(idx1, a.getFloat(idx1) - a.getFloat(idx2));
+ a.setDouble(idx2 + 1, 0.5f * (a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1)));
+ a.setDouble(idx1 + 1, a.getFloat(idx1 + 1) - a.getFloat(idx2 + 1));
+ }
+ }
+ }
+*/
+ private void rdft2d_sub(int isgn, float[][] a) {
+ int n1h, j;
+ float xi;
+
+ n1h = rows >> 1;
+ if (isgn < 0) {
+ for (int i = 1; i < n1h; i++) {
+ j = rows - i;
+ xi = a[i][0] - a[j][0];
+ a[i][0] += a[j][0];
+ a[j][0] = xi;
+ xi = a[j][1] - a[i][1];
+ a[i][1] += a[j][1];
+ a[j][1] = xi;
+ }
+ } else {
+ for (int i = 1; i < n1h; i++) {
+ j = rows - i;
+ a[j][0] = 0.5f * (a[i][0] - a[j][0]);
+ a[i][0] -= a[j][0];
+ a[j][1] = 0.5f * (a[i][1] + a[j][1]);
+ a[i][1] -= a[j][1];
+ }
+ }
+ }
+
+ private void cdft2d_sub(int isgn, float[] a, boolean scale) {
+ int idx1, idx2, idx3, idx4, idx5;
+ int nt = 8 * rows;
+ if (columns == 4) {
+ nt >>= 1;
+ } else if (columns < 4) {
+ nt >>= 2;
+ }
+ float[] t = new float[nt];
+ if (isgn == -1) {
+ if (columns > 4) {
+ for (int c = 0; c < columns; c += 8) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ t[idx4] = a[idx1 + 4];
+ t[idx4 + 1] = a[idx1 + 5];
+ t[idx5] = a[idx1 + 6];
+ t[idx5 + 1] = a[idx1 + 7];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ fftRows.complexForward(t, 4 * rows);
+ fftRows.complexForward(t, 6 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ a[idx1 + 4] = t[idx4];
+ a[idx1 + 5] = t[idx4 + 1];
+ a[idx1 + 6] = t[idx5];
+ a[idx1 + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ }
+ fftRows.complexForward(t, 0);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ }
+ }
+ } else {
+ if (columns > 4) {
+ for (int c = 0; c < columns; c += 8) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ t[idx4] = a[idx1 + 4];
+ t[idx4 + 1] = a[idx1 + 5];
+ t[idx5] = a[idx1 + 6];
+ t[idx5 + 1] = a[idx1 + 7];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ fftRows.complexInverse(t, 4 * rows, scale);
+ fftRows.complexInverse(t, 6 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ a[idx1 + 4] = t[idx4];
+ a[idx1 + 5] = t[idx4 + 1];
+ a[idx1 + 6] = t[idx5];
+ a[idx1 + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns;
+ idx2 = 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ }
+ }
+ }
+ }
+/*
+ private void cdft2d_sub(int isgn, FloatLargeArray a, boolean scale) {
+ long idx1, idx2, idx3, idx4, idx5;
+ long nt = 8 * rowsl;
+ if (columnsl == 4) {
+ nt >>= 1;
+ } else if (columnsl < 4) {
+ nt >>= 2;
+ }
+ FloatLargeArray t = new FloatLargeArray(nt, false);
+ if (isgn == -1) {
+ if (columnsl > 4) {
+ for (long c = 0; c < columnsl; c += 8) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ t.setDouble(idx4, a.getFloat(idx1 + 4));
+ t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
+ t.setDouble(idx5, a.getFloat(idx1 + 6));
+ t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rowsl);
+ fftRows.complexForward(t, 4 * rowsl);
+ fftRows.complexForward(t, 6 * rowsl);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ a.setDouble(idx1 + 4, t.getFloat(idx4));
+ a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
+ a.setDouble(idx1 + 6, t.getFloat(idx5));
+ a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
+ }
+ }
+ } else if (columnsl == 4) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rowsl);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ }
+ } else if (columnsl == 2) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ }
+ fftRows.complexForward(t, 0);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ }
+ }
+ } else {
+ if (columnsl > 4) {
+ for (long c = 0; c < columnsl; c += 8) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ t.setDouble(idx4, a.getFloat(idx1 + 4));
+ t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
+ t.setDouble(idx5, a.getFloat(idx1 + 6));
+ t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rowsl, scale);
+ fftRows.complexInverse(t, 4 * rowsl, scale);
+ fftRows.complexInverse(t, 6 * rowsl, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ a.setDouble(idx1 + 4, t.getFloat(idx4));
+ a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
+ a.setDouble(idx1 + 6, t.getFloat(idx5));
+ a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
+ }
+ }
+ } else if (columnsl == 4) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rowsl, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ }
+ } else if (columnsl == 2) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl;
+ idx2 = 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ }
+ }
+ }
+ }
+*/
+ private void cdft2d_sub(int isgn, float[][] a, boolean scale) {
+ int idx2, idx3, idx4, idx5;
+ int nt = 8 * rows;
+ if (columns == 4) {
+ nt >>= 1;
+ } else if (columns < 4) {
+ nt >>= 2;
+ }
+ float[] t = new float[nt];
+ if (isgn == -1) {
+ if (columns > 4) {
+ for (int c = 0; c < columns; c += 8) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[r][c];
+ t[idx2 + 1] = a[r][c + 1];
+ t[idx3] = a[r][c + 2];
+ t[idx3 + 1] = a[r][c + 3];
+ t[idx4] = a[r][c + 4];
+ t[idx4 + 1] = a[r][c + 5];
+ t[idx5] = a[r][c + 6];
+ t[idx5 + 1] = a[r][c + 7];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ fftRows.complexForward(t, 4 * rows);
+ fftRows.complexForward(t, 6 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[r][c] = t[idx2];
+ a[r][c + 1] = t[idx2 + 1];
+ a[r][c + 2] = t[idx3];
+ a[r][c + 3] = t[idx3 + 1];
+ a[r][c + 4] = t[idx4];
+ a[r][c + 5] = t[idx4 + 1];
+ a[r][c + 6] = t[idx5];
+ a[r][c + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[r][0];
+ t[idx2 + 1] = a[r][1];
+ t[idx3] = a[r][2];
+ t[idx3 + 1] = a[r][3];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[r][0] = t[idx2];
+ a[r][1] = t[idx2 + 1];
+ a[r][2] = t[idx3];
+ a[r][3] = t[idx3 + 1];
+ }
+ } else if (columns == 2) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ t[idx2] = a[r][0];
+ t[idx2 + 1] = a[r][1];
+ }
+ fftRows.complexForward(t, 0);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ a[r][0] = t[idx2];
+ a[r][1] = t[idx2 + 1];
+ }
+ }
+ } else {
+ if (columns > 4) {
+ for (int c = 0; c < columns; c += 8) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[r][c];
+ t[idx2 + 1] = a[r][c + 1];
+ t[idx3] = a[r][c + 2];
+ t[idx3 + 1] = a[r][c + 3];
+ t[idx4] = a[r][c + 4];
+ t[idx4 + 1] = a[r][c + 5];
+ t[idx5] = a[r][c + 6];
+ t[idx5 + 1] = a[r][c + 7];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ fftRows.complexInverse(t, 4 * rows, scale);
+ fftRows.complexInverse(t, 6 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[r][c] = t[idx2];
+ a[r][c + 1] = t[idx2 + 1];
+ a[r][c + 2] = t[idx3];
+ a[r][c + 3] = t[idx3 + 1];
+ a[r][c + 4] = t[idx4];
+ a[r][c + 5] = t[idx4 + 1];
+ a[r][c + 6] = t[idx5];
+ a[r][c + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[r][0];
+ t[idx2 + 1] = a[r][1];
+ t[idx3] = a[r][2];
+ t[idx3 + 1] = a[r][3];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[r][0] = t[idx2];
+ a[r][1] = t[idx2 + 1];
+ a[r][2] = t[idx3];
+ a[r][3] = t[idx3 + 1];
+ }
+ } else if (columns == 2) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ t[idx2] = a[r][0];
+ t[idx2 + 1] = a[r][1];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ a[r][0] = t[idx2];
+ a[r][1] = t[idx2 + 1];
+ }
+ }
+ }
+ }
+
+ private void xdft2d0_subth1(final int icr, final int isgn, final float[] a, final boolean scale) {
+ final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexForward(a, r * columns);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexInverse(a, r * columns, scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realForward(a, r * columns);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realInverse(a, r * columns, scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+/*
+ private void xdft2d0_subth1(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
+ final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.complexForward(a, r * columnsl);
+ }
+ } else {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.complexInverse(a, r * columnsl, scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.realForward(a, r * columnsl);
+ }
+ } else {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.realInverse(a, r * columnsl, scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+*/
+ private void xdft2d0_subth2(final int icr, final int isgn, final float[] a, final boolean scale) {
+ final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexForward(a, r * columns);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexInverse(a, r * columns, scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realForward(a, r * columns);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realInverse2(a, r * columns, scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+/*
+ private void xdft2d0_subth2(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
+ final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final long n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.complexForward(a, r * columnsl);
+ }
+ } else {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.complexInverse(a, r * columnsl, scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.realForward(a, r * columnsl);
+ }
+ } else {
+ for (long r = n0; r < rowsl; r += nthreads) {
+ fftColumns.realInverse2(a, r * columnsl, scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+*/
+ private void xdft2d0_subth1(final int icr, final int isgn, final float[][] a, final boolean scale) {
+ final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexForward(a[r]);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexInverse(a[r], scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realForward(a[r]);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realInverse(a[r], scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+
+ private void xdft2d0_subth2(final int icr, final int isgn, final float[][] a, final boolean scale) {
+ final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
+
+ Future>[] futures = new Future[nthreads];
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ if (icr == 0) {
+ if (isgn == -1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexForward(a[r]);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.complexInverse(a[r], scale);
+ }
+ }
+ } else {
+ if (isgn == 1) {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realForward(a[r]);
+ }
+ } else {
+ for (int r = n0; r < rows; r += nthreads) {
+ fftColumns.realInverse2(a[r], 0, scale);
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+
+ private void cdft2d_subth(final int isgn, final float[] a, final boolean scale) {
+ int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
+ int nt = 8 * rows;
+ if (columns == 4) {
+ nt >>= 1;
+ } else if (columns < 4) {
+ nt >>= 2;
+ }
+ final int ntf = nt;
+ Future>[] futures = new Future[nthread];
+ final int nthreads = nthread;
+ for (int i = 0; i < nthread; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx1, idx2, idx3, idx4, idx5;
+ float[] t = new float[ntf];
+ if (isgn == -1) {
+ if (columns > 4 * nthreads) {
+ for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ t[idx4] = a[idx1 + 4];
+ t[idx4 + 1] = a[idx1 + 5];
+ t[idx5] = a[idx1 + 6];
+ t[idx5 + 1] = a[idx1 + 7];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ fftRows.complexForward(t, 4 * rows);
+ fftRows.complexForward(t, 6 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ a[idx1 + 4] = t[idx4];
+ a[idx1 + 5] = t[idx4 + 1];
+ a[idx1 + 6] = t[idx5];
+ a[idx1 + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 2 * n0;
+ idx2 = 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ }
+ fftRows.complexForward(t, 0);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 2 * n0;
+ idx2 = 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ }
+ }
+ } else {
+ if (columns > 4 * nthreads) {
+ for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ t[idx4] = a[idx1 + 4];
+ t[idx4 + 1] = a[idx1 + 5];
+ t[idx5] = a[idx1 + 6];
+ t[idx5 + 1] = a[idx1 + 7];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ fftRows.complexInverse(t, 4 * rows, scale);
+ fftRows.complexInverse(t, 6 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ a[idx1 + 4] = t[idx4];
+ a[idx1 + 5] = t[idx4 + 1];
+ a[idx1 + 6] = t[idx5];
+ a[idx1 + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ t[idx3] = a[idx1 + 2];
+ t[idx3 + 1] = a[idx1 + 3];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ a[idx1 + 2] = t[idx3];
+ a[idx1 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 2 * n0;
+ idx2 = 2 * r;
+ t[idx2] = a[idx1];
+ t[idx2 + 1] = a[idx1 + 1];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (int r = 0; r < rows; r++) {
+ idx1 = r * columns + 2 * n0;
+ idx2 = 2 * r;
+ a[idx1] = t[idx2];
+ a[idx1 + 1] = t[idx2 + 1];
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+/*
+ private void cdft2d_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
+ int nthread = (int) Math.min(columnsl / 2, ConcurrencyUtils.getNumberOfThreads());
+ long nt = 8 * rowsl;
+ if (columnsl == 4) {
+ nt >>= 1;
+ } else if (columnsl < 4) {
+ nt >>= 2;
+ }
+ final long ntf = nt;
+ Future>[] futures = new Future[nthread];
+ final int nthreads = nthread;
+ for (int i = 0; i < nthread; i++) {
+ final long n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ long idx1, idx2, idx3, idx4, idx5;
+ FloatLargeArray t = new FloatLargeArray(ntf, false);
+ if (isgn == -1) {
+ if (columnsl > 4 * nthreads) {
+ for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ t.setDouble(idx4, a.getFloat(idx1 + 4));
+ t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
+ t.setDouble(idx5, a.getFloat(idx1 + 6));
+ t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rowsl);
+ fftRows.complexForward(t, 4 * rowsl);
+ fftRows.complexForward(t, 6 * rowsl);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ a.setDouble(idx1 + 4, t.getFloat(idx4));
+ a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
+ a.setDouble(idx1 + 6, t.getFloat(idx5));
+ a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
+ }
+ }
+ } else if (columnsl == 4 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rowsl);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ }
+ } else if (columnsl == 2 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 2 * n0;
+ idx2 = 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ }
+ fftRows.complexForward(t, 0);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 2 * n0;
+ idx2 = 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ }
+ }
+ } else {
+ if (columnsl > 4 * nthreads) {
+ for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ t.setDouble(idx4, a.getFloat(idx1 + 4));
+ t.setDouble(idx4 + 1, a.getFloat(idx1 + 5));
+ t.setDouble(idx5, a.getFloat(idx1 + 6));
+ t.setDouble(idx5 + 1, a.getFloat(idx1 + 7));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rowsl, scale);
+ fftRows.complexInverse(t, 4 * rowsl, scale);
+ fftRows.complexInverse(t, 6 * rowsl, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + c;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ idx4 = idx3 + 2 * rowsl;
+ idx5 = idx4 + 2 * rowsl;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ a.setDouble(idx1 + 4, t.getFloat(idx4));
+ a.setDouble(idx1 + 5, t.getFloat(idx4 + 1));
+ a.setDouble(idx1 + 6, t.getFloat(idx5));
+ a.setDouble(idx1 + 7, t.getFloat(idx5 + 1));
+ }
+ }
+ } else if (columnsl == 4 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ t.setDouble(idx3, a.getFloat(idx1 + 2));
+ t.setDouble(idx3 + 1, a.getFloat(idx1 + 3));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rowsl, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 4 * n0;
+ idx2 = 2 * r;
+ idx3 = 2 * rowsl + 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ a.setDouble(idx1 + 2, t.getFloat(idx3));
+ a.setDouble(idx1 + 3, t.getFloat(idx3 + 1));
+ }
+ } else if (columnsl == 2 * nthreads) {
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 2 * n0;
+ idx2 = 2 * r;
+ t.setDouble(idx2, a.getFloat(idx1));
+ t.setDouble(idx2 + 1, a.getFloat(idx1 + 1));
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (long r = 0; r < rowsl; r++) {
+ idx1 = r * columnsl + 2 * n0;
+ idx2 = 2 * r;
+ a.setDouble(idx1, t.getFloat(idx2));
+ a.setDouble(idx1 + 1, t.getFloat(idx2 + 1));
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+*/
+ private void cdft2d_subth(final int isgn, final float[][] a, final boolean scale) {
+ int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
+ int nt = 8 * rows;
+ if (columns == 4) {
+ nt >>= 1;
+ } else if (columns < 4) {
+ nt >>= 2;
+ }
+ final int ntf = nt;
+ Future>[] futures = new Future[nthread];
+ final int nthreads = nthread;
+ for (int i = 0; i < nthreads; i++) {
+ final int n0 = i;
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx2, idx3, idx4, idx5;
+ float[] t = new float[ntf];
+ if (isgn == -1) {
+ if (columns > 4 * nthreads) {
+ for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[r][c];
+ t[idx2 + 1] = a[r][c + 1];
+ t[idx3] = a[r][c + 2];
+ t[idx3 + 1] = a[r][c + 3];
+ t[idx4] = a[r][c + 4];
+ t[idx4 + 1] = a[r][c + 5];
+ t[idx5] = a[r][c + 6];
+ t[idx5 + 1] = a[r][c + 7];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ fftRows.complexForward(t, 4 * rows);
+ fftRows.complexForward(t, 6 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[r][c] = t[idx2];
+ a[r][c + 1] = t[idx2 + 1];
+ a[r][c + 2] = t[idx3];
+ a[r][c + 3] = t[idx3 + 1];
+ a[r][c + 4] = t[idx4];
+ a[r][c + 5] = t[idx4 + 1];
+ a[r][c + 6] = t[idx5];
+ a[r][c + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[r][4 * n0];
+ t[idx2 + 1] = a[r][4 * n0 + 1];
+ t[idx3] = a[r][4 * n0 + 2];
+ t[idx3 + 1] = a[r][4 * n0 + 3];
+ }
+ fftRows.complexForward(t, 0);
+ fftRows.complexForward(t, 2 * rows);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[r][4 * n0] = t[idx2];
+ a[r][4 * n0 + 1] = t[idx2 + 1];
+ a[r][4 * n0 + 2] = t[idx3];
+ a[r][4 * n0 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ t[idx2] = a[r][2 * n0];
+ t[idx2 + 1] = a[r][2 * n0 + 1];
+ }
+ fftRows.complexForward(t, 0);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ a[r][2 * n0] = t[idx2];
+ a[r][2 * n0 + 1] = t[idx2 + 1];
+ }
+ }
+ } else {
+ if (columns > 4 * nthreads) {
+ for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ t[idx2] = a[r][c];
+ t[idx2 + 1] = a[r][c + 1];
+ t[idx3] = a[r][c + 2];
+ t[idx3 + 1] = a[r][c + 3];
+ t[idx4] = a[r][c + 4];
+ t[idx4 + 1] = a[r][c + 5];
+ t[idx5] = a[r][c + 6];
+ t[idx5 + 1] = a[r][c + 7];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ fftRows.complexInverse(t, 4 * rows, scale);
+ fftRows.complexInverse(t, 6 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ idx4 = idx3 + 2 * rows;
+ idx5 = idx4 + 2 * rows;
+ a[r][c] = t[idx2];
+ a[r][c + 1] = t[idx2 + 1];
+ a[r][c + 2] = t[idx3];
+ a[r][c + 3] = t[idx3 + 1];
+ a[r][c + 4] = t[idx4];
+ a[r][c + 5] = t[idx4 + 1];
+ a[r][c + 6] = t[idx5];
+ a[r][c + 7] = t[idx5 + 1];
+ }
+ }
+ } else if (columns == 4 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ t[idx2] = a[r][4 * n0];
+ t[idx2 + 1] = a[r][4 * n0 + 1];
+ t[idx3] = a[r][4 * n0 + 2];
+ t[idx3 + 1] = a[r][4 * n0 + 3];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ fftRows.complexInverse(t, 2 * rows, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ idx3 = 2 * rows + 2 * r;
+ a[r][4 * n0] = t[idx2];
+ a[r][4 * n0 + 1] = t[idx2 + 1];
+ a[r][4 * n0 + 2] = t[idx3];
+ a[r][4 * n0 + 3] = t[idx3 + 1];
+ }
+ } else if (columns == 2 * nthreads) {
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ t[idx2] = a[r][2 * n0];
+ t[idx2 + 1] = a[r][2 * n0 + 1];
+ }
+ fftRows.complexInverse(t, 0, scale);
+ for (int r = 0; r < rows; r++) {
+ idx2 = 2 * r;
+ a[r][2 * n0] = t[idx2];
+ a[r][2 * n0 + 1] = t[idx2 + 1];
+ }
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ }
+
+ private void fillSymmetric(final float[] a) {
+ final int twon2 = 2 * columns;
+ int idx1, idx2, idx3, idx4;
+ int n1d2 = rows / 2;
+
+ for (int r = (rows - 1); r >= 1; r--) {
+ idx1 = r * columns;
+ idx2 = 2 * idx1;
+ for (int c = 0; c < columns; c += 2) {
+ a[idx2 + c] = a[idx1 + c];
+ a[idx1 + c] = 0;
+ a[idx2 + c + 1] = a[idx1 + c + 1];
+ a[idx1 + c + 1] = 0;
+ }
+ }
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int l1k = n1d2 / nthreads;
+ final int newn2 = 2 * columns;
+ for (int i = 0; i < nthreads; i++) {
+ final int l1offa, l1stopa, l2offa, l2stopa;
+ if (i == 0) {
+ l1offa = i * l1k + 1;
+ } else {
+ l1offa = i * l1k;
+ }
+ l1stopa = i * l1k + l1k;
+ l2offa = i * l1k;
+ if (i == nthreads - 1) {
+ l2stopa = i * l1k + l1k + 1;
+ } else {
+ l2stopa = i * l1k + l1k;
+ }
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx1, idx2, idx3, idx4;
+
+ for (int r = l1offa; r < l1stopa; r++) {
+ idx1 = r * newn2;
+ idx2 = (rows - r) * newn2;
+ idx3 = idx1 + columns;
+ a[idx3] = a[idx2 + 1];
+ a[idx3 + 1] = -a[idx2];
+ }
+ for (int r = l1offa; r < l1stopa; r++) {
+ idx1 = r * newn2;
+ idx3 = (rows - r + 1) * newn2;
+ for (int c = columns + 2; c < newn2; c += 2) {
+ idx2 = idx3 - c;
+ idx4 = idx1 + c;
+ a[idx4] = a[idx2];
+ a[idx4 + 1] = -a[idx2 + 1];
+
+ }
+ }
+ for (int r = l2offa; r < l2stopa; r++) {
+ idx3 = ((rows - r) % rows) * newn2;
+ idx4 = r * newn2;
+ for (int c = 0; c < newn2; c += 2) {
+ idx1 = idx3 + (newn2 - c) % newn2;
+ idx2 = idx4 + c;
+ a[idx1] = a[idx2];
+ a[idx1 + 1] = -a[idx2 + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (int r = 1; r < n1d2; r++) {
+ idx2 = r * twon2;
+ idx3 = (rows - r) * twon2;
+ a[idx2 + columns] = a[idx3 + 1];
+ a[idx2 + columns + 1] = -a[idx3];
+ }
+
+ for (int r = 1; r < n1d2; r++) {
+ idx2 = r * twon2;
+ idx3 = (rows - r + 1) * twon2;
+ for (int c = columns + 2; c < twon2; c += 2) {
+ a[idx2 + c] = a[idx3 - c];
+ a[idx2 + c + 1] = -a[idx3 - c + 1];
+
+ }
+ }
+ for (int r = 0; r <= rows / 2; r++) {
+ idx1 = r * twon2;
+ idx4 = ((rows - r) % rows) * twon2;
+ for (int c = 0; c < twon2; c += 2) {
+ idx2 = idx1 + c;
+ idx3 = idx4 + (twon2 - c) % twon2;
+ a[idx3] = a[idx2];
+ a[idx3 + 1] = -a[idx2 + 1];
+ }
+ }
+ }
+ a[columns] = -a[1];
+ a[1] = 0;
+ idx1 = n1d2 * twon2;
+ a[idx1 + columns] = -a[idx1 + 1];
+ a[idx1 + 1] = 0;
+ a[idx1 + columns + 1] = 0;
+ }
+/*
+ private void fillSymmetric(final FloatLargeArray a) {
+ final long twon2 = 2 * columnsl;
+ long idx1, idx2, idx3, idx4;
+ long n1d2 = rowsl / 2;
+
+ for (long r = (rowsl - 1); r >= 1; r--) {
+ idx1 = r * columnsl;
+ idx2 = 2 * idx1;
+ for (long c = 0; c < columnsl; c += 2) {
+ a.setDouble(idx2 + c, a.getFloat(idx1 + c));
+ a.setDouble(idx1 + c, 0);
+ a.setDouble(idx2 + c + 1, a.getFloat(idx1 + c + 1));
+ a.setDouble(idx1 + c + 1, 0);
+ }
+ }
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ long l1k = n1d2 / nthreads;
+ final long newn2 = 2 * columnsl;
+ for (int i = 0; i < nthreads; i++) {
+ final long l1offa, l1stopa, l2offa, l2stopa;
+ if (i == 0) {
+ l1offa = i * l1k + 1;
+ } else {
+ l1offa = i * l1k;
+ }
+ l1stopa = i * l1k + l1k;
+ l2offa = i * l1k;
+ if (i == nthreads - 1) {
+ l2stopa = i * l1k + l1k + 1;
+ } else {
+ l2stopa = i * l1k + l1k;
+ }
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ long idx1, idx2, idx3, idx4;
+
+ for (long r = l1offa; r < l1stopa; r++) {
+ idx1 = r * newn2;
+ idx2 = (rowsl - r) * newn2;
+ idx3 = idx1 + columnsl;
+ a.setDouble(idx3, a.getFloat(idx2 + 1));
+ a.setDouble(idx3 + 1, -a.getFloat(idx2));
+ }
+ for (long r = l1offa; r < l1stopa; r++) {
+ idx1 = r * newn2;
+ idx3 = (rowsl - r + 1) * newn2;
+ for (long c = columnsl + 2; c < newn2; c += 2) {
+ idx2 = idx3 - c;
+ idx4 = idx1 + c;
+ a.setDouble(idx4, a.getFloat(idx2));
+ a.setDouble(idx4 + 1, -a.getFloat(idx2 + 1));
+
+ }
+ }
+ for (long r = l2offa; r < l2stopa; r++) {
+ idx3 = ((rowsl - r) % rowsl) * newn2;
+ idx4 = r * newn2;
+ for (long c = 0; c < newn2; c += 2) {
+ idx1 = idx3 + (newn2 - c) % newn2;
+ idx2 = idx4 + c;
+ a.setDouble(idx1, a.getFloat(idx2));
+ a.setDouble(idx1 + 1, -a.getFloat(idx2 + 1));
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+
+ } else {
+
+ for (long r = 1; r < n1d2; r++) {
+ idx2 = r * twon2;
+ idx3 = (rowsl - r) * twon2;
+ a.setDouble(idx2 + columnsl, a.getFloat(idx3 + 1));
+ a.setDouble(idx2 + columnsl + 1, -a.getFloat(idx3));
+ }
+
+ for (long r = 1; r < n1d2; r++) {
+ idx2 = r * twon2;
+ idx3 = (rowsl - r + 1) * twon2;
+ for (long c = columnsl + 2; c < twon2; c += 2) {
+ a.setDouble(idx2 + c, a.getFloat(idx3 - c));
+ a.setDouble(idx2 + c + 1, -a.getFloat(idx3 - c + 1));
+
+ }
+ }
+ for (long r = 0; r <= rowsl / 2; r++) {
+ idx1 = r * twon2;
+ idx4 = ((rowsl - r) % rowsl) * twon2;
+ for (long c = 0; c < twon2; c += 2) {
+ idx2 = idx1 + c;
+ idx3 = idx4 + (twon2 - c) % twon2;
+ a.setDouble(idx3, a.getFloat(idx2));
+ a.setDouble(idx3 + 1, -a.getFloat(idx2 + 1));
+ }
+ }
+ }
+ a.setDouble(columnsl, -a.getFloat(1));
+ a.setDouble(1, 0);
+ idx1 = n1d2 * twon2;
+ a.setDouble(idx1 + columnsl, -a.getFloat(idx1 + 1));
+ a.setDouble(idx1 + 1, 0);
+ a.setDouble(idx1 + columnsl + 1, 0);
+ }
+*/
+ private void fillSymmetric(final float[][] a) {
+ final int newn2 = 2 * columns;
+ int n1d2 = rows / 2;
+
+ int nthreads = ConcurrencyUtils.getNumberOfThreads();
+ if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
+ Future>[] futures = new Future[nthreads];
+ int l1k = n1d2 / nthreads;
+ for (int i = 0; i < nthreads; i++) {
+ final int l1offa, l1stopa, l2offa, l2stopa;
+ if (i == 0) {
+ l1offa = i * l1k + 1;
+ } else {
+ l1offa = i * l1k;
+ }
+ l1stopa = i * l1k + l1k;
+ l2offa = i * l1k;
+ if (i == nthreads - 1) {
+ l2stopa = i * l1k + l1k + 1;
+ } else {
+ l2stopa = i * l1k + l1k;
+ }
+ futures[i] = ConcurrencyUtils.submit(new Runnable() {
+ public void run() {
+ int idx1, idx2;
+ for (int r = l1offa; r < l1stopa; r++) {
+ idx1 = rows - r;
+ a[r][columns] = a[idx1][1];
+ a[r][columns + 1] = -a[idx1][0];
+ }
+ for (int r = l1offa; r < l1stopa; r++) {
+ idx1 = rows - r;
+ for (int c = columns + 2; c < newn2; c += 2) {
+ idx2 = newn2 - c;
+ a[r][c] = a[idx1][idx2];
+ a[r][c + 1] = -a[idx1][idx2 + 1];
+
+ }
+ }
+ for (int r = l2offa; r < l2stopa; r++) {
+ idx1 = (rows - r) % rows;
+ for (int c = 0; c < newn2; c = c + 2) {
+ idx2 = (newn2 - c) % newn2;
+ a[idx1][idx2] = a[r][c];
+ a[idx1][idx2 + 1] = -a[r][c + 1];
+ }
+ }
+ }
+ });
+ }
+ ConcurrencyUtils.waitForCompletion(futures);
+ } else {
+
+ for (int r = 1; r < n1d2; r++) {
+ int idx1 = rows - r;
+ a[r][columns] = a[idx1][1];
+ a[r][columns + 1] = -a[idx1][0];
+ }
+ for (int r = 1; r < n1d2; r++) {
+ int idx1 = rows - r;
+ for (int c = columns + 2; c < newn2; c += 2) {
+ int idx2 = newn2 - c;
+ a[r][c] = a[idx1][idx2];
+ a[r][c + 1] = -a[idx1][idx2 + 1];
+ }
+ }
+ for (int r = 0; r <= rows / 2; r++) {
+ int idx1 = (rows - r) % rows;
+ for (int c = 0; c < newn2; c += 2) {
+ int idx2 = (newn2 - c) % newn2;
+ a[idx1][idx2] = a[r][c];
+ a[idx1][idx2 + 1] = -a[r][c + 1];
+ }
+ }
+ }
+ a[0][columns] = -a[0][1];
+ a[0][1] = 0;
+ a[n1d2][columns] = -a[n1d2][1];
+ a[n1d2][1] = 0;
+ a[n1d2][columns + 1] = 0;
+ }
+}
diff --git a/src/main/java/org/jtransforms/fft/FloatFFT_3D.java b/org/fairsim/extern/jtransforms/FloatFFT_3D.java
similarity index 97%
rename from src/main/java/org/jtransforms/fft/FloatFFT_3D.java
rename to org/fairsim/extern/jtransforms/FloatFFT_3D.java
index f24b208..dc72845 100644
--- a/src/main/java/org/jtransforms/fft/FloatFFT_3D.java
+++ b/org/fairsim/extern/jtransforms/FloatFFT_3D.java
@@ -24,12 +24,18 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
+
+// Code modified for inclusion with fairSIM:
+// - changed package name
+// - Commented out all dependence on ...LargeArray
+// - based on JTransforms 3.1, git ede249c9824262bd9b5f571e56f7a0fa596f6f20
+
+package org.fairsim.extern.jtransforms;
import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
+//import org.jtransforms.utils.ConcurrencyUtils;
+//import pl.edu.icm.jlargearrays.FloatLargeArray;
+//import pl.edu.icm.jlargearrays.Utilities;
/**
* Computes 3D Discrete Fourier Transform (DFT) of complex and real, single
@@ -314,6 +320,7 @@ public void run() {
*
* @param a data to transform
*/
+ /*
public void complexForward(final FloatLargeArray a) {
int nthreads = ConcurrencyUtils.getNumberOfThreads();
if (isPowerOfTwo) {
@@ -469,7 +476,7 @@ public void run() {
sliceStridel = rowsl * columnsl;
rowStridel = columnsl;
}
- }
+ } */
/**
* Computes 3D forward DFT of complex data leaving the result in
@@ -824,6 +831,7 @@ public void run() {
* @param a data to transform
* @param scale if true then scaling is performed
*/
+ /*
public void complexInverse(final FloatLargeArray a, final boolean scale) {
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -980,7 +988,7 @@ public void run() {
sliceStridel = rowsl * columnsl;
rowStridel = columnsl;
}
- }
+ } */
/**
* Computes 3D inverse DFT of complex data leaving the result in
@@ -1254,6 +1262,7 @@ public void realForward(float[] a) {
*
* @param a data to transform
*/
+ /*
public void realForward(FloatLargeArray a) {
if (isPowerOfTwo == false) {
throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
@@ -1269,7 +1278,7 @@ public void realForward(FloatLargeArray a) {
rdft3d_sub(1, a);
}
}
- }
+ } */
/**
* Computes 3D forward DFT of real data leaving the result in a
@@ -1371,6 +1380,7 @@ public void realForwardFull(float[] a) {
*
* @param a data to transform
*/
+ /*
public void realForwardFull(FloatLargeArray a) {
if (isPowerOfTwo) {
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -1388,6 +1398,7 @@ public void realForwardFull(FloatLargeArray a) {
mixedRadixRealForwardFull(a);
}
}
+ */
/**
* Computes 3D forward DFT of real data leaving the result in a
@@ -1538,6 +1549,7 @@ public void realInverse(float[] a, boolean scale) {
*
* @param scale if true then scaling is performed
*/
+ /*
public void realInverse(FloatLargeArray a, boolean scale) {
if (isPowerOfTwo == false) {
throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
@@ -1553,7 +1565,7 @@ public void realInverse(FloatLargeArray a, boolean scale) {
xdft3da_sub1(1, 1, a, scale);
}
}
- }
+ } */
/**
* Computes 3D inverse DFT of real data leaving the result in a
@@ -1653,6 +1665,7 @@ public void realInverseFull(float[] a, boolean scale) {
* @param a data to transform
* @param scale if true then scaling is performed
*/
+ /*
public void realInverseFull(FloatLargeArray a, boolean scale) {
if (isPowerOfTwo) {
int nthreads = ConcurrencyUtils.getNumberOfThreads();
@@ -1669,7 +1682,7 @@ public void realInverseFull(FloatLargeArray a, boolean scale) {
} else {
mixedRadixRealInverseFull(a, scale);
}
- }
+ } */
/**
* Computes 3D inverse DFT of real data leaving the result in a
@@ -2288,7 +2301,7 @@ public void run() {
}
}
-
+ /*
private void mixedRadixRealForwardFull(final FloatLargeArray a) {
final long twon3 = 2 * columnsl;
FloatLargeArray temp = new FloatLargeArray(twon3, false);
@@ -2530,7 +2543,7 @@ public void run() {
}
}
- }
+ } */
private void mixedRadixRealInverseFull(final float[] a, final boolean scale) {
final int twon3 = 2 * columns;
@@ -2777,6 +2790,7 @@ public void run() {
}
}
+ /*
private void mixedRadixRealInverseFull(final FloatLargeArray a, final boolean scale) {
final long twon3 = 2 * columnsl;
FloatLargeArray temp = new FloatLargeArray(twon3, false);
@@ -3020,7 +3034,7 @@ public void run() {
}
}
- }
+ } */
private void xdft3da_sub1(int icr, int isgn, float[] a, boolean scale) {
int idx0, idx1, idx2, idx3, idx4, idx5;
@@ -3211,6 +3225,7 @@ private void xdft3da_sub1(int icr, int isgn, float[] a, boolean scale) {
}
}
+ /*
private void xdft3da_sub1(long icr, int isgn, FloatLargeArray a, boolean scale) {
long idx0, idx1, idx2, idx3, idx4, idx5;
long nt = slicesl;
@@ -3398,7 +3413,7 @@ private void xdft3da_sub1(long icr, int isgn, FloatLargeArray a, boolean scale)
}
}
}
- }
+ } */
private void xdft3da_sub2(int icr, int isgn, float[] a, boolean scale) {
int idx0, idx1, idx2, idx3, idx4, idx5;
@@ -3588,6 +3603,7 @@ private void xdft3da_sub2(int icr, int isgn, float[] a, boolean scale) {
}
}
+ /*
private void xdft3da_sub2(long icr, int isgn, FloatLargeArray a, boolean scale) {
long idx0, idx1, idx2, idx3, idx4, idx5;
long nt = slicesl;
@@ -3774,7 +3790,7 @@ private void xdft3da_sub2(long icr, int isgn, FloatLargeArray a, boolean scale)
}
}
}
- }
+ } */
private void xdft3da_sub1(int icr, int isgn, float[][][] a, boolean scale) {
int idx2, idx3, idx4, idx5;
@@ -4307,6 +4323,7 @@ private void cdft3db_sub(int isgn, float[] a, boolean scale) {
}
}
+ /*
private void cdft3db_sub(int isgn, FloatLargeArray a, boolean scale) {
long idx0, idx1, idx2, idx3, idx4, idx5;
long nt = slicesl;
@@ -4487,7 +4504,7 @@ private void cdft3db_sub(int isgn, FloatLargeArray a, boolean scale) {
}
}
}
- }
+ } */
private void cdft3db_sub(int isgn, float[][][] a, boolean scale) {
int idx2, idx3, idx4, idx5;
@@ -4855,6 +4872,7 @@ public void run() {
ConcurrencyUtils.waitForCompletion(futures);
}
+ /*
private void xdft3da_subth1(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
int i;
final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), slicesl);
@@ -5055,7 +5073,7 @@ public void run() {
});
}
ConcurrencyUtils.waitForCompletion(futures);
- }
+ } */
private void xdft3da_subth2(final int icr, final int isgn, final float[] a, final boolean scale) {
int i;
@@ -5258,6 +5276,7 @@ public void run() {
ConcurrencyUtils.waitForCompletion(futures);
}
+ /*
private void xdft3da_subth2(final long icr, final int isgn, final FloatLargeArray a, final boolean scale) {
int i;
final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), slicesl);
@@ -5457,7 +5476,7 @@ public void run() {
});
}
ConcurrencyUtils.waitForCompletion(futures);
- }
+ } */
private void xdft3da_subth1(final int icr, final int isgn, final float[][][] a, final boolean scale) {
int i;
@@ -5832,7 +5851,7 @@ public void run() {
});
}
ConcurrencyUtils.waitForCompletion(futures);
- }
+ }
private void cdft3db_subth(final int isgn, final float[] a, final boolean scale) {
int i;
@@ -6030,6 +6049,7 @@ public void run() {
ConcurrencyUtils.waitForCompletion(futures);
}
+ /*
private void cdft3db_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
int i;
final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), rowsl);
@@ -6224,7 +6244,7 @@ public void run() {
});
}
ConcurrencyUtils.waitForCompletion(futures);
- }
+ } */
private void cdft3db_subth(final int isgn, final float[][][] a, final boolean scale) {
int i;
@@ -6517,6 +6537,7 @@ private void rdft3d_sub(int isgn, float[] a) {
}
}
+ /*
private void rdft3d_sub(int isgn, FloatLargeArray a) {
long n1h, n2h, i, j, k, l, idx1, idx2, idx3, idx4;
float xi;
@@ -6628,7 +6649,7 @@ private void rdft3d_sub(int isgn, FloatLargeArray a) {
a.setFloat(idx4 + 1, a.getFloat(idx4 + 1) - a.getFloat(idx3 + 1));
}
}
- }
+ } */
private void rdft3d_sub(int isgn, float[][][] a) {
int n1h, n2h, i, j, k, l;
@@ -7057,6 +7078,7 @@ public void run() {
a[idx3 + columns + 1] = 0;
}
+ /*
private void fillSymmetric(final FloatLargeArray a) {
final long twon3 = 2 * columnsl;
final long n2d2 = rowsl / 2;
@@ -7258,5 +7280,5 @@ public void run() {
a.setFloat(idx3 + 1, 0);
a.setFloat(idx2 + columnsl + 1, 0);
a.setFloat(idx3 + columnsl + 1, 0);
- }
+ } */
}
diff --git a/pom.xml b/pom.xml
index 09b080a..e70184a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,26 +1,30 @@
-
-a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(double[] a, boolean scale)
- {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(DoubleLargeArray a, boolean scale)
- {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final int offa, boolean scale)
- {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- forward(new DoubleLargeArray(a), offa, scale);
- } else {
- if (isPowerOfTwo) {
- double xr = a[offa + n - 1];
- for (int j = n - 2; j >= 2; j -= 2) {
- a[offa + j + 1] = a[offa + j] - a[offa + j - 1];
- a[offa + j] += a[offa + j - 1];
- }
- a[offa + 1] = a[offa] - xr;
- a[offa] += xr;
- if (n > 4) {
- rftbsub(n, a, offa, nc, w, nw);
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- } else if (n == 4) {
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- }
- CommonUtils.dctsub(n, a, offa, nc, w, nw);
- if (scale) {
- CommonUtils.scale(n, Math.sqrt(2.0 / n), a, offa, false);
- a[offa] = a[offa] / Math.sqrt(2.0);
- }
- } else {
- final int twon = 2 * n;
- final double[] t = new double[twon];
- System.arraycopy(a, offa, t, 0, n);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- for (int i = n; i < twon; i++) {
- t[i] = t[twon - i - 1];
- }
- fft.realForward(t);
- if ((nthreads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = n / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? n : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstIdx; i < lastIdx; i++) {
- int twoi = 2 * i;
- int idx = offa + i;
- a[idx] = w[twoi] * t[twoi] - w[twoi + 1] * t[twoi + 1];
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < n; i++) {
- int twoi = 2 * i;
- int idx = offa + i;
- a[idx] = w[twoi] * t[twoi] - w[twoi + 1] * t[twoi + 1];
- }
- }
- if (scale) {
- CommonUtils.scale(n, 1 / Math.sqrt(twon), a, offa, false);
- a[offa] = a[offa] / Math.sqrt(2.0);
- }
- }
- }
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final long offa, boolean scale)
- {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (isPowerOfTwo) {
- double xr = a.getDouble(offa + nl - 1);
- for (long j = nl - 2; j >= 2; j -= 2) {
- a.setDouble(offa + j + 1, a.getDouble(offa + j) - a.getDouble(offa + j - 1));
- a.setDouble(offa + j, a.getDouble(offa + j) + a.getDouble(offa + j - 1));
- }
- a.setDouble(offa + 1, a.getDouble(offa) - xr);
- a.setDouble(offa, a.getDouble(offa) + xr);
- if (nl > 4) {
- rftbsub(nl, a, offa, ncl, wl, nwl);
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- } else if (nl == 4) {
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- }
- CommonUtils.dctsub(nl, a, offa, ncl, wl, nwl);
- if (scale) {
- CommonUtils.scale(nl, Math.sqrt(2.0 / nl), a, offa, false);
- a.setDouble(offa, a.getDouble(offa) / Math.sqrt(2.0));
- }
- } else {
- final long twon = 2 * nl;
- final DoubleLargeArray t = new DoubleLargeArray(twon, false);
- Utilities.arraycopy(a, offa, t, 0, nl);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- for (long i = nl; i < twon; i++) {
- t.setDouble(i, t.getDouble(twon - i - 1));
- }
- fft.realForward(t);
- if ((nthreads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nl / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nl : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstIdx; i < lastIdx; i++) {
- long twoi = 2 * i;
- long idx = offa + i;
- a.setDouble(idx, wl.getDouble(twoi) * t.getDouble(twoi) - wl.getDouble(twoi + 1) * t.getDouble(twoi + 1));
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < nl; i++) {
- long twoi = 2 * i;
- long idx = offa + i;
- a.setDouble(idx, wl.getDouble(twoi) * t.getDouble(twoi) - wl.getDouble(twoi + 1) * t.getDouble(twoi + 1));
- }
- }
- if (scale) {
- CommonUtils.scale(nl, 1 / Math.sqrt(twon), a, offa, false);
- a.setDouble(offa, a.getDouble(offa) / Math.sqrt(2.0));
- }
- }
- }
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(double[] a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(DoubleLargeArray a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final int offa, boolean scale)
- {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- inverse(new DoubleLargeArray(a), offa, scale);
- } else {
- if (isPowerOfTwo) {
- double xr;
- if (scale) {
- CommonUtils.scale(n, Math.sqrt(2.0 / n), a, offa, false);
- a[offa] = a[offa] / Math.sqrt(2.0);
- }
- CommonUtils.dctsub(n, a, offa, nc, w, nw);
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- rftfsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- }
- xr = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- for (int j = 2; j < n; j += 2) {
- a[offa + j - 1] = a[offa + j] - a[offa + j + 1];
- a[offa + j] += a[offa + j + 1];
- }
- a[offa + n - 1] = xr;
- } else {
- final int twon = 2 * n;
- if (scale) {
- CommonUtils.scale(n, Math.sqrt(twon), a, offa, false);
- a[offa] = a[offa] * Math.sqrt(2.0);
- }
- final double[] t = new double[twon];
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = n / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? n : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstIdx; i < lastIdx; i++) {
- int twoi = 2 * i;
- double elem = a[offa + i];
- t[twoi] = w[twoi] * elem;
- t[twoi + 1] = -w[twoi + 1] * elem;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < n; i++) {
- int twoi = 2 * i;
- double elem = a[offa + i];
- t[twoi] = w[twoi] * elem;
- t[twoi + 1] = -w[twoi + 1] * elem;
- }
- }
- fft.realInverse(t, true);
- System.arraycopy(t, 0, a, offa, n);
- }
- }
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final long offa, boolean scale)
- {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (isPowerOfTwo) {
- double xr;
- if (scale) {
- CommonUtils.scale(nl, Math.sqrt(2.0 / nl), a, offa, false);
- a.setDouble(offa, a.getDouble(offa) / Math.sqrt(2.0));
- }
- CommonUtils.dctsub(nl, a, offa, ncl, wl, nwl);
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- rftfsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- }
- xr = a.getDouble(offa) - a.getDouble(offa + 1);
- a.setDouble(offa, a.getDouble(offa) + a.getDouble(offa + 1));
- for (long j = 2; j < nl; j += 2) {
- a.setDouble(offa + j - 1, a.getDouble(offa + j) - a.getDouble(offa + j + 1));
- a.setDouble(offa + j, a.getDouble(offa + j) + a.getDouble(offa + j + 1));
- }
- a.setDouble(offa + nl - 1, xr);
- } else {
- final long twon = 2 * nl;
- if (scale) {
- CommonUtils.scale(nl, Math.sqrt(twon), a, offa, false);
- a.setDouble(offa, a.getDouble(offa) * Math.sqrt(2.0));
- }
- final DoubleLargeArray t = new DoubleLargeArray(twon, false);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nl / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nl : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstIdx; i < lastIdx; i++) {
- long twoi = 2 * i;
- double elem = a.getDouble(offa + i);
- t.setDouble(twoi, wl.getDouble(twoi) * elem);
- t.setDouble(twoi + 1, -wl.getDouble(twoi + 1) * elem);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < nl; i++) {
- long twoi = 2 * i;
- double elem = a.getDouble(offa + i);
- t.setDouble(twoi, wl.getDouble(twoi) * elem);
- t.setDouble(twoi + 1, -wl.getDouble(twoi + 1) * elem);
- }
- }
- fft.realInverse(t, true);
- Utilities.arraycopy(t, 0, a, offa, nl);
- }
- }
- }
-
- /* -------- initializing routines -------- */
- private double[] makect(int n)
- {
- int twon = 2 * n;
- int idx;
- double delta = PI / twon;
- double deltaj;
- double[] c = new double[twon];
- c[0] = 1;
- for (int j = 1; j < n; j++) {
- idx = 2 * j;
- deltaj = delta * j;
- c[idx] = Math.cos(deltaj);
- c[idx + 1] = -Math.sin(deltaj);
- }
- return c;
- }
-
- private DoubleLargeArray makect(long n)
- {
- long twon = 2 * n;
- long idx;
- double delta = PI / twon;
- double deltaj;
- DoubleLargeArray c = new DoubleLargeArray(twon, false);
- c.setDouble(0, 1);
- for (long j = 1; j < n; j++) {
- idx = 2 * j;
- deltaj = delta * j;
- c.setDouble(idx, Math.cos(deltaj));
- c.setDouble(idx + 1, -Math.sin(deltaj));
- }
- return c;
- }
-
- private static void rftfsub(int n, double[] a, int offa, int nc, double[] c, int startc)
- {
- int k, kk, ks, m;
- double wkr, wki, xr, xi, yr, yi;
- int idx1, idx2;
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (int j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c[startc + nc - kk];
- wki = c[startc + kk];
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a[idx1] - a[idx2];
- xi = a[idx1 + 1] + a[idx2 + 1];
- yr = wkr * xr - wki * xi;
- yi = wkr * xi + wki * xr;
- a[idx1] -= yr;
- a[idx1 + 1] -= yi;
- a[idx2] += yr;
- a[idx2 + 1] -= yi;
- }
- }
-
- private static void rftfsub(long n, DoubleLargeArray a, long offa, long nc, DoubleLargeArray c, long startc)
- {
- long k, kk, ks, m;
- double wkr, wki, xr, xi, yr, yi;
- long idx1, idx2;
- m = n >> 1l;
- ks = 2 * nc / m;
- kk = 0;
- for (long j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c.getDouble(startc + nc - kk);
- wki = c.getDouble(startc + kk);
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a.getDouble(idx1) - a.getDouble(idx2);
- xi = a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1);
- yr = wkr * xr - wki * xi;
- yi = wkr * xi + wki * xr;
- a.setDouble(idx1, a.getDouble(idx1) - yr);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) - yi);
- a.setDouble(idx2, a.getDouble(idx2) + yr);
- a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - yi);
- }
- }
-
- private static void rftbsub(int n, double[] a, int offa, int nc, double[] c, int startc)
- {
- int k, kk, ks, m;
- double wkr, wki, xr, xi, yr, yi;
- int idx1, idx2;
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (int j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c[startc + nc - kk];
- wki = c[startc + kk];
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a[idx1] - a[idx2];
- xi = a[idx1 + 1] + a[idx2 + 1];
- yr = wkr * xr + wki * xi;
- yi = wkr * xi - wki * xr;
- a[idx1] -= yr;
- a[idx1 + 1] -= yi;
- a[idx2] += yr;
- a[idx2 + 1] -= yi;
- }
- }
-
- private static void rftbsub(long n, DoubleLargeArray a, long offa, long nc, DoubleLargeArray c, long startc)
- {
- long k, kk, ks, m;
- double wkr, wki, xr, xi, yr, yi;
- long idx1, idx2;
- m = n >> 1l;
- ks = 2 * nc / m;
- kk = 0;
- for (long j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5 - c.getDouble(startc + nc - kk);
- wki = c.getDouble(startc + kk);
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a.getDouble(idx1) - a.getDouble(idx2);
- xi = a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1);
- yr = wkr * xr + wki * xi;
- yi = wkr * xi - wki * xr;
- a.setDouble(idx1, a.getDouble(idx1) - yr);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) - yi);
- a.setDouble(idx2, a.getDouble(idx2) + yr);
- a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - yi);
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/DoubleDCT_2D.java b/src/main/java/org/jtransforms/dct/DoubleDCT_2D.java
deleted file mode 100644
index 452de2d..0000000
--- a/src/main/java/org/jtransforms/dct/DoubleDCT_2D.java
+++ /dev/null
@@ -1,1107 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 2D Discrete Cosine Transform (DCT) of double precision data. The
- * sizes of both dimensions can be arbitrary numbers. This is a parallel
- * implementation of split-radix and mixed-radix algorithms optimized for SMP
- * systems. a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- dctColumns.forward(a, r * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a, i * columns, scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DCT (DCT-II) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dctColumns.forward(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- dctColumns.forward(a, r * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dctColumns.forward(a, i * columnsl, scale);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DCT (DCT-II) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.forward(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a[i], scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[r], scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- private void ddxt2d_subth(final int isgn, final double[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final long nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.inverse(t, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final double[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.forward(a, r * columns, scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dctColumns.forward(a, r * columnsl, scale);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- dctColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.forward(a[r], scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, double[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1l;
- } else if (columnsl < 2) {
- nt >>= 2l;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, double[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/DoubleDCT_3D.java b/src/main/java/org/jtransforms/dct/DoubleDCT_3D.java
deleted file mode 100644
index 2dccd44..0000000
--- a/src/main/java/org/jtransforms/dct/DoubleDCT_3D.java
+++ /dev/null
@@ -1,2092 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 3D Discrete Cosine Transform (DCT) of double precision data. The
- * sizes of all three dimensions can be arbitrary numbers. This is a parallel
- * implementation of split-radix and mixed-radix algorithms optimized for SMP
- * systems. a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DCT (DCT-II) leaving the result in a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dctSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dctSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DCT (DCT-II) leaving the result in a
- * . The data is stored in 3D array
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dctSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dctSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- dctSlices.forward(t, 2 * slicesl, scale);
- dctSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- dctSlices.inverse(t, 2 * slicesl, scale);
- dctSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- Future>[] futures = new Future[nthreads];
- final int ntf = nt;
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int j = 0; j < rows; j++) {
- idx1 = idx0 + j * rowStride + c;
- idx2 = rows + j;
- t[j] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int j = 0; j < rows; j++) {
- idx1 = idx0 + j * rowStride + c;
- idx2 = rows + j;
- a[idx1] = t[j];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- Future>[] futures = new Future[nthreads];
- final long ntf = nt;
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long j = 0; j < rowsl; j++) {
- idx1 = idx0 + j * rowStridel + c;
- idx2 = rowsl + j;
- t.setDouble(j, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long j = 0; j < rowsl; j++) {
- idx1 = idx0 + j * rowStridel + c;
- idx2 = rowsl + j;
- a.setDouble(idx1, t.getDouble(j));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- dctSlices.forward(t, 2 * slicesl, scale);
- dctSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- dctSlices.inverse(t, 2 * slicesl, scale);
- dctSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/FloatDCT_1D.java b/src/main/java/org/jtransforms/dct/FloatDCT_1D.java
deleted file mode 100644
index 5bf38e3..0000000
--- a/src/main/java/org/jtransforms/dct/FloatDCT_1D.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.concurrent.Future;
-import org.jtransforms.fft.FloatFFT_1D;
-import org.jtransforms.utils.CommonUtils;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-import pl.edu.icm.jlargearrays.LongLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 1D Discrete Cosine Transform (DCT) of single precision data. The
- * size of data can be an arbitrary number. This is a parallel implementation of
- * split-radix and mixed-radix algorithms optimized for SMP systems. a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void forward(float[] a, boolean scale)
- {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void forward(FloatLargeArray a, boolean scale)
- {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void forward(final float[] a, final int offa, boolean scale)
- {
- if (n == 1)
- return;
- if (useLargeArrays) {
- forward(new FloatLargeArray(a), offa, scale);
- } else {
- if (isPowerOfTwo) {
- float xr = a[offa + n - 1];
- for (int j = n - 2; j >= 2; j -= 2) {
- a[offa + j + 1] = a[offa + j] - a[offa + j - 1];
- a[offa + j] += a[offa + j - 1];
- }
- a[offa + 1] = a[offa] - xr;
- a[offa] += xr;
- if (n > 4) {
- rftbsub(n, a, offa, nc, w, nw);
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- } else if (n == 4) {
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- }
- CommonUtils.dctsub(n, a, offa, nc, w, nw);
- if (scale) {
- CommonUtils.scale(n, (float)Math.sqrt(2.0 / n), a, offa, false);
- a[offa] = a[offa] / (float)Math.sqrt(2.0);
- }
- } else {
- final int twon = 2 * n;
- final float[] t = new float[twon];
- System.arraycopy(a, offa, t, 0, n);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- for (int i = n; i < twon; i++) {
- t[i] = t[twon - i - 1];
- }
- fft.realForward(t);
- if ((nthreads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = n / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? n : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstIdx; i < lastIdx; i++) {
- int twoi = 2 * i;
- int idx = offa + i;
- a[idx] = w[twoi] * t[twoi] - w[twoi + 1] * t[twoi + 1];
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < n; i++) {
- int twoi = 2 * i;
- int idx = offa + i;
- a[idx] = w[twoi] * t[twoi] - w[twoi + 1] * t[twoi + 1];
- }
- }
- if (scale) {
- CommonUtils.scale(n, 1 / (float)Math.sqrt(twon), a, offa, false);
- a[offa] = a[offa] / (float)Math.sqrt(2.0);
- }
- }
- }
- }
-
- /**
- * Computes 1D forward DCT (DCT-II) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final long offa, boolean scale)
- {
- if (nl == 1)
- return;
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (isPowerOfTwo) {
- float xr = a.getFloat(offa + nl - 1);
- for (long j = nl - 2; j >= 2; j -= 2) {
- a.setFloat(offa + j + 1, a.getFloat(offa + j) - a.getFloat(offa + j - 1));
- a.setFloat(offa + j, a.getFloat(offa + j) + a.getFloat(offa + j - 1));
- }
- a.setFloat(offa + 1, a.getFloat(offa) - xr);
- a.setFloat(offa, a.getFloat(offa) + xr);
- if (nl > 4) {
- rftbsub(nl, a, offa, ncl, wl, nwl);
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- } else if (nl == 4) {
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- }
- CommonUtils.dctsub(nl, a, offa, ncl, wl, nwl);
- if (scale) {
- CommonUtils.scale(nl, (float)Math.sqrt(2.0 / nl), a, offa, false);
- a.setFloat(offa, a.getFloat(offa) / (float)Math.sqrt(2.0));
- }
- } else {
- final long twon = 2 * nl;
- final FloatLargeArray t = new FloatLargeArray(twon, false);
- Utilities.arraycopy(a, offa, t, 0, nl);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- for (long i = nl; i < twon; i++) {
- t.setFloat(i, t.getFloat(twon - i - 1));
- }
- fft.realForward(t);
- if ((nthreads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nl / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nl : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstIdx; i < lastIdx; i++) {
- long twoi = 2 * i;
- long idx = offa + i;
- a.setFloat(idx, wl.getFloat(twoi) * t.getFloat(twoi) - wl.getFloat(twoi + 1) * t.getFloat(twoi + 1));
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < nl; i++) {
- long twoi = 2 * i;
- long idx = offa + i;
- a.setFloat(idx, wl.getFloat(twoi) * t.getFloat(twoi) - wl.getFloat(twoi + 1) * t.getFloat(twoi + 1));
- }
- }
- if (scale) {
- CommonUtils.scale(nl, 1 / (float)Math.sqrt(twon), a, offa, false);
- a.setFloat(offa, a.getFloat(offa) / (float)Math.sqrt(2.0));
- }
- }
- }
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(float[] a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(FloatLargeArray a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(final float[] a, final int offa, boolean scale)
- {
- if (n == 1)
- return;
- if (useLargeArrays) {
- inverse(new FloatLargeArray(a), offa, scale);
- } else {
- if (isPowerOfTwo) {
- float xr;
- if (scale) {
- CommonUtils.scale(n, (float)Math.sqrt(2.0 / n), a, offa, false);
- a[offa] = a[offa] / (float)Math.sqrt(2.0);
- }
- CommonUtils.dctsub(n, a, offa, nc, w, nw);
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- rftfsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- }
- xr = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- for (int j = 2; j < n; j += 2) {
- a[offa + j - 1] = a[offa + j] - a[offa + j + 1];
- a[offa + j] += a[offa + j + 1];
- }
- a[offa + n - 1] = xr;
- } else {
- final int twon = 2 * n;
- if (scale) {
- CommonUtils.scale(n, (float)Math.sqrt(twon), a, offa, false);
- a[offa] = a[offa] * (float)Math.sqrt(2.0);
- }
- final float[] t = new float[twon];
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = n / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? n : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstIdx; i < lastIdx; i++) {
- int twoi = 2 * i;
- float elem = a[offa + i];
- t[twoi] = w[twoi] * elem;
- t[twoi + 1] = -w[twoi + 1] * elem;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < n; i++) {
- int twoi = 2 * i;
- float elem = a[offa + i];
- t[twoi] = w[twoi] * elem;
- t[twoi + 1] = -w[twoi + 1] * elem;
- }
- }
- fft.realInverse(t, true);
- System.arraycopy(t, 0, a, offa, n);
- }
- }
- }
-
- /**
- * Computes 1D inverse DCT (DCT-III) leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final long offa, boolean scale)
- {
- if (nl == 1)
- return;
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (isPowerOfTwo) {
- float xr;
- if (scale) {
- CommonUtils.scale(nl, (float)Math.sqrt(2.0 / nl), a, offa, false);
- a.setFloat(offa, a.getFloat(offa) / (float)Math.sqrt(2.0));
- }
- CommonUtils.dctsub(nl, a, offa, ncl, wl, nwl);
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- rftfsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- }
- xr = a.getFloat(offa) - a.getFloat(offa + 1);
- a.setFloat(offa, a.getFloat(offa) + a.getFloat(offa + 1));
- for (long j = 2; j < nl; j += 2) {
- a.setFloat(offa + j - 1, a.getFloat(offa + j) - a.getFloat(offa + j + 1));
- a.setFloat(offa + j, a.getFloat(offa + j) + a.getFloat(offa + j + 1));
- }
- a.setFloat(offa + nl - 1, xr);
- } else {
- final long twon = 2 * nl;
- if (scale) {
- CommonUtils.scale(nl, (float)Math.sqrt(twon), a, offa, false);
- a.setFloat(offa, a.getFloat(offa) * (float)Math.sqrt(2.0));
- }
- final FloatLargeArray t = new FloatLargeArray(twon, false);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nl / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nl : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstIdx; i < lastIdx; i++) {
- long twoi = 2 * i;
- float elem = a.getFloat(offa + i);
- t.setFloat(twoi, wl.getFloat(twoi) * elem);
- t.setFloat(twoi + 1, -wl.getFloat(twoi + 1) * elem);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < nl; i++) {
- long twoi = 2 * i;
- float elem = a.getFloat(offa + i);
- t.setFloat(twoi, wl.getFloat(twoi) * elem);
- t.setFloat(twoi + 1, -wl.getFloat(twoi + 1) * elem);
- }
- }
- fft.realInverse(t, true);
- Utilities.arraycopy(t, 0, a, offa, nl);
- }
- }
- }
-
- /* -------- initializing routines -------- */
- private float[] makect(int n)
- {
- int twon = 2 * n;
- int idx;
- float delta = PI / twon;
- float deltaj;
- float[] c = new float[twon];
- c[0] = 1;
- for (int j = 1; j < n; j++) {
- idx = 2 * j;
- deltaj = delta * j;
- c[idx] = (float)Math.cos(deltaj);
- c[idx + 1] = -(float)Math.sin(deltaj);
- }
- return c;
- }
-
- private FloatLargeArray makect(long n)
- {
- long twon = 2 * n;
- long idx;
- float delta = PI / twon;
- float deltaj;
- FloatLargeArray c = new FloatLargeArray(twon, false);
- c.setFloat(0, 1);
- for (long j = 1; j < n; j++) {
- idx = 2 * j;
- deltaj = delta * j;
- c.setFloat(idx, (float)Math.cos(deltaj));
- c.setFloat(idx + 1, -(float)Math.sin(deltaj));
- }
- return c;
- }
-
- private static void rftfsub(int n, float[] a, int offa, int nc, float[] c, int startc)
- {
- int k, kk, ks, m;
- float wkr, wki, xr, xi, yr, yi;
- int idx1, idx2;
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (int j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5f - c[startc + nc - kk];
- wki = c[startc + kk];
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a[idx1] - a[idx2];
- xi = a[idx1 + 1] + a[idx2 + 1];
- yr = wkr * xr - wki * xi;
- yi = wkr * xi + wki * xr;
- a[idx1] -= yr;
- a[idx1 + 1] -= yi;
- a[idx2] += yr;
- a[idx2 + 1] -= yi;
- }
- }
-
- private static void rftfsub(long n, FloatLargeArray a, long offa, long nc, FloatLargeArray c, long startc)
- {
- long k, kk, ks, m;
- float wkr, wki, xr, xi, yr, yi;
- long idx1, idx2;
- m = n >> 1l;
- ks = 2 * nc / m;
- kk = 0;
- for (long j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5f - c.getFloat(startc + nc - kk);
- wki = c.getFloat(startc + kk);
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a.getFloat(idx1) - a.getFloat(idx2);
- xi = a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1);
- yr = wkr * xr - wki * xi;
- yi = wkr * xi + wki * xr;
- a.setFloat(idx1, a.getFloat(idx1) - yr);
- a.setFloat(idx1 + 1, a.getFloat(idx1 + 1) - yi);
- a.setFloat(idx2, a.getFloat(idx2) + yr);
- a.setFloat(idx2 + 1, a.getFloat(idx2 + 1) - yi);
- }
- }
-
- private static void rftbsub(int n, float[] a, int offa, int nc, float[] c, int startc)
- {
- int k, kk, ks, m;
- float wkr, wki, xr, xi, yr, yi;
- int idx1, idx2;
- m = n >> 1;
- ks = 2 * nc / m;
- kk = 0;
- for (int j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5f - c[startc + nc - kk];
- wki = c[startc + kk];
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a[idx1] - a[idx2];
- xi = a[idx1 + 1] + a[idx2 + 1];
- yr = wkr * xr + wki * xi;
- yi = wkr * xi - wki * xr;
- a[idx1] -= yr;
- a[idx1 + 1] -= yi;
- a[idx2] += yr;
- a[idx2 + 1] -= yi;
- }
- }
-
- private static void rftbsub(long n, FloatLargeArray a, long offa, long nc, FloatLargeArray c, long startc)
- {
- long k, kk, ks, m;
- float wkr, wki, xr, xi, yr, yi;
- long idx1, idx2;
- m = n >> 1l;
- ks = 2 * nc / m;
- kk = 0;
- for (long j = 2; j < m; j += 2) {
- k = n - j;
- kk += ks;
- wkr = 0.5f - c.getFloat(startc + nc - kk);
- wki = c.getFloat(startc + kk);
- idx1 = offa + j;
- idx2 = offa + k;
- xr = a.getFloat(idx1) - a.getFloat(idx2);
- xi = a.getFloat(idx1 + 1) + a.getFloat(idx2 + 1);
- yr = wkr * xr + wki * xi;
- yi = wkr * xi - wki * xr;
- a.setFloat(idx1, a.getFloat(idx1) - yr);
- a.setFloat(idx1 + 1, a.getFloat(idx1 + 1) - yi);
- a.setFloat(idx2, a.getFloat(idx2) + yr);
- a.setFloat(idx2 + 1, a.getFloat(idx2 + 1) - yi);
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/FloatDCT_2D.java b/src/main/java/org/jtransforms/dct/FloatDCT_2D.java
deleted file mode 100644
index b451579..0000000
--- a/src/main/java/org/jtransforms/dct/FloatDCT_2D.java
+++ /dev/null
@@ -1,1106 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 2D Discrete Cosine Transform (DCT) of single precision data. The
- * sizes of both dimensions can be arbitrary numbers. This is a parallel
- * implementation of split-radix and mixed-radix algorithms optimized for SMP
- * systems. a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int r = firstRow; r < lastRow; r++) {
- dctColumns.forward(a, r * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a, i * columns, scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DCT (DCT-II) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dctColumns.forward(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long r = firstRow; r < lastRow; r++) {
- dctColumns.forward(a, r * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dctColumns.forward(a, i * columnsl, scale);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DCT (DCT-II) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.forward(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.forward(a[i], scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a, i * columns, scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dctColumns.inverse(a, i * columnsl, scale);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DCT (DCT-III) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dctColumns.inverse(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dctColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[r], scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- private void ddxt2d_subth(final int isgn, final float[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final long nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.inverse(t, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setFloat(idx2, a.getFloat(idx1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setFloat(idx1, t.getFloat(idx2));
- a.setFloat(idx1 + 1, t.getFloat(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final float[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthread];
-
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.forward(a, r * columns, scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dctColumns.forward(a, r * columnsl, scale);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- dctColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.forward(a[r], scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dctColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, float[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1l;
- } else if (columnsl < 2) {
- nt >>= 2l;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, float[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- } else {
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/FloatDCT_3D.java b/src/main/java/org/jtransforms/dct/FloatDCT_3D.java
deleted file mode 100644
index 272d0f9..0000000
--- a/src/main/java/org/jtransforms/dct/FloatDCT_3D.java
+++ /dev/null
@@ -1,2092 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 3D Discrete Cosine Transform (DCT) of single precision data. The
- * sizes of all three dimensions can be arbitrary numbers. This is a parallel
- * implementation of split-radix and mixed-radix algorithms optimized for SMP
- * systems. a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DCT (DCT-II) leaving the result in a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dctSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dctRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dctSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DCT (DCT-II) leaving the result in a
- * . The data is stored in 3D array
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dctSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dctRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dctSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DCT (DCT-III) leaving the result in
- * a. The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dctRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dctSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- dctSlices.forward(t, 2 * slicesl, scale);
- dctSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- dctSlices.inverse(t, 2 * slicesl, scale);
- dctSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- Future>[] futures = new Future[nthreads];
- final int ntf = nt;
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int j = 0; j < rows; j++) {
- idx1 = idx0 + j * rowStride + c;
- idx2 = rows + j;
- t[j] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int j = 0; j < rows; j++) {
- idx1 = idx0 + j * rowStride + c;
- idx2 = rows + j;
- a[idx1] = t[j];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- Future>[] futures = new Future[nthreads];
- final long ntf = nt;
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- dctRows.forward(t, 2 * rowsl, scale);
- dctRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dctColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long j = 0; j < rowsl; j++) {
- idx1 = idx0 + j * rowStridel + c;
- idx2 = rowsl + j;
- t.setFloat(j, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- dctRows.inverse(t, 2 * rowsl, scale);
- dctRows.inverse(t, 3 * rowsl, scale);
- for (long j = 0; j < rowsl; j++) {
- idx1 = idx0 + j * rowStridel + c;
- idx2 = rowsl + j;
- a.setFloat(idx1, t.getFloat(j));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dctColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- dctRows.forward(t, 2 * rows, scale);
- dctRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.forward(t, 0, scale);
- dctRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dctColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- dctRows.inverse(t, 2 * rows, scale);
- dctRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dctRows.inverse(t, 0, scale);
- dctRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- dctSlices.forward(t, 2 * slicesl, scale);
- dctSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
- dctSlices.inverse(t, 2 * slicesl, scale);
- dctSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- dctSlices.forward(t, 2 * slices, scale);
- dctSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.forward(t, 0, scale);
- dctSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
- dctSlices.inverse(t, 2 * slices, scale);
- dctSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dctSlices.inverse(t, 0, scale);
- dctSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-}
diff --git a/src/main/java/org/jtransforms/dct/package.html b/src/main/java/org/jtransforms/dct/package.html
deleted file mode 100644
index 6a9f43d..0000000
--- a/src/main/java/org/jtransforms/dct/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Discrete Cosine Transforms.
-
-
diff --git a/src/main/java/org/jtransforms/dht/BenchmarkDoubleDHT.java b/src/main/java/org/jtransforms/dht/BenchmarkDoubleDHT.java
deleted file mode 100644
index 26d13b0..0000000
--- a/src/main/java/org/jtransforms/dht/BenchmarkDoubleDHT.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Benchmark of double precision DHT's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkDoubleDHT
-{
-
- private static int nthread = 8;
-
- private static int niter = 200;
-
- private static int nsize = 16;
-
- private static int threadsBegin2D = 65636;
-
- private static int threadsBegin3D = 65636;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkDoubleDHT()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDHT_1D dht = new DoubleDHT_1D(sizes1D[i]);
- x = new double[(int) sizes1D[i]];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dht.forward(x);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dht.forward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleDHT_1D dht = new DoubleDHT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes1D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- dht.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
- x = new DoubleLargeArray(sizes2D[i] * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes2D[i] * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dht2.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
- x = new double[(int) sizes2D[i]][(int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleDHT_2D dht2 = new DoubleDHT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes2D[i]][(int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dht2.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dht3.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleDHT_3D dht3 = new DoubleDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dht3.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDHT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkForward_1D();
- benchmarkForward_2D_input_1D();
- benchmarkForward_2D_input_2D();
- benchmarkForward_3D_input_1D();
- benchmarkForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/dht/BenchmarkFloatDHT.java b/src/main/java/org/jtransforms/dht/BenchmarkFloatDHT.java
deleted file mode 100644
index 8b63936..0000000
--- a/src/main/java/org/jtransforms/dht/BenchmarkFloatDHT.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Benchmark of single precision DHT's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkFloatDHT
-{
-
- private static int nthread = 8;
-
- private static int niter = 200;
-
- private static int nsize = 16;
-
- private static int threadsBegin2D = 65636;
-
- private static int threadsBegin3D = 65636;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkFloatDHT()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDHT_1D dht = new FloatDHT_1D(sizes1D[i]);
- x = new float[(int) sizes1D[i]];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dht.forward(x);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dht.forward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatDHT_1D dht = new FloatDHT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes1D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- dht.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDHT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDHT_2D dht2 = new FloatDHT_2D(sizes2D[i], sizes2D[i]);
- x = new FloatLargeArray(sizes2D[i] * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatDHT_2D dht2 = new FloatDHT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes2D[i] * sizes2D[i], false);
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dht2.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDHT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDHT_2D dht2 = new FloatDHT_2D(sizes2D[i], sizes2D[i]);
- x = new float[(int) sizes2D[i]][(int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dht2.forward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatDHT_2D dht2 = new FloatDHT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes2D[i]][(int) sizes2D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dht2.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDHT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDHT_3D dht3 = new FloatDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatDHT_3D dht3 = new FloatDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dht3.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDHT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DHT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDHT_3D dht3 = new FloatDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dht3.forward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatDHT_3D dht3 = new FloatDHT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dht3.forward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dht3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDHT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkForward_1D();
- benchmarkForward_2D_input_1D();
- benchmarkForward_2D_input_2D();
- benchmarkForward_3D_input_1D();
- benchmarkForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/dht/DoubleDHT_1D.java b/src/main/java/org/jtransforms/dht/DoubleDHT_1D.java
deleted file mode 100644
index 19017b2..0000000
--- a/src/main/java/org/jtransforms/dht/DoubleDHT_1D.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.fft.DoubleFFT_1D;
-import org.jtransforms.utils.CommonUtils;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 1D Discrete Hartley Transform (DHT) of real, double precision data.
- * The size of the data can be an arbitrary number. It uses FFT algorithm. This
- * is a parallel implementation optimized for SMP systems.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class DoubleDHT_1D {
-
- private final int n;
- private final long nl;
- private final DoubleFFT_1D fft;
- private final boolean useLargeArrays;
-
- /**
- * Creates new instance of DoubleDHT_1D.
- *
- * @param n size of data
- */
- public DoubleDHT_1D(long n) {
- this.n = (int) n;
- this.nl = n;
- this.useLargeArrays = n >= ConcurrencyUtils.getLargeArraysBeginN();
- fft = new DoubleFFT_1D(n);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a data to transform
- */
- public void forward(double[] a) {
- forward(a, 0);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a data to transform
- */
- public void forward(DoubleLargeArray a) {
- forward(a, 0);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void forward(final double[] a, final int offa) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- forward(new DoubleLargeArray(a), offa);
- } else {
- fft.realForward(a, offa);
- final double[] b = new double[n];
- System.arraycopy(a, offa, b, 0, n);
- int nd2 = n / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k1 = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = 1 + i * k1;
- final int lastIdx = (i == (nthreads - 1)) ? nd2 : firstIdx + k1;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx1, idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a[offa + i] = b[idx1] - b[idx2];
- a[offa + n - i] = b[idx1] + b[idx2];
- }
- }
-
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int i = 1; i < nd2; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a[offa + i] = b[idx1] - b[idx2];
- a[offa + n - i] = b[idx1] + b[idx2];
- }
- }
- if ((n % 2) == 0) {
- a[offa + nd2] = b[1];
- } else {
- a[offa + nd2] = b[n - 1] - b[1];
- a[offa + nd2 + 1] = b[n - 1] + b[1];
- }
- }
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void forward(final DoubleLargeArray a, final long offa) {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- fft.realForward(a, offa);
- final DoubleLargeArray b = new DoubleLargeArray(nl, false);
- Utilities.arraycopy(a, offa, b, 0, nl);
- long nd2 = nl / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k1 = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = 1 + i * k1;
- final long lastIdx = (i == (nthreads - 1)) ? nd2 : firstIdx + k1;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx1, idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a.setDouble(offa + i, b.getDouble(idx1) - b.getDouble(idx2));
- a.setDouble(offa + nl - i, b.getDouble(idx1) + b.getDouble(idx2));
- }
- }
-
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long i = 1; i < nd2; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a.setDouble(offa + i, b.getDouble(idx1) - b.getDouble(idx2));
- a.setDouble(offa + nl - i, b.getDouble(idx1) + b.getDouble(idx2));
- }
- }
- if ((nl % 2) == 0) {
- a.setDouble(offa + nd2, b.getDouble(1));
- } else {
- a.setDouble(offa + nd2, b.getDouble(nl - 1) - b.getDouble(1));
- a.setDouble(offa + nd2 + 1, b.getDouble(nl - 1) + b.getDouble(1));
- }
- }
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(double[] a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(DoubleLargeArray a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final int offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- inverse(new DoubleLargeArray(a), offa, scale);
- } else {
- forward(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- }
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final long offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- forward(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dht/DoubleDHT_2D.java b/src/main/java/org/jtransforms/dht/DoubleDHT_2D.java
deleted file mode 100644
index eb3c649..0000000
--- a/src/main/java/org/jtransforms/dht/DoubleDHT_2D.java
+++ /dev/null
@@ -1,1189 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 2D Discrete Hartley Transform (DHT) of real, double precision data.
- * The sizes of both dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- */
- public void forward(final double[] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a, i * columns);
- }
- }
- DoubleDHT_2D.this.yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a, i * columns);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a, i * columns);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, forward DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- */
- public void forward(final DoubleLargeArray a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, forward DHT leaving the result in a. The
- * data is stored in 2D array.
- *
- * @param a data to transform
- */
- public void forward(final double[][] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a[i]);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a[i]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a[i]);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- private void ddxt2d_subth(final int isgn, final double[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final double[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.forward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dhtColumns.forward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- dhtColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.forward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, double[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, double[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-
- private void yTransform(double[] a) {
- int mRow, mCol, idx1, idx2;
- double A, B, C, D, E;
- for (int r = 0; r <= rows / 2; r++) {
- mRow = (rows - r) % rows;
- idx1 = r * columns;
- idx2 = mRow * columns;
- for (int c = 0; c <= columns / 2; c++) {
- mCol = (columns - c) % columns;
- A = a[idx1 + c];
- B = a[idx2 + c];
- C = a[idx1 + mCol];
- D = a[idx2 + mCol];
- E = ((A + D) - (B + C)) / 2;
- a[idx1 + c] = A - E;
- a[idx2 + c] = B + E;
- a[idx1 + mCol] = C + E;
- a[idx2 + mCol] = D - E;
- }
- }
- }
-
- private void yTransform(DoubleLargeArray a) {
- long mRow, mCol, idx1, idx2;
- double A, B, C, D, E;
- for (long r = 0; r <= rowsl / 2; r++) {
- mRow = (rowsl - r) % rowsl;
- idx1 = r * columnsl;
- idx2 = mRow * columnsl;
- for (long c = 0; c <= columnsl / 2; c++) {
- mCol = (columnsl - c) % columnsl;
- A = a.getDouble(idx1 + c);
- B = a.getDouble(idx2 + c);
- C = a.getDouble(idx1 + mCol);
- D = a.getDouble(idx2 + mCol);
- E = ((A + D) - (B + C)) / 2;
- a.setDouble(idx1 + c, A - E);
- a.setDouble(idx2 + c, B + E);
- a.setDouble(idx1 + mCol, C + E);
- a.setDouble(idx2 + mCol, D - E);
- }
- }
- }
-
- private void yTransform(double[][] a) {
- int mRow, mCol;
- double A, B, C, D, E;
- for (int r = 0; r <= rows / 2; r++) {
- mRow = (rows - r) % rows;
- for (int c = 0; c <= columns / 2; c++) {
- mCol = (columns - c) % columns;
- A = a[r][c];
- B = a[mRow][c];
- C = a[r][mCol];
- D = a[mRow][mCol];
- E = ((A + D) - (B + C)) / 2;
- a[r][c] = A - E;
- a[mRow][c] = B + E;
- a[r][mCol] = C + E;
- a[mRow][mCol] = D - E;
- }
- }
- }
-
-}
diff --git a/src/main/java/org/jtransforms/dht/DoubleDHT_3D.java b/src/main/java/org/jtransforms/dht/DoubleDHT_3D.java
deleted file mode 100644
index a4efc7b..0000000
--- a/src/main/java/org/jtransforms/dht/DoubleDHT_3D.java
+++ /dev/null
@@ -1,2229 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 3D Discrete Hartley Transform (DHT) of real, double precision data.
- * The sizes of all three dimensions can be arbitrary numbers. This is a
- * parallel implementation optimized for SMP systems.a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- */
- public void forward(final double[] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int startRow = l * p;
- final int stopRow;
- if (l == nthreads - 1) {
- stopRow = rows;
- } else {
- stopRow = startRow + p;
- }
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = startRow; r < stopRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, forward DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- */
- public void forward(final DoubleLargeArray a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long startRow = l * p;
- final long stopRow;
- if (l == nthreads - 1) {
- stopRow = rowsl;
- } else {
- stopRow = startRow + p;
- }
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = startRow; r < stopRow; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dhtSlices.forward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dhtSlices.forward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, forward DHT leaving the result in a.
- * The data is stored in 3D array.
- *
- * @param a data to transform
- */
- public void forward(final double[][][] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dhtSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dhtSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- private void ddxt3da_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx0 + r * rowStridel);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columnsl == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- dhtSlices.forward(t, 2 * slicesl);
- dhtSlices.forward(t, 3 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- dhtSlices.inverse(t, 2 * slicesl, scale);
- dhtSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- dhtSlices.forward(t, 2 * slicesl);
- dhtSlices.forward(t, 3 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- dhtSlices.inverse(t, 2 * slicesl, scale);
- dhtSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void yTransform(double[] a) {
- double A, B, C, D, E, F, G, H;
- int cC, rC, sC;
- int idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10, idx11, idx12;
- for (int s = 0; s <= slices / 2; s++) {
- sC = (slices - s) % slices;
- idx9 = s * sliceStride;
- idx10 = sC * sliceStride;
- for (int r = 0; r <= rows / 2; r++) {
- rC = (rows - r) % rows;
- idx11 = r * rowStride;
- idx12 = rC * rowStride;
- for (int c = 0; c <= columns / 2; c++) {
- cC = (columns - c) % columns;
- idx1 = idx9 + idx12 + c;
- idx2 = idx9 + idx11 + cC;
- idx3 = idx10 + idx11 + c;
- idx4 = idx10 + idx12 + cC;
- idx5 = idx10 + idx12 + c;
- idx6 = idx10 + idx11 + cC;
- idx7 = idx9 + idx11 + c;
- idx8 = idx9 + idx12 + cC;
- A = a[idx1];
- B = a[idx2];
- C = a[idx3];
- D = a[idx4];
- E = a[idx5];
- F = a[idx6];
- G = a[idx7];
- H = a[idx8];
- a[idx7] = (A + B + C - D) / 2;
- a[idx3] = (E + F + G - H) / 2;
- a[idx1] = (G + H + E - F) / 2;
- a[idx5] = (C + D + A - B) / 2;
- a[idx2] = (H + G + F - E) / 2;
- a[idx6] = (D + C + B - A) / 2;
- a[idx8] = (B + A + D - C) / 2;
- a[idx4] = (F + E + H - G) / 2;
- }
- }
- }
- }
-
- private void yTransform(DoubleLargeArray a) {
- double A, B, C, D, E, F, G, H;
- long cC, rC, sC;
- long idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10, idx11, idx12;
- for (long s = 0; s <= slicesl / 2; s++) {
- sC = (slicesl - s) % slicesl;
- idx9 = s * sliceStridel;
- idx10 = sC * sliceStridel;
- for (long r = 0; r <= rowsl / 2; r++) {
- rC = (rowsl - r) % rowsl;
- idx11 = r * rowStridel;
- idx12 = rC * rowStridel;
- for (long c = 0; c <= columnsl / 2; c++) {
- cC = (columnsl - c) % columnsl;
- idx1 = idx9 + idx12 + c;
- idx2 = idx9 + idx11 + cC;
- idx3 = idx10 + idx11 + c;
- idx4 = idx10 + idx12 + cC;
- idx5 = idx10 + idx12 + c;
- idx6 = idx10 + idx11 + cC;
- idx7 = idx9 + idx11 + c;
- idx8 = idx9 + idx12 + cC;
- A = a.getDouble(idx1);
- B = a.getDouble(idx2);
- C = a.getDouble(idx3);
- D = a.getDouble(idx4);
- E = a.getDouble(idx5);
- F = a.getDouble(idx6);
- G = a.getDouble(idx7);
- H = a.getDouble(idx8);
- a.setDouble(idx7, (A + B + C - D) / 2);
- a.setDouble(idx3, (E + F + G - H) / 2);
- a.setDouble(idx1, (G + H + E - F) / 2);
- a.setDouble(idx5, (C + D + A - B) / 2);
- a.setDouble(idx2, (H + G + F - E) / 2);
- a.setDouble(idx6, (D + C + B - A) / 2);
- a.setDouble(idx8, (B + A + D - C) / 2);
- a.setDouble(idx4, (F + E + H - G) / 2);
- }
- }
- }
- }
-
- private void yTransform(double[][][] a) {
- double A, B, C, D, E, F, G, H;
- int cC, rC, sC;
- for (int s = 0; s <= slices / 2; s++) {
- sC = (slices - s) % slices;
- for (int r = 0; r <= rows / 2; r++) {
- rC = (rows - r) % rows;
- for (int c = 0; c <= columns / 2; c++) {
- cC = (columns - c) % columns;
- A = a[s][rC][c];
- B = a[s][r][cC];
- C = a[sC][r][c];
- D = a[sC][rC][cC];
- E = a[sC][rC][c];
- F = a[sC][r][cC];
- G = a[s][r][c];
- H = a[s][rC][cC];
- a[s][r][c] = (A + B + C - D) / 2;
- a[sC][r][c] = (E + F + G - H) / 2;
- a[s][rC][c] = (G + H + E - F) / 2;
- a[sC][rC][c] = (C + D + A - B) / 2;
- a[s][r][cC] = (H + G + F - E) / 2;
- a[sC][r][cC] = (D + C + B - A) / 2;
- a[s][rC][cC] = (B + A + D - C) / 2;
- a[sC][rC][cC] = (F + E + H - G) / 2;
- }
- }
- }
- }
-
-}
diff --git a/src/main/java/org/jtransforms/dht/FloatDHT_1D.java b/src/main/java/org/jtransforms/dht/FloatDHT_1D.java
deleted file mode 100644
index 4af3e61..0000000
--- a/src/main/java/org/jtransforms/dht/FloatDHT_1D.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.fft.FloatFFT_1D;
-import org.jtransforms.utils.CommonUtils;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 1D Discrete Hartley Transform (DHT) of real, single precision data.
- * The size of the data can be an arbitrary number. It uses FFT algorithm. This
- * is a parallel implementation optimized for SMP systems.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class FloatDHT_1D
-{
-
- private final int n;
- private final long nl;
- private final FloatFFT_1D fft;
- private final boolean useLargeArrays;
-
- /**
- * Creates new instance of FloatDHT_1D.
- *
- * @param n
- * size of data
-
- */
- public FloatDHT_1D(long n)
- {
- this.n = (int) n;
- this.nl = n;
- this.useLargeArrays = n >= ConcurrencyUtils.getLargeArraysBeginN();
- fft = new FloatFFT_1D(n);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a
- * data to transform
- */
- public void forward(float[] a)
- {
- forward(a, 0);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a
- * data to transform
- */
- public void forward(FloatLargeArray a)
- {
- forward(a, 0);
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- */
- public void forward(final float[] a, final int offa)
- {
- if (n == 1)
- return;
- if (useLargeArrays) {
- forward(new FloatLargeArray(a), offa);
- } else {
- fft.realForward(a, offa);
- final float[] b = new float[n];
- System.arraycopy(a, offa, b, 0, n);
- int nd2 = n / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k1 = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = 1 + i * k1;
- final int lastIdx = (i == (nthreads - 1)) ? nd2 : firstIdx + k1;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
-
- public void run()
- {
- int idx1, idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a[offa + i] = b[idx1] - b[idx2];
- a[offa + n - i] = b[idx1] + b[idx2];
- }
- }
-
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int i = 1; i < nd2; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a[offa + i] = b[idx1] - b[idx2];
- a[offa + n - i] = b[idx1] + b[idx2];
- }
- }
- if ((n % 2) == 0) {
- a[offa + nd2] = b[1];
- } else {
- a[offa + nd2] = b[n - 1] - b[1];
- a[offa + nd2 + 1] = b[n - 1] + b[1];
- }
- }
- }
-
- /**
- * Computes 1D real, forward DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- */
- public void forward(final FloatLargeArray a, final long offa)
- {
- if (nl == 1)
- return;
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- fft.realForward(a, offa);
- final FloatLargeArray b = new FloatLargeArray(nl, false);
- Utilities.arraycopy(a, offa, b, 0, nl);
- long nd2 = nl / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k1 = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = 1 + i * k1;
- final long lastIdx = (i == (nthreads - 1)) ? nd2 : firstIdx + k1;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
-
- public void run()
- {
- long idx1, idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a.setFloat(offa + i, b.getFloat(idx1) - b.getFloat(idx2));
- a.setFloat(offa + nl - i, b.getFloat(idx1) + b.getFloat(idx2));
- }
- }
-
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long i = 1; i < nd2; i++) {
- idx1 = 2 * i;
- idx2 = idx1 + 1;
- a.setFloat(offa + i, b.getFloat(idx1) - b.getFloat(idx2));
- a.setFloat(offa + nl - i, b.getFloat(idx1) + b.getFloat(idx2));
- }
- }
- if ((nl % 2) == 0) {
- a.setFloat(offa + nd2, b.getFloat(1));
- } else {
- a.setFloat(offa + nd2, b.getFloat(nl - 1) - b.getFloat(1));
- a.setFloat(offa + nd2 + 1, b.getFloat(nl - 1) + b.getFloat(1));
- }
- }
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(float[] a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(FloatLargeArray a, boolean scale)
- {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(final float[] a, final int offa, boolean scale)
- {
- if (n == 1)
- return;
- if (useLargeArrays) {
- inverse(new FloatLargeArray(a), offa, scale);
- } else {
- forward(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- }
- }
-
- /**
- * Computes 1D real, inverse DHT leaving the result in a.
- *
- * @param a
- * data to transform
- * @param offa
- * index of the first element in array a
- * @param scale
- * if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final long offa, boolean scale)
- {
- if (n == 1)
- return;
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- forward(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0f / n, a, offa, false);
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dht/FloatDHT_2D.java b/src/main/java/org/jtransforms/dht/FloatDHT_2D.java
deleted file mode 100644
index 323a9a6..0000000
--- a/src/main/java/org/jtransforms/dht/FloatDHT_2D.java
+++ /dev/null
@@ -1,1189 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 2D Discrete Hartley Transform (DHT) of real, single precision data.
- * The sizes of both dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- */
- public void forward(final float[] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a, i * columns);
- }
- }
- FloatDHT_2D.this.yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a, i * columns);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a, i * columns);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, forward DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- */
- public void forward(final FloatLargeArray a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.forward(a, i * columnsl);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, forward DHT leaving the result in a. The
- * data is stored in 2D array.
- *
- * @param a data to transform
- */
- public void forward(final float[][] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, true);
- ddxt2d0_subth(-1, a, true);
- } else {
- ddxt2d_sub(-1, a, true);
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a[i]);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.forward(a[i]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.forward(a[i]);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a, i * columns, scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long i = 0; i < rowsl; i++) {
- dhtColumns.inverse(a, i * columnsl, scale);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes 2D real, inverse DHT leaving the result in a. The
- * data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int i = 0; i < rows; i++) {
- dhtColumns.inverse(a[i], scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- yTransform(a);
- }
- }
-
- private void ddxt2d_subth(final int isgn, final float[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setFloat(idx2, a.getFloat(idx1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setFloat(idx1, t.getFloat(idx2));
- a.setFloat(idx1 + 1, t.getFloat(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final float[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.forward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dhtColumns.forward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- dhtColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.forward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dhtColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, float[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, float[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- } else {
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-
- private void yTransform(float[] a) {
- int mRow, mCol, idx1, idx2;
- float A, B, C, D, E;
- for (int r = 0; r <= rows / 2; r++) {
- mRow = (rows - r) % rows;
- idx1 = r * columns;
- idx2 = mRow * columns;
- for (int c = 0; c <= columns / 2; c++) {
- mCol = (columns - c) % columns;
- A = a[idx1 + c];
- B = a[idx2 + c];
- C = a[idx1 + mCol];
- D = a[idx2 + mCol];
- E = ((A + D) - (B + C)) / 2;
- a[idx1 + c] = A - E;
- a[idx2 + c] = B + E;
- a[idx1 + mCol] = C + E;
- a[idx2 + mCol] = D - E;
- }
- }
- }
-
- private void yTransform(FloatLargeArray a) {
- long mRow, mCol, idx1, idx2;
- float A, B, C, D, E;
- for (long r = 0; r <= rowsl / 2; r++) {
- mRow = (rowsl - r) % rowsl;
- idx1 = r * columnsl;
- idx2 = mRow * columnsl;
- for (long c = 0; c <= columnsl / 2; c++) {
- mCol = (columnsl - c) % columnsl;
- A = a.getFloat(idx1 + c);
- B = a.getFloat(idx2 + c);
- C = a.getFloat(idx1 + mCol);
- D = a.getFloat(idx2 + mCol);
- E = ((A + D) - (B + C)) / 2;
- a.setFloat(idx1 + c, A - E);
- a.setFloat(idx2 + c, B + E);
- a.setFloat(idx1 + mCol, C + E);
- a.setFloat(idx2 + mCol, D - E);
- }
- }
- }
-
- private void yTransform(float[][] a) {
- int mRow, mCol;
- float A, B, C, D, E;
- for (int r = 0; r <= rows / 2; r++) {
- mRow = (rows - r) % rows;
- for (int c = 0; c <= columns / 2; c++) {
- mCol = (columns - c) % columns;
- A = a[r][c];
- B = a[mRow][c];
- C = a[r][mCol];
- D = a[mRow][mCol];
- E = ((A + D) - (B + C)) / 2;
- a[r][c] = A - E;
- a[mRow][c] = B + E;
- a[r][mCol] = C + E;
- a[mRow][mCol] = D - E;
- }
- }
- }
-
-}
diff --git a/src/main/java/org/jtransforms/dht/FloatDHT_3D.java b/src/main/java/org/jtransforms/dht/FloatDHT_3D.java
deleted file mode 100644
index 8e63038..0000000
--- a/src/main/java/org/jtransforms/dht/FloatDHT_3D.java
+++ /dev/null
@@ -1,2229 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dht;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 3D Discrete Hartley Transform (DHT) of real, single precision data.
- * The sizes of all three dimensions can be arbitrary numbers. This is a
- * parallel implementation optimized for SMP systems.a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- */
- public void forward(final float[] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int startRow = l * p;
- final int stopRow;
- if (l == nthreads - 1) {
- stopRow = rows;
- } else {
- stopRow = startRow + p;
- }
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = startRow; r < stopRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, forward DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- */
- public void forward(final FloatLargeArray a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long startRow = l * p;
- final long stopRow;
- if (l == nthreads - 1) {
- stopRow = rowsl;
- } else {
- stopRow = startRow + p;
- }
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = startRow; r < stopRow; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dhtSlices.forward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx1 + r * rowStride);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dhtRows.forward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dhtSlices.forward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, forward DHT leaving the result in a.
- * The data is stored in 3D array.
- *
- * @param a data to transform
- */
- public void forward(final float[][][] a) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, true);
- ddxt3db_subth(-1, a, true);
- } else {
- ddxt3da_sub(-1, a, true);
- ddxt3db_sub(-1, a, true);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.forward(temp);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.forward(temp);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 1D array addressed in slice-major, then row-major,
- * then column-major, in order of significance, i.e. the element (i,j,k) of
- * 3D array x[slices][rows][columns] is stored in a[i*sliceStride +
- * j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dhtSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx1 + r * rowStridel, scale);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dhtRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dhtSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- /**
- * Computes the 3D real, inverse DHT leaving the result in a.
- * The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- yTransform(a);
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dhtRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dhtSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- yTransform(a);
- }
- }
-
- private void ddxt3da_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx0 + r * rowStridel);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columnsl == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- dhtSlices.forward(t, 2 * slicesl);
- dhtSlices.forward(t, 3 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- dhtSlices.inverse(t, 2 * slicesl, scale);
- dhtSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.forward(a, idx0 + r * rowStride);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- dhtRows.forward(t, 2 * rowsl);
- dhtRows.forward(t, 3 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dhtColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- dhtRows.inverse(t, 2 * rowsl, scale);
- dhtRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStride;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.forward(a[s][r]);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- dhtRows.forward(t, 2 * rows);
- dhtRows.forward(t, 3 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dhtRows.forward(t, 0);
- dhtRows.forward(t, rows);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dhtColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- dhtRows.inverse(t, 2 * rows, scale);
- dhtRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dhtRows.inverse(t, 0, scale);
- dhtRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- dhtSlices.forward(t, 2 * slicesl);
- dhtSlices.forward(t, 3 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- dhtSlices.inverse(t, 2 * slicesl, scale);
- dhtSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- dhtSlices.forward(t, 2 * slices);
- dhtSlices.forward(t, 3 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dhtSlices.forward(t, 0);
- dhtSlices.forward(t, slices);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
- dhtSlices.inverse(t, 2 * slices, scale);
- dhtSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dhtSlices.inverse(t, 0, scale);
- dhtSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void yTransform(float[] a) {
- float A, B, C, D, E, F, G, H;
- int cC, rC, sC;
- int idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10, idx11, idx12;
- for (int s = 0; s <= slices / 2; s++) {
- sC = (slices - s) % slices;
- idx9 = s * sliceStride;
- idx10 = sC * sliceStride;
- for (int r = 0; r <= rows / 2; r++) {
- rC = (rows - r) % rows;
- idx11 = r * rowStride;
- idx12 = rC * rowStride;
- for (int c = 0; c <= columns / 2; c++) {
- cC = (columns - c) % columns;
- idx1 = idx9 + idx12 + c;
- idx2 = idx9 + idx11 + cC;
- idx3 = idx10 + idx11 + c;
- idx4 = idx10 + idx12 + cC;
- idx5 = idx10 + idx12 + c;
- idx6 = idx10 + idx11 + cC;
- idx7 = idx9 + idx11 + c;
- idx8 = idx9 + idx12 + cC;
- A = a[idx1];
- B = a[idx2];
- C = a[idx3];
- D = a[idx4];
- E = a[idx5];
- F = a[idx6];
- G = a[idx7];
- H = a[idx8];
- a[idx7] = (A + B + C - D) / 2;
- a[idx3] = (E + F + G - H) / 2;
- a[idx1] = (G + H + E - F) / 2;
- a[idx5] = (C + D + A - B) / 2;
- a[idx2] = (H + G + F - E) / 2;
- a[idx6] = (D + C + B - A) / 2;
- a[idx8] = (B + A + D - C) / 2;
- a[idx4] = (F + E + H - G) / 2;
- }
- }
- }
- }
-
- private void yTransform(FloatLargeArray a) {
- float A, B, C, D, E, F, G, H;
- long cC, rC, sC;
- long idx1, idx2, idx3, idx4, idx5, idx6, idx7, idx8, idx9, idx10, idx11, idx12;
- for (long s = 0; s <= slicesl / 2; s++) {
- sC = (slicesl - s) % slicesl;
- idx9 = s * sliceStridel;
- idx10 = sC * sliceStridel;
- for (long r = 0; r <= rowsl / 2; r++) {
- rC = (rowsl - r) % rowsl;
- idx11 = r * rowStridel;
- idx12 = rC * rowStridel;
- for (long c = 0; c <= columnsl / 2; c++) {
- cC = (columnsl - c) % columnsl;
- idx1 = idx9 + idx12 + c;
- idx2 = idx9 + idx11 + cC;
- idx3 = idx10 + idx11 + c;
- idx4 = idx10 + idx12 + cC;
- idx5 = idx10 + idx12 + c;
- idx6 = idx10 + idx11 + cC;
- idx7 = idx9 + idx11 + c;
- idx8 = idx9 + idx12 + cC;
- A = a.getFloat(idx1);
- B = a.getFloat(idx2);
- C = a.getFloat(idx3);
- D = a.getFloat(idx4);
- E = a.getFloat(idx5);
- F = a.getFloat(idx6);
- G = a.getFloat(idx7);
- H = a.getFloat(idx8);
- a.setFloat(idx7, (A + B + C - D) / 2);
- a.setFloat(idx3, (E + F + G - H) / 2);
- a.setFloat(idx1, (G + H + E - F) / 2);
- a.setFloat(idx5, (C + D + A - B) / 2);
- a.setFloat(idx2, (H + G + F - E) / 2);
- a.setFloat(idx6, (D + C + B - A) / 2);
- a.setFloat(idx8, (B + A + D - C) / 2);
- a.setFloat(idx4, (F + E + H - G) / 2);
- }
- }
- }
- }
-
- private void yTransform(float[][][] a) {
- float A, B, C, D, E, F, G, H;
- int cC, rC, sC;
- for (int s = 0; s <= slices / 2; s++) {
- sC = (slices - s) % slices;
- for (int r = 0; r <= rows / 2; r++) {
- rC = (rows - r) % rows;
- for (int c = 0; c <= columns / 2; c++) {
- cC = (columns - c) % columns;
- A = a[s][rC][c];
- B = a[s][r][cC];
- C = a[sC][r][c];
- D = a[sC][rC][cC];
- E = a[sC][rC][c];
- F = a[sC][r][cC];
- G = a[s][r][c];
- H = a[s][rC][cC];
- a[s][r][c] = (A + B + C - D) / 2;
- a[sC][r][c] = (E + F + G - H) / 2;
- a[s][rC][c] = (G + H + E - F) / 2;
- a[sC][rC][c] = (C + D + A - B) / 2;
- a[s][r][cC] = (H + G + F - E) / 2;
- a[sC][r][cC] = (D + C + B - A) / 2;
- a[s][rC][cC] = (B + A + D - C) / 2;
- a[sC][rC][cC] = (F + E + H - G) / 2;
- }
- }
- }
- }
-
-}
diff --git a/src/main/java/org/jtransforms/dht/package.html b/src/main/java/org/jtransforms/dht/package.html
deleted file mode 100644
index 9ee9e8c..0000000
--- a/src/main/java/org/jtransforms/dht/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Discrete Hartley Transforms.
-
-
diff --git a/src/main/java/org/jtransforms/dst/BenchmarkDoubleDST.java b/src/main/java/org/jtransforms/dst/BenchmarkDoubleDST.java
deleted file mode 100644
index 92020fd..0000000
--- a/src/main/java/org/jtransforms/dst/BenchmarkDoubleDST.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Benchmark of double precision DST's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkDoubleDST
-{
-
- private static int nthread = 8;
-
- private static int niter = 200;
-
- private static int nsize = 16;
-
- private static int threadsBegin2D = 65636;
-
- private static int threadsBegin3D = 65636;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkDoubleDST()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDST_1D dst = new DoubleDST_1D(sizes1D[i]);
- x = new double[(int) sizes1D[i]];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dst.forward(x, doScaling);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dst.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- DoubleDST_1D dst = new DoubleDST_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes1D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- dst.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDST_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDST_2D dst2 = new DoubleDST_2D(sizes2D[i], sizes2D[i]);
- x = new DoubleLargeArray(sizes2D[i] * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- DoubleDST_2D dst2 = new DoubleDST_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes2D[i] * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dst2.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDST_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDST_2D dst2 = new DoubleDST_2D(sizes2D[i], sizes2D[i]);
- x = new double[(int) sizes2D[i]][(int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- DoubleDST_2D dst2 = new DoubleDST_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes2D[i]][(int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dst2.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDST_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDST_3D dst3 = new DoubleDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- DoubleDST_3D dst3 = new DoubleDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dst3.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDST_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleDST_3D dst3 = new DoubleDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- DoubleDST_3D dst3 = new DoubleDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dst3.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleForwardDST_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkForward_1D();
- benchmarkForward_2D_input_1D();
- benchmarkForward_2D_input_2D();
- benchmarkForward_3D_input_1D();
- benchmarkForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/BenchmarkFloatDST.java b/src/main/java/org/jtransforms/dst/BenchmarkFloatDST.java
deleted file mode 100644
index 875b6bf..0000000
--- a/src/main/java/org/jtransforms/dst/BenchmarkFloatDST.java
+++ /dev/null
@@ -1,326 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Benchmark of single precision DST's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkFloatDST
-{
-
- private static int nthread = 8;
-
- private static int niter = 200;
-
- private static int nsize = 16;
-
- private static int threadsBegin2D = 65636;
-
- private static int threadsBegin3D = 65636;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkFloatDST()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDST_1D dst = new FloatDST_1D(sizes1D[i]);
- x = new float[(int) sizes1D[i]];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dst.forward(x, doScaling);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- dst.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- FloatDST_1D dst = new FloatDST_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes1D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- dst.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDST_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDST_2D dst2 = new FloatDST_2D(sizes2D[i], sizes2D[i]);
- x = new FloatLargeArray(sizes2D[i] * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- FloatDST_2D dst2 = new FloatDST_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes2D[i] * sizes2D[i], false);
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dst2.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDST_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDST_2D dst2 = new FloatDST_2D(sizes2D[i], sizes2D[i]);
- x = new float[(int) sizes2D[i]][(int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- dst2.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- FloatDST_2D dst2 = new FloatDST_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes2D[i]][(int) sizes2D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- dst2.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDST_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDST_3D dst3 = new FloatDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- FloatDST_3D dst3 = new FloatDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * sizes3D[i], false);
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dst3.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDST_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Forward DST 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatDST_3D dst3 = new FloatDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- dst3.forward(x, doScaling);
- }
- long elapsedTime = System.nanoTime();
- FloatDST_3D dst3 = new FloatDST_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][(int) sizes3D[i]];
- double min_time = 0;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- dst3.forward(x, doScaling);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- dst3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatForwardDST_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkForward_1D();
- benchmarkForward_2D_input_1D();
- benchmarkForward_2D_input_2D();
- benchmarkForward_3D_input_1D();
- benchmarkForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/DoubleDST_1D.java b/src/main/java/org/jtransforms/dst/DoubleDST_1D.java
deleted file mode 100644
index ac980ad..0000000
--- a/src/main/java/org/jtransforms/dst/DoubleDST_1D.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.dct.DoubleDCT_1D;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 1D Discrete Sine Transform (DST) of double precision data. The size
- * of data can be an arbitrary number. It uses DCT algorithm. This is a parallel
- * implementation optimized for SMP systems.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class DoubleDST_1D {
-
- private final int n;
- private final long nl;
- private final DoubleDCT_1D dct;
- private final boolean useLargeArrays;
-
- /**
- * Creates new instance of DoubleDST_1D.
- *
- * @param n size of data
- */
- public DoubleDST_1D(long n) {
- this.n = (int) n;
- this.nl = n;
- this.useLargeArrays = n >= ConcurrencyUtils.getLargeArraysBeginN();
- dct = new DoubleDCT_1D(n);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(double[] a, boolean scale) {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(DoubleLargeArray a, boolean scale) {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final int offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- forward(new DoubleLargeArray(a), offa, scale);
- } else {
- double tmp;
- int nd2 = n / 2;
- int startIdx = 1 + offa;
- int stopIdx = offa + n;
- for (int i = startIdx; i < stopIdx; i += 2) {
- a[i] = -a[i];
- }
- dct.forward(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double tmp;
- int idx0 = offa + n - 1;
- int idx1;
- int idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx0 = offa + n - 1;
- int idx1;
- int idx2;
- for (int i = 0; i < nd2; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- }
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final long offa, boolean scale) {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- double tmp;
- long nd2 = nl / 2;
- long startIdx = 1 + offa;
- long stopIdx = offa + nl;
- for (long i = startIdx; i < stopIdx; i += 2) {
- a.setDouble(i, -a.getDouble(i));
- }
- dct.forward(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double tmp;
- long idx0 = offa + nl - 1;
- long idx1;
- long idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a.getDouble(idx2);
- idx1 = idx0 - i;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, tmp);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx0 = offa + nl - 1;
- long idx1;
- long idx2;
- for (long i = 0; i < nd2; i++) {
- idx2 = offa + i;
- tmp = a.getDouble(idx2);
- idx1 = idx0 - i;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, tmp);
- }
- }
- }
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(double[] a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(DoubleLargeArray a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final int offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- inverse(new DoubleLargeArray(a), offa, scale);
- } else {
- double tmp;
- int nd2 = n / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double tmp;
- int idx0 = offa + n - 1;
- int idx1, idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx0 = offa + n - 1;
- for (int i = 0; i < nd2; i++) {
- tmp = a[offa + i];
- a[offa + i] = a[idx0 - i];
- a[idx0 - i] = tmp;
- }
- }
- dct.inverse(a, offa, scale);
- int startidx = 1 + offa;
- int stopidx = offa + n;
- for (int i = startidx; i < stopidx; i += 2) {
- a[i] = -a[i];
- }
- }
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final long offa, boolean scale) {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- double tmp;
- long nd2 = nl / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double tmp;
- long idx0 = offa + nl - 1;
- long idx1, idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a.getDouble(idx2);
- idx1 = idx0 - i;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, tmp);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx0 = offa + nl - 1;
- for (long i = 0; i < nd2; i++) {
- tmp = a.getDouble(offa + i);
- a.setDouble(offa + i, a.getDouble(idx0 - i));
- a.setDouble(idx0 - i, tmp);
- }
- }
- dct.inverse(a, offa, scale);
- long startidx = 1 + offa;
- long stopidx = offa + nl;
- for (long i = startidx; i < stopidx; i += 2) {
- a.setDouble(i, -a.getDouble(i));
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/DoubleDST_2D.java b/src/main/java/org/jtransforms/dst/DoubleDST_2D.java
deleted file mode 100644
index 47241cd..0000000
--- a/src/main/java/org/jtransforms/dst/DoubleDST_2D.java
+++ /dev/null
@@ -1,1105 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 2D Discrete Sine Transform (DST) of double precision data. The sizes
- * of both dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DST (DST-II) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DST (DST-II) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a[i], scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl + c));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setDouble(r * columnsl + c, temp.getDouble(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a[i], scale);
- }
- double[] temp = new double[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- private void ddxt2d_subth(final int isgn, final double[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final double[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.forward(a, r * columns, scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dstColumns.forward(a, r * columnsl, scale);
- }
- } else {
- for (long r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final double[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.forward(a[r], scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, double[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, double[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/DoubleDST_3D.java b/src/main/java/org/jtransforms/dst/DoubleDST_3D.java
deleted file mode 100644
index 5caf44c..0000000
--- a/src/main/java/org/jtransforms/dst/DoubleDST_3D.java
+++ /dev/null
@@ -1,2101 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 3D Discrete Sine Transform (DST) of double precision data. The sizes
- * of all three dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DST (DST-II) leaving the result in a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dstSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dstSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DST (DST-II) leaving the result in a
- * . The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final double[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
-
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final DoubleLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- DoubleLargeArray temp = new DoubleLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dstSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- DoubleLargeArray temp = new DoubleLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setDouble(r, a.getDouble(idx3));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setDouble(idx3, temp.getDouble(r));
- }
- }
- }
- temp = new DoubleLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setDouble(s, a.getDouble(idx3));
- }
- dstSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setDouble(idx3, temp.getDouble(s));
- }
- }
- }
- }
- }
-
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final double[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- double[] temp = new double[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- }
- double[] temp = new double[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new double[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
-
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, DoubleLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- dstSlices.forward(t, 2 * slicesl, scale);
- dstSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- dstSlices.inverse(t, 2 * slicesl, scale);
- dstSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, double[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- double[] t = new double[nt];
-
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
-
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
-
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1l;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + rowsl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * rowsl, a.getDouble(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + rowsl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setDouble(r, a.getDouble(idx1));
- t.setDouble(rowsl + r, a.getDouble(idx1 + 1));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setDouble(idx1, t.getDouble(r));
- a.setDouble(idx1 + 1, t.getDouble(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final DoubleLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- dstSlices.forward(t, 2 * slicesl, scale);
- dstSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(idx2, a.getDouble(idx1 + 1));
- t.setDouble(idx2 + slicesl, a.getDouble(idx1 + 2));
- t.setDouble(idx2 + 2 * slicesl, a.getDouble(idx1 + 3));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- dstSlices.inverse(t, 2 * slicesl, scale);
- dstSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(idx2));
- a.setDouble(idx1 + 2, t.getDouble(idx2 + slicesl));
- a.setDouble(idx1 + 3, t.getDouble(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setDouble(s, a.getDouble(idx1));
- t.setDouble(slicesl + s, a.getDouble(idx1 + 1));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setDouble(idx1, t.getDouble(s));
- a.setDouble(idx1 + 1, t.getDouble(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final double[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/FloatDST_1D.java b/src/main/java/org/jtransforms/dst/FloatDST_1D.java
deleted file mode 100644
index e50cfcc..0000000
--- a/src/main/java/org/jtransforms/dst/FloatDST_1D.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.dct.FloatDCT_1D;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 1D Discrete Sine Transform (DST) of float precision data. The size
- * of data can be an arbitrary number. It uses DCT algorithm. This is a parallel
- * implementation optimized for SMP systems.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class FloatDST_1D {
-
- private final int n;
- private final long nl;
- private final FloatDCT_1D dct;
- private final boolean useLargeArrays;
-
- /**
- * Creates new instance of FloatDST_1D.
- *
- * @param n size of data
- */
- public FloatDST_1D(long n) {
- this.n = (int) n;
- this.nl = n;
- this.useLargeArrays = n >= ConcurrencyUtils.getLargeArraysBeginN();
- dct = new FloatDCT_1D(n);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(float[] a, boolean scale) {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(FloatLargeArray a, boolean scale) {
- forward(a, 0, scale);
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final float[] a, final int offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- forward(new FloatLargeArray(a), offa, scale);
- } else {
- float tmp;
- int nd2 = n / 2;
- int startIdx = 1 + offa;
- int stopIdx = offa + n;
- for (int i = startIdx; i < stopIdx; i += 2) {
- a[i] = -a[i];
- }
- dct.forward(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float tmp;
- int idx0 = offa + n - 1;
- int idx1;
- int idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx0 = offa + n - 1;
- int idx1;
- int idx2;
- for (int i = 0; i < nd2; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- }
- }
-
- /**
- * Computes 1D forward DST (DST-II) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final long offa, boolean scale) {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- forward(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- float tmp;
- long nd2 = nl / 2;
- long startIdx = 1 + offa;
- long stopIdx = offa + nl;
- for (long i = startIdx; i < stopIdx; i += 2) {
- a.setFloat(i, -a.getFloat(i));
- }
- dct.forward(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float tmp;
- long idx0 = offa + nl - 1;
- long idx1;
- long idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a.getFloat(idx2);
- idx1 = idx0 - i;
- a.setFloat(idx2, a.getFloat(idx1));
- a.setFloat(idx1, tmp);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx0 = offa + nl - 1;
- long idx1;
- long idx2;
- for (long i = 0; i < nd2; i++) {
- idx2 = offa + i;
- tmp = a.getFloat(idx2);
- idx1 = idx0 - i;
- a.setFloat(idx2, a.getFloat(idx1));
- a.setFloat(idx1, tmp);
- }
- }
- }
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(float[] a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(FloatLargeArray a, boolean scale) {
- inverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final int offa, boolean scale) {
- if (n == 1) {
- return;
- }
- if (useLargeArrays) {
- inverse(new FloatLargeArray(a), offa, scale);
- } else {
- float tmp;
- int nd2 = n / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final int k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final int firstIdx = j * k;
- final int lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float tmp;
- int idx0 = offa + n - 1;
- int idx1, idx2;
- for (int i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a[idx2];
- idx1 = idx0 - i;
- a[idx2] = a[idx1];
- a[idx1] = tmp;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx0 = offa + n - 1;
- for (int i = 0; i < nd2; i++) {
- tmp = a[offa + i];
- a[offa + i] = a[idx0 - i];
- a[idx0 - i] = tmp;
- }
- }
- dct.inverse(a, offa, scale);
- int startidx = 1 + offa;
- int stopidx = offa + n;
- for (int i = startidx; i < stopidx; i += 2) {
- a[i] = -a[i];
- }
- }
- }
-
- /**
- * Computes 1D inverse DST (DST-III) leaving the result in a.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final long offa, boolean scale) {
- if (nl == 1) {
- return;
- }
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- inverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- float tmp;
- long nd2 = nl / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nd2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- nthreads = 2;
- final long k = nd2 / nthreads;
- Future>[] futures = new Future[nthreads];
- for (int j = 0; j < nthreads; j++) {
- final long firstIdx = j * k;
- final long lastIdx = (j == (nthreads - 1)) ? nd2 : firstIdx + k;
- futures[j] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float tmp;
- long idx0 = offa + nl - 1;
- long idx1, idx2;
- for (long i = firstIdx; i < lastIdx; i++) {
- idx2 = offa + i;
- tmp = a.getFloat(idx2);
- idx1 = idx0 - i;
- a.setFloat(idx2, a.getFloat(idx1));
- a.setFloat(idx1, tmp);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx0 = offa + nl - 1;
- for (long i = 0; i < nd2; i++) {
- tmp = a.getFloat(offa + i);
- a.setFloat(offa + i, a.getFloat(idx0 - i));
- a.setFloat(idx0 - i, tmp);
- }
- }
- dct.inverse(a, offa, scale);
- long startidx = 1 + offa;
- long stopidx = offa + nl;
- for (long i = startidx; i < stopidx; i += 2) {
- a.setFloat(i, -a.getFloat(i));
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/FloatDST_2D.java b/src/main/java/org/jtransforms/dst/FloatDST_2D.java
deleted file mode 100644
index f5c5733..0000000
--- a/src/main/java/org/jtransforms/dst/FloatDST_2D.java
+++ /dev/null
@@ -1,1105 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 2D Discrete Sine Transform (DST) of single precision data. The sizes
- * of both dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a, i * columns, scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DST (DST-II) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dstColumns.forward(a, i * columnsl, scale);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D forward DST (DST-II) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(-1, a, scale);
- ddxt2d0_subth(-1, a, scale);
- } else {
- ddxt2d_sub(-1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.forward(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.forward(a[i], scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a, i * columns, scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r * columns + c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r * columns + c] = temp[r];
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 1D array in row-major order.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (long i = 0; i < rowsl; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columnsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = l * p;
- final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = firstColumn; c < lastColumn; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long i = 0; i < rowsl; i++) {
- dstColumns.inverse(a, i * columnsl, scale);
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- temp.setFloat(r, a.getFloat(r * columnsl + c));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- a.setFloat(r * columnsl + c, temp.getFloat(r));
- }
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DST (DST-III) leaving the result in a.
- * The data is stored in 2D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt2d_subth(1, a, scale);
- ddxt2d0_subth(1, a, scale);
- } else {
- ddxt2d_sub(1, a, scale);
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a[i], scale);
- }
- }
- } else {
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstRow; i < lastRow; i++) {
- dstColumns.inverse(a[i], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = columns / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = l * p;
- final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int c = firstColumn; c < lastColumn; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int i = 0; i < rows; i++) {
- dstColumns.inverse(a[i], scale);
- }
- float[] temp = new float[rows];
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[r][c] = temp[r];
- }
- }
- }
- }
- }
-
- private void ddxt2d_subth(final int isgn, final float[] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- t[idx2] = a[idx1];
- t[idx2 + rows] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- int nthread = (int) Math.min(columnsl, ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- final long ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 4 * n0; c < columnsl; c += 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- t.setFloat(idx2, a.getFloat(idx1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = r;
- a.setFloat(idx1, t.getFloat(idx2));
- a.setFloat(idx1 + 1, t.getFloat(idx2 + rowsl));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_subth(final int isgn, final float[][] a, final boolean scale) {
- int nthread = Math.min(columns, ConcurrencyUtils.getNumberOfThreads());
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- final int ntf = nt;
- final int nthreads = nthread;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 4 * n0; c < columns; c += 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + rows] = a[r][2 * n0 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx2 = r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + rows];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.forward(a, r * columns, scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a, r * columns, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- dstColumns.forward(a, r * columnsl, scale);
- }
- } else {
- for (long r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a, r * columnsl, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d0_subth(final int isgn, final float[][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.forward(a[r], scale);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- dstColumns.inverse(a[r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt2d_sub(int isgn, float[] a, boolean scale) {
- int idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- } else if (columnsl < 2) {
- nt >>= 2;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (columnsl > 2) {
- if (isgn == -1) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
-
- private void ddxt2d_sub(int isgn, float[][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- } else if (columns < 2) {
- nt >>= 2;
- }
- float[] t = new float[nt];
- if (columns > 2) {
- if (isgn == -1) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[r][c];
- t[idx2] = a[r][c + 1];
- t[idx2 + rows] = a[r][c + 2];
- t[idx2 + 2 * rows] = a[r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[r][c] = t[r];
- a[r][c + 1] = t[idx2];
- a[r][c + 2] = t[idx2 + rows];
- a[r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[r][0];
- t[rows + r] = a[r][1];
- }
- if (isgn == -1) {
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- } else {
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- }
- for (int r = 0; r < rows; r++) {
- a[r][0] = t[r];
- a[r][1] = t[rows + r];
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/FloatDST_3D.java b/src/main/java/org/jtransforms/dst/FloatDST_3D.java
deleted file mode 100644
index 6625fc6..0000000
--- a/src/main/java/org/jtransforms/dst/FloatDST_3D.java
+++ /dev/null
@@ -1,2101 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dst;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Computes 3D Discrete Sine Transform (DST) of single precision data. The sizes
- * of all three dimensions can be arbitrary numbers. This is a parallel
- * implementation optimized for SMP systems.a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx1 + r * rowStride, scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DST (DST-II) leaving the result in a
- * . The data is stored in 1D array addressed in slice-major, then
- * row-major, then column-major, in order of significance, i.e. the element
- * (i,j,k) of 3D array x[slices][rows][columns] is stored in a[i*sliceStride
- * + j*rowStride + k], where sliceStride = rows * columns and rowStride =
- * columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dstSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx1 + r * rowStridel, scale);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dstRows.forward(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStridel + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStridel;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dstSlices.forward(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStridel + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D forward DST (DST-II) leaving the result in a
- * . The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void forward(final float[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(-1, a, scale);
- ddxt3db_subth(-1, a, scale);
- } else {
- ddxt3da_sub(-1, a, scale);
- ddxt3db_sub(-1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.forward(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.forward(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- int idx1 = s * sliceStride;
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- temp[r] = a[idx3];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * rowStride + c;
- a[idx3] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- int idx1 = r * rowStride;
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- temp[s] = a[idx3];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx3 = s * sliceStride + idx1 + c;
- a[idx3] = temp[s];
- }
- }
- }
- }
- }
-
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. the
- * element (i,j,k) of 3D array x[slices][rows][columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * columns
- * and rowStride = columns.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final FloatLargeArray a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- FloatLargeArray temp = new FloatLargeArray(slicesl, false);
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dstSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx1 + r * rowStride, scale);
- }
- }
- FloatLargeArray temp = new FloatLargeArray(rowsl, false);
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * sliceStride;
- for (long c = 0; c < columnsl; c++) {
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- temp.setFloat(r, a.getFloat(idx3));
- }
- dstRows.inverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * rowStride + c;
- a.setFloat(idx3, temp.getFloat(r));
- }
- }
- }
- temp = new FloatLargeArray(slicesl, false);
- for (long r = 0; r < rowsl; r++) {
- long idx1 = r * rowStride;
- for (long c = 0; c < columnsl; c++) {
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- temp.setFloat(s, a.getFloat(idx3));
- }
- dstSlices.inverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx3 = s * sliceStride + idx1 + c;
- a.setFloat(idx3, temp.getFloat(s));
- }
- }
- }
- }
- }
-
- }
-
- /**
- * Computes the 3D inverse DST (DST-III) leaving the result in
- * a. The data is stored in 3D array.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void inverse(final float[][][] a, final boolean scale) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if (isPowerOfTwo) {
- if ((nthreads > 1) && useThreads) {
- ddxt3da_subth(1, a, scale);
- ddxt3db_subth(1, a, scale);
- } else {
- ddxt3da_sub(1, a, scale);
- ddxt3db_sub(1, a, scale);
- }
- } else {
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[rows];
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- float[] temp = new float[slices];
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- }
- float[] temp = new float[rows];
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- for (int r = 0; r < rows; r++) {
- temp[r] = a[s][r][c];
- }
- dstRows.inverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][c] = temp[r];
- }
- }
- }
- temp = new float[slices];
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c++) {
- for (int s = 0; s < slices; s++) {
- temp[s] = a[s][r][c];
- }
- dstSlices.inverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][c] = temp[s];
- }
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[r] = a[idx1];
- t[rows + r] = a[idx1 + 1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[r];
- a[idx1 + 1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
-
- private void ddxt3da_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
-
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[r] = a[s][r][0];
- t[rows + r] = a[s][r][1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[r];
- a[s][r][1] = t[rows + r];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[] a, boolean scale) {
- int idx0, idx1, idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[s] = a[idx1];
- t[slices + s] = a[idx1 + 1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[s];
- a[idx1 + 1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, FloatLargeArray a, boolean scale) {
- long idx0, idx1, idx2;
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- FloatLargeArray t = new FloatLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- dstSlices.forward(t, 2 * slicesl, scale);
- dstSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- dstSlices.inverse(t, 2 * slicesl, scale);
- dstSlices.inverse(t, 3 * slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
-
- private void ddxt3db_sub(int isgn, float[][][] a, boolean scale) {
- int idx2;
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- float[] t = new float[nt];
-
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- t[s] = a[s][r][0];
- t[slices + s] = a[s][r][1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[s];
- a[s][r][1] = t[slices + s];
- }
- }
- }
- }
- }
-
- private void ddxt3da_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
-
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a, idx0 + r * rowStride, scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- t[ r] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + rows] = a[idx1 + 2];
- t[idx2 + 2 * rows] = a[idx1 + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = rows + r;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + rows];
- a[idx1 + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- t[ r] = a[idx1];
- t[ rows + r] = a[idx1 + 1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- a[idx1] = t[ r];
- a[idx1 + 1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > slicesl ? slicesl : ConcurrencyUtils.getNumberOfThreads());
-
- long nt = 4 * rowsl;
- if (columnsl == 2) {
- nt >>= 1l;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.forward(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- dstRows.forward(t, 2 * rowsl, scale);
- dstRows.forward(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- dstColumns.inverse(a, idx0 + r * rowStridel, scale);
- }
- if (columnsl > 2) {
- for (long c = 0; c < columnsl; c += 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + rowsl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * rowsl, a.getFloat(idx1 + 3));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- dstRows.inverse(t, 2 * rowsl, scale);
- dstRows.inverse(t, 3 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = rowsl + r;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + rowsl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * rowsl));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- t.setFloat(r, a.getFloat(idx1));
- t.setFloat(rowsl + r, a.getFloat(idx1 + 1));
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- a.setFloat(idx1, t.getFloat(r));
- a.setFloat(idx1 + 1, t.getFloat(rowsl + r));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3da_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > slices ? slices : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * rows;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dstColumns.forward(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- dstRows.forward(t, 2 * rows, scale);
- dstRows.forward(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dstRows.forward(t, 0, scale);
- dstRows.forward(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- for (int r = 0; r < rows; r++) {
- dstColumns.inverse(a[s][r], scale);
- }
- if (columns > 2) {
- for (int c = 0; c < columns; c += 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- t[ r] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + rows] = a[s][r][c + 2];
- t[idx2 + 2 * rows] = a[s][r][c + 3];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- dstRows.inverse(t, 2 * rows, scale);
- dstRows.inverse(t, 3 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = rows + r;
- a[s][r][c] = t[ r];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + rows];
- a[s][r][c + 3] = t[idx2 + 2 * rows];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- t[ r] = a[s][r][0];
- t[ rows + r] = a[s][r][1];
- }
- dstRows.inverse(t, 0, scale);
- dstRows.inverse(t, rows, scale);
- for (int r = 0; r < rows; r++) {
- a[s][r][0] = t[ r];
- a[s][r][1] = t[ rows + r];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx0, idx1, idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- t[ s] = a[idx1];
- t[idx2] = a[idx1 + 1];
- t[idx2 + slices] = a[idx1 + 2];
- t[idx2 + 2 * slices] = a[idx1 + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = slices + s;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[idx2];
- a[idx1 + 2] = t[idx2 + slices];
- a[idx1 + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- t[ s] = a[idx1];
- t[ slices + s] = a[idx1 + 1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- a[idx1] = t[ s];
- a[idx1 + 1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final FloatLargeArray a, final boolean scale) {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
- long nt = 4 * slicesl;
- if (columnsl == 2) {
- nt >>= 1;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- long idx0, idx1, idx2;
- FloatLargeArray t = new FloatLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- dstSlices.forward(t, 2 * slicesl, scale);
- dstSlices.forward(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- } else {
- if (columnsl > 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 4) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(idx2, a.getFloat(idx1 + 1));
- t.setFloat(idx2 + slicesl, a.getFloat(idx1 + 2));
- t.setFloat(idx2 + 2 * slicesl, a.getFloat(idx1 + 3));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
- dstSlices.inverse(t, 2 * slicesl, scale);
- dstSlices.inverse(t, 3 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = slicesl + s;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(idx2));
- a.setFloat(idx1 + 2, t.getFloat(idx2 + slicesl));
- a.setFloat(idx1 + 3, t.getFloat(idx2 + 2 * slicesl));
- }
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- t.setFloat(s, a.getFloat(idx1));
- t.setFloat(slicesl + s, a.getFloat(idx1 + 1));
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slicesl, scale);
-
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- a.setFloat(idx1, t.getFloat(s));
- a.setFloat(idx1 + 1, t.getFloat(slicesl + s));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void ddxt3db_subth(final int isgn, final float[][][] a, final boolean scale) {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
- int nt = 4 * slices;
- if (columns == 2) {
- nt >>= 1;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
-
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
-
- public void run() {
- int idx2;
- float[] t = new float[ntf];
- if (isgn == -1) {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- dstSlices.forward(t, 2 * slices, scale);
- dstSlices.forward(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dstSlices.forward(t, 0, scale);
- dstSlices.forward(t, slices, scale);
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- } else {
- if (columns > 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 4) {
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- t[ s] = a[s][r][c];
- t[idx2] = a[s][r][c + 1];
- t[idx2 + slices] = a[s][r][c + 2];
- t[idx2 + 2 * slices] = a[s][r][c + 3];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
- dstSlices.inverse(t, 2 * slices, scale);
- dstSlices.inverse(t, 3 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = slices + s;
- a[s][r][c] = t[ s];
- a[s][r][c + 1] = t[idx2];
- a[s][r][c + 2] = t[idx2 + slices];
- a[s][r][c + 3] = t[idx2 + 2 * slices];
- }
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- t[ s] = a[s][r][0];
- t[ slices + s] = a[s][r][1];
- }
- dstSlices.inverse(t, 0, scale);
- dstSlices.inverse(t, slices, scale);
-
- for (int s = 0; s < slices; s++) {
- a[s][r][0] = t[ s];
- a[s][r][1] = t[ slices + s];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-}
diff --git a/src/main/java/org/jtransforms/dst/package.html b/src/main/java/org/jtransforms/dst/package.html
deleted file mode 100644
index 1e2097c..0000000
--- a/src/main/java/org/jtransforms/dst/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Discrete Sine Transforms.
-
-
diff --git a/src/main/java/org/jtransforms/fft/BenchmarkDoubleFFT.java b/src/main/java/org/jtransforms/fft/BenchmarkDoubleFFT.java
deleted file mode 100644
index 4d309ae..0000000
--- a/src/main/java/org/jtransforms/fft/BenchmarkDoubleFFT.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Benchmark of single precision FFT's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkDoubleFFT
-{
-
- private static int nthread = 16;
-
- private static int niter = 100;
-
- private static int nsize = 8;
-
- private static int threadsBegin2D = 65536;
-
- private static int threadsBegin3D = 65536;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkDoubleFFT()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkComplexForward_1D()
- {
- double[] x;
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_1D fft = new DoubleFFT_1D(sizes1D[i]);
- x = new double[(int) (2 * sizes1D[i])];
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- fft.complexForward(x);
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- fft.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_1D fft = new DoubleFFT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) (2 * sizes1D[i])];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- elapsedTime = System.nanoTime();
- fft.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleComplexForwardFFT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkRealForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_1D fft = new DoubleFFT_1D(sizes1D[i]);
- x = new double[(int) (2 * sizes1D[i])];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- fft.realForwardFull(x);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- fft.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_1D fft = new DoubleFFT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) (2 * sizes1D[i])];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- fft.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleRealForwardFFT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkComplexForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- x = new DoubleLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- int niter_local = niter;
- if (sizes2D[i] >= (1 << 13)) {
- niter_local = Math.max(1, niter / 10);
- }
- for (int j = 0; j < niter_local; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleComplexForwardFFT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- x = new double[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleComplexForwardFFT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- x = new DoubleLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleRealForwardFFT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- x = new double[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_2D fft2 = new DoubleFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleRealForwardFFT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- int niter_local = niter;
- if (sizes3D[i] >= (1 << 10)) {
- niter_local = Math.max(1, niter / 10);
- }
- for (int j = 0; j < niter_local; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleComplexForwardFFT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleComplexForwardFFT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- DoubleLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new DoubleLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleRealForwardFFT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- double[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- DoubleFFT_3D fft3 = new DoubleFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new double[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkDoubleRealForwardFFT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkComplexForward_1D();
- benchmarkRealForward_1D();
-
- benchmarkComplexForward_2D_input_1D();
- benchmarkComplexForward_2D_input_2D();
- benchmarkRealForward_2D_input_1D();
- benchmarkRealForward_2D_input_2D();
-
- benchmarkComplexForward_3D_input_1D();
- benchmarkComplexForward_3D_input_3D();
- benchmarkRealForward_3D_input_1D();
- benchmarkRealForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/BenchmarkFloatFFT.java b/src/main/java/org/jtransforms/fft/BenchmarkFloatFFT.java
deleted file mode 100644
index 088a619..0000000
--- a/src/main/java/org/jtransforms/fft/BenchmarkFloatFFT.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.Arrays;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * Benchmark of single precision FFT's
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class BenchmarkFloatFFT
-{
-
- private static int nthread = 16;
-
- private static int niter = 100;
-
- private static int nsize = 8;
-
- private static int threadsBegin2D = 65536;
-
- private static int threadsBegin3D = 65536;
-
- private static boolean doWarmup = true;
-
- private static long[] sizes1D = new long[]{262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 10368, 27000, 75600, 165375, 362880, 1562500, 3211264, 6250000};
-
- private static long[] sizes2D = new long[]{256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 260, 520, 1050, 1458, 1960, 2916, 4116, 5832};
-
- private static long[] sizes3D = new long[]{16, 32, 64, 128, 256, 512, 1024, 2048, 5, 17, 30, 95, 180, 270, 324, 420};
-
- private static boolean doScaling = false;
-
- private BenchmarkFloatFFT()
- {
-
- }
-
- public static void parseArguments(String[] args)
- {
- if (args.length > 0) {
- nthread = Integer.parseInt(args[0]);
- threadsBegin2D = Integer.parseInt(args[1]);
- threadsBegin3D = Integer.parseInt(args[2]);
- niter = Integer.parseInt(args[3]);
- doWarmup = Boolean.parseBoolean(args[4]);
- doScaling = Boolean.parseBoolean(args[5]);
- nsize = Integer.parseInt(args[6]);
- sizes1D = new long[nsize];
- sizes2D = new long[nsize];
- sizes3D = new long[nsize];
- for (int i = 0; i < nsize; i++) {
- sizes1D[i] = Integer.parseInt(args[7 + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes2D[i] = Integer.parseInt(args[7 + nsize + i]);
- }
- for (int i = 0; i < nsize; i++) {
- sizes3D[i] = Integer.parseInt(args[7 + nsize + nsize + i]);
- }
- } else {
- System.out.println("Default settings are used.");
- }
- ConcurrencyUtils.setNumberOfThreads(nthread);
- ConcurrencyUtils.setThreadsBeginN_2D(threadsBegin2D);
- ConcurrencyUtils.setThreadsBeginN_3D(threadsBegin3D);
- System.out.println("nthred = " + nthread);
- System.out.println("threadsBegin2D = " + threadsBegin2D);
- System.out.println("threadsBegin3D = " + threadsBegin3D);
- System.out.println("niter = " + niter);
- System.out.println("doWarmup = " + doWarmup);
- System.out.println("doScaling = " + doScaling);
- System.out.println("nsize = " + nsize);
- System.out.println("sizes1D[] = " + Arrays.toString(sizes1D));
- System.out.println("sizes2D[] = " + Arrays.toString(sizes2D));
- System.out.println("sizes3D[] = " + Arrays.toString(sizes3D));
- }
-
- public static void benchmarkComplexForward_1D()
- {
- float[] x;
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_1D fft = new FloatFFT_1D(sizes1D[i]);
- x = new float[(int) (2 * sizes1D[i])];
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- fft.complexForward(x);
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- fft.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_1D fft = new FloatFFT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) (2 * sizes1D[i])];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(2 * sizes1D[i], x);
- elapsedTime = System.nanoTime();
- fft.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatComplexForwardFFT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkRealForward_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 1D of size " + sizes1D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_1D fft = new FloatFFT_1D(sizes1D[i]);
- x = new float[(int) (2 * sizes1D[i])];
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- fft.realForwardFull(x);
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- fft.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_1D fft = new FloatFFT_1D(sizes1D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) (2 * sizes1D[i])];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_1D(sizes1D[i], x);
- elapsedTime = System.nanoTime();
- fft.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatRealForwardFFT_1D.txt", nthread, niter, doWarmup, doScaling, sizes1D, times_without_constructor, times_with_constructor);
-
- }
-
- public static void benchmarkComplexForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- x = new FloatLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- int niter_local = niter;
- if (sizes2D[i] >= (1 << 13)) {
- niter_local = Math.max(1, niter / 10);
- }
- for (int j = 0; j < niter_local; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatComplexForwardFFT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- x = new float[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- fft2.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], 2 * sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatComplexForwardFFT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_2D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 2D (input 1D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- x = new FloatLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes2D[i] * 2 * sizes2D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatRealForwardFFT_2D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_2D_input_2D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 2D (input 2D) of size " + sizes2D[i] + " x " + sizes2D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- x = new float[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- fft2.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_2D fft2 = new FloatFFT_2D(sizes2D[i], sizes2D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes2D[i]][2 * (int) sizes2D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_2D(sizes2D[i], sizes2D[i], x);
- elapsedTime = System.nanoTime();
- fft2.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft2 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatRealForwardFFT_2D_input_2D.txt", nthread, niter, doWarmup, doScaling, sizes2D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- int niter_local = niter;
- if (sizes3D[i] >= (1 << 10)) {
- niter_local = Math.max(1, niter / 10);
- }
- for (int j = 0; j < niter_local; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatComplexForwardFFT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkComplexForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Complex forward FFT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- fft3.complexForward(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], 2 * sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.complexForward(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatComplexForwardFFT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_3D_input_1D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- FloatLargeArray x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 3D (input 1D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new FloatLargeArray(sizes3D[i] * sizes3D[i] * 2 * sizes3D[i], false);
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatRealForwardFFT_3D_input_1D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void benchmarkRealForward_3D_input_3D()
- {
- double[] times_without_constructor = new double[nsize];
- double[] times_with_constructor = new double[nsize];
- float[][][] x;
- for (int i = 0; i < nsize; i++) {
- System.out.println("Real forward FFT 3D (input 3D) of size " + sizes3D[i] + " x " + sizes3D[i] + " x " + sizes3D[i]);
- if (doWarmup) { // call the transform twice to warm up
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- fft3.realForwardFull(x);
- }
- long elapsedTime = System.nanoTime();
- FloatFFT_3D fft3 = new FloatFFT_3D(sizes3D[i], sizes3D[i], sizes3D[i]);
- times_with_constructor[i] = (System.nanoTime() - elapsedTime) / 1000000.0;
- x = new float[(int) sizes3D[i]][(int) sizes3D[i]][2 * (int) sizes3D[i]];
- double min_time = Double.MAX_VALUE;
- for (int j = 0; j < niter; j++) {
- IOUtils.fillMatrix_3D(sizes3D[i], sizes3D[i], sizes3D[i], x);
- elapsedTime = System.nanoTime();
- fft3.realForwardFull(x);
- elapsedTime = System.nanoTime() - elapsedTime;
- if (elapsedTime < min_time) {
- min_time = elapsedTime;
- }
- }
- times_without_constructor[i] = (double) min_time / 1000000.0;
- times_with_constructor[i] += times_without_constructor[i];
- System.out.println("\tBest execution time without constructor: " + String.format("%.2f", times_without_constructor[i]) + " msec");
- System.out.println("\tBest execution time with constructor: " + String.format("%.2f", times_with_constructor[i]) + " msec");
- x = null;
- fft3 = null;
- System.gc();
- ConcurrencyUtils.sleep(5000);
- }
- IOUtils.writeFFTBenchmarkResultsToFile("benchmarkFloatRealForwardFFT_3D_input_3D.txt", nthread, niter, doWarmup, doScaling, sizes3D, times_without_constructor, times_with_constructor);
- }
-
- public static void main(String[] args)
- {
- parseArguments(args);
- benchmarkComplexForward_1D();
- benchmarkRealForward_1D();
-
- benchmarkComplexForward_2D_input_1D();
- benchmarkComplexForward_2D_input_2D();
- benchmarkRealForward_2D_input_1D();
- benchmarkRealForward_2D_input_2D();
-
- benchmarkComplexForward_3D_input_1D();
- benchmarkComplexForward_3D_input_3D();
- benchmarkRealForward_3D_input_1D();
- benchmarkRealForward_3D_input_3D();
- System.exit(0);
-
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/DoubleFFT_1D.java b/src/main/java/org/jtransforms/fft/DoubleFFT_1D.java
deleted file mode 100644
index 985e630..0000000
--- a/src/main/java/org/jtransforms/fft/DoubleFFT_1D.java
+++ /dev/null
@@ -1,7682 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.CommonUtils;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.LongLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 1D Discrete Fourier Transform (DFT) of complex and real, double
- * precision data. The size of the data can be an arbitrary number. This is a
- * parallel implementation of split-radix and mixed-radix algorithms optimized
- * for SMP systems. a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - */ - public void complexForward(double[] a) { - complexForward(a, 0); - } - - /** - * Computes 1D forward DFT of complex data leaving the result in - *
a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - */ - public void complexForward(DoubleLargeArray a) { - complexForward(a, 0); - } - - /** - * Computes 1D forward DFT of complex data leaving the result in - *
a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- */
- public void complexForward(double[] a, int offa) {
- if (useLargeArrays) {
- complexForward(new DoubleLargeArray(a), offa);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftbsub(2 * n, a, offa, ip, nw, w);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, -1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of complex data leaving the result in
- * a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- */
- public void complexForward(DoubleLargeArray a, long offa) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- complexForward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftbsub(2 * nl, a, offa, ipl, nwl, wl);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, -1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of complex data leaving the result in
- * a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(double[] a, boolean scale) { - complexInverse(a, 0, scale); - } - - /** - * Computes 1D inverse DFT of complex data leaving the result in - *
a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[2*k] = Re[k], a[2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(DoubleLargeArray a, boolean scale) { - complexInverse(a, 0, scale); - } - - /** - * Computes 1D inverse DFT of complex data leaving the result in - *
a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- * @param scale if true then scaling is performed
- */
- public void complexInverse(double[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- complexInverse(new DoubleLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftfsub(2 * n, a, offa, ip, nw, w);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, +1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, 1);
- break;
- }
- if (scale) {
- CommonUtils.scale(n, 1.0 / (double) n, a, offa, true);
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of complex data leaving the result in
- * a. Complex number is stored as two double values in
- * sequence: the real and imaginary part, i.e. the size of the input array
- * must be greater or equal 2*n. The physical layout of the input data has
- * to be as follows:- * a[offa+2*k] = Re[k], a[offa+2*k+1] = Im[k], 0<=k<n - *- * - * @param a data to transform - * @param offa index of the first element in array
a
- * @param scale if true then scaling is performed
- */
- public void complexInverse(DoubleLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- complexInverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- CommonUtils.cftfsub(2 * nl, a, offa, ipl, nwl, wl);
- break;
- case MIXED_RADIX:
- cfftf(a, offa, +1);
- break;
- case BLUESTEIN:
- bluestein_complex(a, offa, 1);
- break;
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0 / (double) nl, a, offa, true);
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(double[] a) {
- realForward(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(DoubleLargeArray a) {
- realForward(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForward(double[] a, int offa) {
- if (useLargeArrays) {
- realForward(new DoubleLargeArray(a), offa);
- } else {
- if (n == 1) {
- return;
- }
-
- switch (plan) {
- case SPLIT_RADIX:
- double xi;
-
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- CommonUtils.rftfsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftx020(a, offa);
- }
- xi = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- a[offa + 1] = xi;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (int k = n - 1; k >= 2; k--) {
- int idx = offa + k;
- double tmp = a[idx];
- a[idx] = a[idx - 1];
- a[idx - 1] = tmp;
- }
- break;
- case BLUESTEIN:
- bluestein_real_forward(a, offa);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . The physical layout of the output data is as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForward(DoubleLargeArray a, long offa) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realForward(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
-
- switch (plan) {
- case SPLIT_RADIX:
- double xi;
-
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftx020(a, offa);
- }
- xi = a.getDouble(offa) - a.getDouble(offa + 1);
- a.setDouble(offa, a.getDouble(offa) + a.getDouble(offa + 1));
- a.setDouble(offa + 1, xi);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (long k = nl - 1; k >= 2; k--) {
- long idx = offa + k;
- double tmp = a.getDouble(idx);
- a.setDouble(idx, a.getDouble(idx - 1));
- a.setDouble(idx - 1, tmp);
- }
- break;
- case BLUESTEIN:
- bluestein_real_forward(a, offa);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary parts equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(double[] a) {
- realForwardFull(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary parts equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForwardFull(DoubleLargeArray a) {
- realForwardFull(a, 0);
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForwardFull(final double[] a, final int offa) {
-
- if (useLargeArrays) {
- realForwardFull(new DoubleLargeArray(a), offa);
- } else {
- final int twon = 2 * n;
- switch (plan) {
- case SPLIT_RADIX:
- realForward(a, offa);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- int k = n / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- for (int k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int k = 0; k < n / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- a[offa + n] = -a[offa + 1];
- a[offa + 1] = 0;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- } else {
- m = (n + 1) / 2;
- }
- for (int k = 1; k < m; k++) {
- int idx1 = offa + twon - 2 * k;
- int idx2 = offa + 2 * k;
- a[idx1 + 1] = -a[idx2];
- a[idx1] = a[idx2 - 1];
- }
- for (int k = 1; k < n; k++) {
- int idx = offa + n - k;
- double tmp = a[idx + 1];
- a[idx + 1] = a[idx];
- a[idx] = tmp;
- }
- a[offa + 1] = 0;
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D forward DFT of real data leaving the result in a
- * . This method computes the full real forward transform, i.e. you will get
- * the same result as from complexForward called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- */
- public void realForwardFull(final DoubleLargeArray a, final long offa) {
-
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realForwardFull(a.getData(), (int) offa);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- final long twon = 2 * nl;
- switch (plan) {
- case SPLIT_RADIX:
- realForward(a, offa);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- long k = nl / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- for (long k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setDouble(idx2, a.getDouble(offa + idx1));
- a.setDouble(idx2 + 1, -a.getDouble(offa + idx1 + 1));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long k = 0; k < nl / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setDouble(idx2, a.getDouble(offa + idx1));
- a.setDouble(idx2 + 1, -a.getDouble(offa + idx1 + 1));
- }
- }
- a.setDouble(offa + nl, -a.getDouble(offa + 1));
- a.setDouble(offa + 1, 0);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- } else {
- m = (nl + 1) / 2;
- }
- for (long k = 1; k < m; k++) {
- long idx1 = offa + twon - 2 * k;
- long idx2 = offa + 2 * k;
- a.setDouble(idx1 + 1, -a.getDouble(idx2));
- a.setDouble(idx1, a.getDouble(idx2 - 1));
- }
- for (long k = 1; k < nl; k++) {
- long idx = offa + nl - k;
- double tmp = a.getDouble(idx + 1);
- a.setDouble(idx + 1, a.getDouble(idx));
- a.setDouble(idx, tmp);
- }
- a.setDouble(offa + 1, 0);
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, -1);
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(double[] a, boolean scale) {
- realInverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[2*k] = Re[k], 0<=k<n/2 a[2*k+1] = Im[k], 0<k<n/2 a[1] = - * Re[n/2] - *- * - * if n is odd then - * - * *
- * a[2*k] = Re[k], 0<=k<(n+1)/2 a[2*k+1] = Im[k], 0<k<(n-1)/2 - * a[1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(DoubleLargeArray a, boolean scale) {
- realInverse(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(double[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- realInverse(new DoubleLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- a[offa + 1] = 0.5 * (a[offa] - a[offa + 1]);
- a[offa] -= a[offa + 1];
- if (n > 4) {
- CommonUtils.rftfsub(n, a, offa, nc, w, nw);
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- } else if (n == 4) {
- CommonUtils.cftxc020(a, offa);
- }
- if (scale) {
- CommonUtils.scale(n, 1.0 / (n / 2.0), a, offa, false);
- }
- break;
- case MIXED_RADIX:
- for (int k = 2; k < n; k++) {
- int idx = offa + k;
- double tmp = a[idx - 1];
- a[idx - 1] = a[idx];
- a[idx] = tmp;
- }
- rfftb(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- break;
- }
- }
-
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . The physical layout of the input data has to be as follows:- * a[offa+2*k] = Re[k], 0<=k<n/2 a[offa+2*k+1] = Im[k], 0<k<n/2 - * a[offa+1] = Re[n/2] - *- * - * if n is odd then - * - * *
- * a[offa+2*k] = Re[k], 0<=k<(n+1)/2 a[offa+2*k+1] = Im[k], - * 0<k<(n-1)/2 a[offa+1] = Im[(n-1)/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- *
- */
- public void realInverse(DoubleLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverse(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- a.setDouble(offa + 1, 0.5 * (a.getDouble(offa) - a.getDouble(offa + 1)));
- a.setDouble(offa, a.getDouble(offa) - a.getDouble(offa + 1));
- if (nl > 4) {
- CommonUtils.rftfsub(nl, a, offa, ncl, wl, nwl);
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- } else if (nl == 4) {
- CommonUtils.cftxc020(a, offa);
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0 / (nl / 2.0), a, offa, false);
- }
- break;
- case MIXED_RADIX:
- for (long k = 2; k < nl; k++) {
- long idx = offa + k;
- double tmp = a.getDouble(idx - 1);
- a.setDouble(idx - 1, a.getDouble(idx));
- a.setDouble(idx, tmp);
- }
- rfftb(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- break;
- }
- }
-
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(double[] a, boolean scale) {
- realInverseFull(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(DoubleLargeArray a, boolean scale) {
- realInverseFull(a, 0, scale);
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(final double[] a, final int offa, boolean scale) {
- if (useLargeArrays) {
- realInverseFull(new DoubleLargeArray(a), offa, scale);
- } else {
- final int twon = 2 * n;
- switch (plan) {
- case SPLIT_RADIX:
- realInverse2(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (n / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- int k = n / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- int idx1, idx2;
- for (int k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- int idx1, idx2;
- for (int k = 0; k < n / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a[idx2] = a[offa + idx1];
- a[idx2 + 1] = -a[offa + idx1 + 1];
- }
- }
- a[offa + n] = -a[offa + 1];
- a[offa + 1] = 0;
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- } else {
- m = (n + 1) / 2;
- }
- for (int k = 1; k < m; k++) {
- int idx1 = offa + 2 * k;
- int idx2 = offa + twon - 2 * k;
- a[idx1] = -a[idx1];
- a[idx2 + 1] = -a[idx1];
- a[idx2] = a[idx1 - 1];
- }
- for (int k = 1; k < n; k++) {
- int idx = offa + n - k;
- double tmp = a[idx + 1];
- a[idx + 1] = a[idx];
- a[idx] = tmp;
- }
- a[offa + 1] = 0;
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, 1);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, true);
- }
- break;
- }
- }
- }
-
- /**
- * Computes 1D inverse DFT of real data leaving the result in a
- * . This method computes the full real inverse transform, i.e. you will get
- * the same result as from complexInverse called with all
- * imaginary part equal 0. Because the result is stored in a,
- * the size of the input array must greater or equal 2*n, with only the
- * first n elements filled with real data.
- *
- * @param a data to transform
- * @param offa index of the first element in array a
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(final DoubleLargeArray a, final long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverseFull(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- final long twon = 2 * nl;
- switch (plan) {
- case SPLIT_RADIX:
- realInverse2(a, offa, scale);
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && (nl / 2 > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- Future>[] futures = new Future[nthreads];
- long k = nl / 2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl / 2 : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- long idx1, idx2;
- for (long k = firstIdx; k < lastIdx; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setDouble(idx2, a.getDouble(offa + idx1));
- a.setDouble(idx2 + 1, -a.getDouble(offa + idx1 + 1));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- long idx1, idx2;
- for (long k = 0; k < nl / 2; k++) {
- idx1 = 2 * k;
- idx2 = offa + ((twon - idx1) % twon);
- a.setDouble(idx2, a.getDouble(offa + idx1));
- a.setDouble(idx2 + 1, -a.getDouble(offa + idx1 + 1));
- }
- }
- a.setDouble(offa + nl, -a.getDouble(offa + 1));
- a.setDouble(offa + 1, 0);
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- } else {
- m = (nl + 1) / 2;
- }
- for (long k = 1; k < m; k++) {
- long idx1 = offa + 2 * k;
- long idx2 = offa + twon - 2 * k;
- a.setDouble(idx1, -a.getDouble(idx1));
- a.setDouble(idx2 + 1, -a.getDouble(idx1));
- a.setDouble(idx2, a.getDouble(idx1 - 1));
- }
- for (long k = 1; k < nl; k++) {
- long idx = offa + nl - k;
- double tmp = a.getDouble(idx + 1);
- a.setDouble(idx + 1, a.getDouble(idx));
- a.setDouble(idx, tmp);
- }
- a.setDouble(offa + 1, 0);
- break;
- case BLUESTEIN:
- bluestein_real_full(a, offa, 1);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, true);
- }
- break;
- }
- }
- }
-
- protected void realInverse2(double[] a, int offa, boolean scale) {
- if (useLargeArrays) {
- realInverse2(new DoubleLargeArray(a), offa, scale);
- } else {
- if (n == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- double xi;
-
- if (n > 4) {
- CommonUtils.cftfsub(n, a, offa, ip, nw, w);
- CommonUtils.rftbsub(n, a, offa, nc, w, nw);
- } else if (n == 4) {
- CommonUtils.cftbsub(n, a, offa, ip, nw, w);
- }
- xi = a[offa] - a[offa + 1];
- a[offa] += a[offa + 1];
- a[offa + 1] = xi;
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (int k = n - 1; k >= 2; k--) {
- int idx = offa + k;
- double tmp = a[idx];
- a[idx] = a[idx - 1];
- a[idx - 1] = tmp;
- }
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- int m;
- if (n % 2 == 0) {
- m = n / 2;
- for (int i = 1; i < m; i++) {
- int idx = offa + 2 * i + 1;
- a[idx] = -a[idx];
- }
- } else {
- m = (n - 1) / 2;
- for (int i = 0; i < m; i++) {
- int idx = offa + 2 * i + 1;
- a[idx] = -a[idx];
- }
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse2(a, offa);
- if (scale) {
- CommonUtils.scale(n, 1.0 / n, a, offa, false);
- }
- break;
- }
- }
- }
-
- protected void realInverse2(DoubleLargeArray a, long offa, boolean scale) {
- if (!useLargeArrays) {
- if (a.getData() != null && offa < Integer.MAX_VALUE) {
- realInverse2(a.getData(), (int) offa, scale);
- } else {
- throw new IllegalArgumentException("The data array is too big.");
- }
- } else {
- if (nl == 1) {
- return;
- }
- switch (plan) {
- case SPLIT_RADIX:
- double xi;
-
- if (nl > 4) {
- CommonUtils.cftfsub(nl, a, offa, ipl, nwl, wl);
- CommonUtils.rftbsub(nl, a, offa, ncl, wl, nwl);
- } else if (nl == 4) {
- CommonUtils.cftbsub(nl, a, offa, ipl, nwl, wl);
- }
- xi = a.getDouble(offa) - a.getDouble(offa + 1);
- a.setDouble(offa, a.getDouble(offa) + a.getDouble(offa + 1));
- a.setDouble(offa + 1, xi);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- break;
- case MIXED_RADIX:
- rfftf(a, offa);
- for (long k = nl - 1; k >= 2; k--) {
- long idx = offa + k;
- double tmp = a.getDouble(idx);
- a.setDouble(idx, a.getDouble(idx - 1));
- a.setDouble(idx - 1, tmp);
- }
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- long m;
- if (nl % 2 == 0) {
- m = nl / 2;
- for (long i = 1; i < m; i++) {
- long idx = offa + 2 * i + 1;
- a.setDouble(idx, -a.getDouble(idx));
- }
- } else {
- m = (nl - 1) / 2;
- for (long i = 0; i < m; i++) {
- long idx = offa + 2 * i + 1;
- a.setDouble(idx, -a.getDouble(idx));
- }
- }
- break;
- case BLUESTEIN:
- bluestein_real_inverse2(a, offa);
- if (scale) {
- CommonUtils.scale(nl, 1.0 / nl, a, offa, false);
- }
- break;
- }
- }
- }
-
-
- /* -------- initializing routines -------- */
-
- /*---------------------------------------------------------
- cffti: initialization of Complex FFT
- --------------------------------------------------------*/
- void cffti(int n, int offw) {
- if (n == 1) {
- return;
- }
-
- final int twon = 2 * n;
- final int fourn = 4 * n;
- double argh;
- int idot, ntry = 0, i, j;
- double argld;
- int i1, k1, l1, l2, ib;
- double fi;
- int ld, ii, nf, ipll, nll, nq, nr;
- double arg;
- int ido, ipm;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtable[offw + nf + 1 + fourn] = ntry;
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + fourn;
- wtable[offw + idx + 1] = wtable[offw + idx];
- }
- wtable[offw + 2 + fourn] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable[offw + fourn] = n;
- wtable[offw + 1 + fourn] = nf;
- argh = TWO_PI / (double) n;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable[offw + k1 + 1 + fourn];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtable[offw + i - 1 + twon] = 1;
- wtable[offw + i + twon] = 0;
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + twon;
- wtable[offw + idx - 1] = Math.cos(arg);
- wtable[offw + idx] = Math.sin(arg);
- }
- if (ipll > 5) {
- int idx1 = i1 + twon;
- int idx2 = i + twon;
- wtable[offw + idx1 - 1] = wtable[offw + idx2 - 1];
- wtable[offw + idx1] = wtable[offw + idx2];
- }
- }
- l1 = l2;
- }
-
- }
-
- final void cffti() {
- if (n == 1) {
- return;
- }
-
- final int twon = 2 * n;
- final int fourn = 4 * n;
- double argh;
- int idot, ntry = 0, i, j;
- double argld;
- int i1, k1, l1, l2, ib;
- double fi;
- int ld, ii, nf, ipll, nll, nq, nr;
- double arg;
- int ido, ipm;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtable[nf + 1 + fourn] = ntry;
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + fourn;
- wtable[idx + 1] = wtable[idx];
- }
- wtable[2 + fourn] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable[fourn] = n;
- wtable[1 + fourn] = nf;
- argh = TWO_PI / (double) n;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable[k1 + 1 + fourn];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtable[i - 1 + twon] = 1;
- wtable[i + twon] = 0;
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + twon;
- wtable[idx - 1] = Math.cos(arg);
- wtable[idx] = Math.sin(arg);
- }
- if (ipll > 5) {
- int idx1 = i1 + twon;
- int idx2 = i + twon;
- wtable[idx1 - 1] = wtable[idx2 - 1];
- wtable[idx1] = wtable[idx2];
- }
- }
- l1 = l2;
- }
-
- }
-
- final void cfftil() {
- if (nl == 1) {
- return;
- }
-
- final long twon = 2 * nl;
- final long fourn = 4 * nl;
- double argh;
- long idot, ntry = 0, i, j;
- double argld;
- long i1, k1, l1, l2, ib;
- double fi;
- long ld, ii, nf, ipll, nl2, nq, nr;
- double arg;
- long ido, ipm;
-
- nl2 = nl;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- j++;
- if (j <= 4) {
- ntry = factors[(int) (j - 1)];
- } else {
- ntry += 2;
- }
- do {
- nq = nl2 / ntry;
- nr = nl2 - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- nf++;
- wtablel.setDouble(nf + 1 + fourn, ntry);
- nl2 = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- long idx = ib + fourn;
- wtablel.setDouble(idx + 1, wtablel.getDouble(idx));
- }
- wtablel.setDouble(2 + fourn, 2);
- }
- } while (nl2 != 1);
- break;
- }
- wtablel.setDouble(fourn, nl);
- wtablel.setDouble(1 + fourn, nf);
- argh = TWO_PI / (double) nl;
- i = 1;
- l1 = 1;
- for (k1 = 1; k1 <= nf; k1++) {
- ipll = (long) wtablel.getDouble(k1 + 1 + fourn);
- ld = 0;
- l2 = l1 * ipll;
- ido = nl / l2;
- idot = ido + ido + 2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; j++) {
- i1 = i;
- wtablel.setDouble(i - 1 + twon, 1);
- wtablel.setDouble(i + twon, 0);
- ld += l1;
- fi = 0;
- argld = ld * argh;
- for (ii = 4; ii <= idot; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- long idx = i + twon;
- wtablel.setDouble(idx - 1, Math.cos(arg));
- wtablel.setDouble(idx, Math.sin(arg));
- }
- if (ipll > 5) {
- long idx1 = i1 + twon;
- long idx2 = i + twon;
- wtablel.setDouble(idx1 - 1, wtablel.getDouble(idx2 - 1));
- wtablel.setDouble(idx1, wtablel.getDouble(idx2));
- }
- }
- l1 = l2;
- }
-
- }
-
- void rffti() {
-
- if (n == 1) {
- return;
- }
- final int twon = 2 * n;
- double argh;
- int ntry = 0, i, j;
- double argld;
- int k1, l1, l2, ib;
- double fi;
- int ld, ii, nf, ipll, nll, is, nq, nr;
- double arg;
- int ido, ipm;
- int nfm1;
-
- nll = n;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- ++j;
- if (j <= 4) {
- ntry = factors[j - 1];
- } else {
- ntry += 2;
- }
- do {
- nq = nll / ntry;
- nr = nll - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- ++nf;
- wtable_r[nf + 1 + twon] = ntry;
-
- nll = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- int idx = ib + twon;
- wtable_r[idx + 1] = wtable_r[idx];
- }
- wtable_r[2 + twon] = 2;
- }
- } while (nll != 1);
- break;
- }
- wtable_r[twon] = n;
- wtable_r[1 + twon] = nf;
- argh = TWO_PI / (double) (n);
- is = 0;
- nfm1 = nf - 1;
- l1 = 1;
- if (nfm1 == 0) {
- return;
- }
- for (k1 = 1; k1 <= nfm1; k1++) {
- ipll = (int) wtable_r[k1 + 1 + twon];
- ld = 0;
- l2 = l1 * ipll;
- ido = n / l2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; ++j) {
- ld += l1;
- i = is;
- argld = (double) ld * argh;
-
- fi = 0;
- for (ii = 3; ii <= ido; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- int idx = i + n;
- wtable_r[idx - 2] = Math.cos(arg);
- wtable_r[idx - 1] = Math.sin(arg);
- }
- is += ido;
- }
- l1 = l2;
- }
- }
-
- void rfftil() {
-
- if (nl == 1) {
- return;
- }
- final long twon = 2 * nl;
- double argh;
- long ntry = 0, i, j;
- double argld;
- long k1, l1, l2, ib;
- double fi;
- long ld, ii, nf, ipll, nl2, is, nq, nr;
- double arg;
- long ido, ipm;
- long nfm1;
-
- nl2 = nl;
- nf = 0;
- j = 0;
-
- factorize_loop:
- while (true) {
- ++j;
- if (j <= 4) {
- ntry = factors[(int) (j - 1)];
- } else {
- ntry += 2;
- }
- do {
- nq = nl2 / ntry;
- nr = nl2 - ntry * nq;
- if (nr != 0) {
- continue factorize_loop;
- }
- ++nf;
- wtable_rl.setDouble(nf + 1 + twon, ntry);
-
- nl2 = nq;
- if (ntry == 2 && nf != 1) {
- for (i = 2; i <= nf; i++) {
- ib = nf - i + 2;
- long idx = ib + twon;
- wtable_rl.setDouble(idx + 1, wtable_rl.getDouble(idx));
- }
- wtable_rl.setDouble(2 + twon, 2);
- }
- } while (nl2 != 1);
- break;
- }
- wtable_rl.setDouble(twon, nl);
- wtable_rl.setDouble(1 + twon, nf);
- argh = TWO_PI / (double) (nl);
- is = 0;
- nfm1 = nf - 1;
- l1 = 1;
- if (nfm1 == 0) {
- return;
- }
- for (k1 = 1; k1 <= nfm1; k1++) {
- ipll = (long) wtable_rl.getDouble(k1 + 1 + twon);
- ld = 0;
- l2 = l1 * ipll;
- ido = nl / l2;
- ipm = ipll - 1;
- for (j = 1; j <= ipm; ++j) {
- ld += l1;
- i = is;
- argld = (double) ld * argh;
-
- fi = 0;
- for (ii = 3; ii <= ido; ii += 2) {
- i += 2;
- fi += 1;
- arg = fi * argld;
- long idx = i + nl;
- wtable_rl.setDouble(idx - 2, Math.cos(arg));
- wtable_rl.setDouble(idx - 1, Math.sin(arg));
- }
- is += ido;
- }
- l1 = l2;
- }
- }
-
- private void bluesteini() {
- int k = 0;
- double arg;
- double pi_n = PI / n;
- bk1[0] = 1;
- bk1[1] = 0;
- for (int i = 1; i < n; i++) {
- k += 2 * i - 1;
- if (k >= 2 * n) {
- k -= 2 * n;
- }
- arg = pi_n * k;
- bk1[2 * i] = Math.cos(arg);
- bk1[2 * i + 1] = Math.sin(arg);
- }
- double scale = 1.0 / nBluestein;
- bk2[0] = bk1[0] * scale;
- bk2[1] = bk1[1] * scale;
- for (int i = 2; i < 2 * n; i += 2) {
- bk2[i] = bk1[i] * scale;
- bk2[i + 1] = bk1[i + 1] * scale;
- bk2[2 * nBluestein - i] = bk2[i];
- bk2[2 * nBluestein - i + 1] = bk2[i + 1];
- }
- CommonUtils.cftbsub(2 * nBluestein, bk2, 0, ip, nw, w);
- }
-
- private void bluesteinil() {
- long k = 0;
- double arg;
- double pi_n = PI / nl;
- bk1l.setDouble(0, 1);
- bk1l.setDouble(1, 0);
- for (int i = 1; i < nl; i++) {
- k += 2 * i - 1;
- if (k >= 2 * nl) {
- k -= 2 * nl;
- }
- arg = pi_n * k;
- bk1l.setDouble(2 * i, Math.cos(arg));
- bk1l.setDouble(2 * i + 1, Math.sin(arg));
- }
- double scale = 1.0 / nBluesteinl;
- bk2l.setDouble(0, bk1l.getDouble(0) * scale);
- bk2l.setDouble(1, bk1l.getDouble(1) * scale);
- for (int i = 2; i < 2 * nl; i += 2) {
- bk2l.setDouble(i, bk1l.getDouble(i) * scale);
- bk2l.setDouble(i + 1, bk1l.getDouble(i + 1) * scale);
- bk2l.setDouble(2 * nBluesteinl - i, bk2l.getDouble(i));
- bk2l.setDouble(2 * nBluesteinl - i + 1, bk2l.getDouble(i + 1));
- }
- CommonUtils.cftbsub(2 * nBluesteinl, bk2l, 0, ipl, nwl, wl);
- }
-
- private void bluestein_complex(final double[] a, final int offa, final int isign) {
- final double[] ak = new double[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = -a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[idx4] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- a[idx3] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[idx4] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- }
-
- private void bluestein_complex(final DoubleLargeArray a, final long offa, final int isign) {
- final DoubleLargeArray ak = new DoubleLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) - a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) + a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setDouble(idx3, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(idx4, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setDouble(idx3, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(idx4, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) - a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) + a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- } else {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setDouble(idx3, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(idx4, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- a.setDouble(idx3, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(idx4, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- }
- }
- }
-
- private void bluestein_real_full(final double[] a, final int offa, final int isign) {
- final double[] ak = new double[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- } else {
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (isign > 0) {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- }
- }
- }
-
- private void bluestein_real_full(final DoubleLargeArray a, final long offa, final long isign) {
- final DoubleLargeArray ak = new DoubleLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- if (isign > 0) {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- } else {
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (isign > 0) {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- }
- }
- }
-
- private void bluestein_real_forward(final double[] a, final int offa) {
- final double[] ak = new double[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = -a[idx3] * bk1[idx2];
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] - ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (n % 2 == 0) {
- a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n] + bk1[n + 1] * ak[n + 1];
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- a[offa] = bk1[0] * ak[0] + bk1[1] * ak[1];
- a[offa + 1] = -bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] + bk1[idx2] * ak[idx2];
- a[offa + idx2] = -bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- a[offa + n - 1] = bk1[n - 1] * ak[n - 1] + bk1[n] * ak[n];
- }
-
- }
-
- private void bluestein_real_forward(final DoubleLargeArray a, final long offa) {
- final DoubleLargeArray ak = new DoubleLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, -a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) - ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (nl % 2 == 0) {
- a.setDouble(offa, bk1l.getDouble(0) * ak.getDouble(0) + bk1l.getDouble(1) * ak.getDouble(1));
- a.setDouble(offa + 1, bk1l.getDouble(nl) * ak.getDouble(nl) + bk1l.getDouble(nl + 1) * ak.getDouble(nl + 1));
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- a.setDouble(offa, bk1l.getDouble(0) * ak.getDouble(0) + bk1l.getDouble(1) * ak.getDouble(1));
- a.setDouble(offa + 1, -bk1l.getDouble(nl) * ak.getDouble(nl - 1) + bk1l.getDouble(nl - 1) * ak.getDouble(nl));
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) + bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, -bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- a.setDouble(offa + nl - 1, bk1l.getDouble(nl - 1) * ak.getDouble(nl - 1) + bk1l.getDouble(nl) * ak.getDouble(nl));
- }
-
- }
-
- private void bluestein_real_inverse(final double[] a, final int offa) {
- final double[] ak = new double[2 * nBluestein];
- if (n % 2 == 0) {
- ak[0] = a[offa] * bk1[0];
- ak[1] = a[offa] * bk1[1];
-
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
-
- ak[n] = a[offa + 1] * bk1[n];
- ak[n + 1] = a[offa + 1] * bk1[n + 1];
-
- for (int i = n / 2 + 1; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + 2 * n - idx1;
- int idx4 = idx3 + 1;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
- }
-
- } else {
- ak[0] = a[offa] * bk1[0];
- ak[1] = a[offa] * bk1[1];
-
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + idx1;
- int idx4 = offa + idx2;
- ak[idx1] = a[idx3] * bk1[idx1] - a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] + a[idx4] * bk1[idx1];
- }
-
- ak[n - 1] = a[offa + n - 1] * bk1[n - 1] - a[offa + 1] * bk1[n];
- ak[n] = a[offa + n - 1] * bk1[n] + a[offa + 1] * bk1[n - 1];
-
- ak[n + 1] = a[offa + n - 1] * bk1[n + 1] + a[offa + 1] * bk1[n + 2];
- ak[n + 2] = a[offa + n - 1] * bk1[n + 2] - a[offa + 1] * bk1[n + 1];
-
- for (int i = (n - 1) / 2 + 2; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + 2 * n - idx1;
- int idx4 = idx3 + 1;
- ak[idx1] = a[idx3] * bk1[idx1] + a[idx4] * bk1[idx2];
- ak[idx2] = a[idx3] * bk1[idx2] - a[idx4] * bk1[idx1];
- }
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + i] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- }
- }
- }
-
- private void bluestein_real_inverse(final DoubleLargeArray a, final long offa) {
- final DoubleLargeArray ak = new DoubleLargeArray(2 * nBluesteinl, false);
- if (nl % 2 == 0) {
- ak.setDouble(0, a.getDouble(offa) * bk1l.getDouble(0));
- ak.setDouble(1, a.getDouble(offa) * bk1l.getDouble(1));
-
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) - a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
-
- ak.setDouble(nl, a.getDouble(offa + 1) * bk1l.getDouble(nl));
- ak.setDouble(nl + 1, a.getDouble(offa + 1) * bk1l.getDouble(nl + 1));
-
- for (long i = nl / 2 + 1; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + 2 * nl - idx1;
- long idx4 = idx3 + 1;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) + a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) - a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
-
- } else {
- ak.setDouble(0, a.getDouble(offa) * bk1l.getDouble(0));
- ak.setDouble(1, a.getDouble(offa) * bk1l.getDouble(1));
-
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + idx1;
- long idx4 = offa + idx2;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) - a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) + a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
-
- ak.setDouble(nl - 1, a.getDouble(offa + nl - 1) * bk1l.getDouble(nl - 1) - a.getDouble(offa + 1) * bk1l.getDouble(nl));
- ak.setDouble(nl, a.getDouble(offa + nl - 1) * bk1l.getDouble(nl) + a.getDouble(offa + 1) * bk1l.getDouble(nl - 1));
-
- ak.setDouble(nl + 1, a.getDouble(offa + nl - 1) * bk1l.getDouble(nl + 1) + a.getDouble(offa + 1) * bk1l.getDouble(nl + 2));
- ak.setDouble(nl + 2, a.getDouble(offa + nl - 1) * bk1l.getDouble(nl + 2) - a.getDouble(offa + 1) * bk1l.getDouble(nl + 1));
-
- for (long i = (nl - 1) / 2 + 2; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + 2 * nl - idx1;
- long idx4 = idx3 + 1;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1) + a.getDouble(idx4) * bk1l.getDouble(idx2));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2) - a.getDouble(idx4) * bk1l.getDouble(idx1));
- }
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + i, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + i, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- }
- }
- }
-
- private void bluestein_real_inverse2(final double[] a, final int offa) {
- final double[] ak = new double[2 * nBluestein];
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (n >= ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- int k = n / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? n : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- k = nBluestein / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int firstIdx = i * k;
- final int lastIdx = (i == (nthreads - 1)) ? nBluestein : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (int i = firstIdx; i < lastIdx; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int i = 0; i < n; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- int idx3 = offa + i;
- ak[idx1] = a[idx3] * bk1[idx1];
- ak[idx2] = a[idx3] * bk1[idx2];
- }
-
- CommonUtils.cftbsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- for (int i = 0; i < nBluestein; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- double im = -ak[idx1] * bk2[idx2] + ak[idx2] * bk2[idx1];
- ak[idx1] = ak[idx1] * bk2[idx1] + ak[idx2] * bk2[idx2];
- ak[idx2] = im;
- }
- }
-
- CommonUtils.cftfsub(2 * nBluestein, ak, 0, ip, nw, w);
-
- if (n % 2 == 0) {
- a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n] - bk1[n + 1] * ak[n + 1];
- for (int i = 1; i < n / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- } else {
- a[offa] = bk1[0] * ak[0] - bk1[1] * ak[1];
- a[offa + 1] = bk1[n] * ak[n - 1] + bk1[n - 1] * ak[n];
- for (int i = 1; i < (n - 1) / 2; i++) {
- int idx1 = 2 * i;
- int idx2 = idx1 + 1;
- a[offa + idx1] = bk1[idx1] * ak[idx1] - bk1[idx2] * ak[idx2];
- a[offa + idx2] = bk1[idx2] * ak[idx1] + bk1[idx1] * ak[idx2];
- }
- a[offa + n - 1] = bk1[n - 1] * ak[n - 1] - bk1[n] * ak[n];
- }
- }
-
- private void bluestein_real_inverse2(final DoubleLargeArray a, final long offa) {
- final DoubleLargeArray ak = new DoubleLargeArray(2 * nBluesteinl, false);
- int threads = ConcurrencyUtils.getNumberOfThreads();
- if ((threads > 1) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_2Threads())) {
- int nthreads = 2;
- if ((threads >= 4) && (nl > ConcurrencyUtils.getThreadsBeginN_1D_FFT_4Threads())) {
- nthreads = 4;
- }
- Future>[] futures = new Future[nthreads];
- long k = nl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- k = nBluesteinl / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final long firstIdx = i * k;
- final long lastIdx = (i == (nthreads - 1)) ? nBluesteinl : firstIdx + k;
- futures[i] = ConcurrencyUtils.submit(new Runnable() {
- public void run() {
- for (long i = firstIdx; i < lastIdx; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long i = 0; i < nl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- long idx3 = offa + i;
- ak.setDouble(idx1, a.getDouble(idx3) * bk1l.getDouble(idx1));
- ak.setDouble(idx2, a.getDouble(idx3) * bk1l.getDouble(idx2));
- }
-
- CommonUtils.cftbsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- for (long i = 0; i < nBluesteinl; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- double im = -ak.getDouble(idx1) * bk2l.getDouble(idx2) + ak.getDouble(idx2) * bk2l.getDouble(idx1);
- ak.setDouble(idx1, ak.getDouble(idx1) * bk2l.getDouble(idx1) + ak.getDouble(idx2) * bk2l.getDouble(idx2));
- ak.setDouble(idx2, im);
- }
- }
-
- CommonUtils.cftfsub(2 * nBluesteinl, ak, 0, ipl, nwl, wl);
-
- if (nl % 2 == 0) {
- a.setDouble(offa, bk1l.getDouble(0) * ak.getDouble(0) - bk1l.getDouble(1) * ak.getDouble(1));
- a.setDouble(offa + 1, bk1l.getDouble(nl) * ak.getDouble(nl) - bk1l.getDouble(nl + 1) * ak.getDouble(nl + 1));
- for (long i = 1; i < nl / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- } else {
- a.setDouble(offa, bk1l.getDouble(0) * ak.getDouble(0) - bk1l.getDouble(1) * ak.getDouble(1));
- a.setDouble(offa + 1, bk1l.getDouble(nl) * ak.getDouble(nl - 1) + bk1l.getDouble(nl - 1) * ak.getDouble(nl));
- for (long i = 1; i < (nl - 1) / 2; i++) {
- long idx1 = 2 * i;
- long idx2 = idx1 + 1;
- a.setDouble(offa + idx1, bk1l.getDouble(idx1) * ak.getDouble(idx1) - bk1l.getDouble(idx2) * ak.getDouble(idx2));
- a.setDouble(offa + idx2, bk1l.getDouble(idx2) * ak.getDouble(idx1) + bk1l.getDouble(idx1) * ak.getDouble(idx2));
- }
- a.setDouble(offa + nl - 1, bk1l.getDouble(nl - 1) * ak.getDouble(nl - 1) - bk1l.getDouble(nl) * ak.getDouble(nl));
- }
- }
-
- /*---------------------------------------------------------
- rfftf1: further processing of Real forward FFT
- --------------------------------------------------------*/
- void rfftf(final double a[], final int offa) {
- if (n == 1) {
- return;
- }
- int l1, l2, na, kh, nf, ipll, iw, ido, idl1;
-
- final double[] ch = new double[n];
- final int twon = 2 * n;
- nf = (int) wtable_r[1 + twon];
- na = 1;
- l2 = n;
- iw = twon - 1;
- for (int k1 = 1; k1 <= nf; ++k1) {
- kh = nf - k1;
- ipll = (int) wtable_r[kh + 2 + twon];
- l1 = l2 / ipll;
- ido = n / l2;
- idl1 = ido * l1;
- iw -= (ipll - 1) * ido;
- na = 1 - na;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radf2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf2(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 3:
- if (na == 0) {
- radf3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf3(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 4:
- if (na == 0) {
- radf4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf4(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 5:
- if (na == 0) {
- radf5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf5(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- default:
- if (ido == 1) {
- na = 1 - na;
- }
- if (na == 0) {
- radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- na = 1;
- } else {
- radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- na = 0;
- }
- break;
- }
- l2 = l1;
- }
- if (na == 1) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, n);
- }
-
- /*---------------------------------------------------------
- rfftf1: further processing of Real forward FFT
- --------------------------------------------------------*/
- void rfftf(final DoubleLargeArray a, final long offa) {
- if (nl == 1) {
- return;
- }
- long l1, l2, na, kh, nf, iw, ido, idl1;
- int ipll;
-
- final DoubleLargeArray ch = new DoubleLargeArray(nl, false);
- final long twon = 2 * nl;
- nf = (long) wtable_rl.getDouble(1 + twon);
- na = 1;
- l2 = nl;
- iw = twon - 1;
- for (long k1 = 1; k1 <= nf; ++k1) {
- kh = nf - k1;
- ipll = (int) wtable_rl.getDouble(kh + 2 + twon);
- l1 = l2 / ipll;
- ido = nl / l2;
- idl1 = ido * l1;
- iw -= (ipll - 1) * ido;
- na = 1 - na;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radf2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf2(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 3:
- if (na == 0) {
- radf3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf3(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 4:
- if (na == 0) {
- radf4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf4(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- case 5:
- if (na == 0) {
- radf5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radf5(ido, l1, ch, 0, a, offa, iw);
- }
- break;
- default:
- if (ido == 1) {
- na = 1 - na;
- }
- if (na == 0) {
- radfg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- na = 1;
- } else {
- radfg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- na = 0;
- }
- break;
- }
- l2 = l1;
- }
- if (na == 1) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, nl);
- }
-
- /*---------------------------------------------------------
- rfftb1: further processing of Real backward FFT
- --------------------------------------------------------*/
- void rfftb(final double a[], final int offa) {
- if (n == 1) {
- return;
- }
- int l1, l2, na, nf, ipll, iw, ido, idl1;
-
- double[] ch = new double[n];
- final int twon = 2 * n;
- nf = (int) wtable_r[1 + twon];
- na = 0;
- l1 = 1;
- iw = n;
- for (int k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable_r[k1 + 1 + twon];
- l2 = ipll * l1;
- ido = n / l2;
- idl1 = ido * l1;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radb2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb2(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- radb3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb3(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 4:
- if (na == 0) {
- radb4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb4(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- radb5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb5(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- } else {
- radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- }
- if (ido == 1) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * ido;
- }
- if (na == 0) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, n);
- }
-
- /*---------------------------------------------------------
- rfftb1: further processing of Real backward FFT
- --------------------------------------------------------*/
- void rfftb(final DoubleLargeArray a, final long offa) {
- if (nl == 1) {
- return;
- }
- long l1, l2, na, nf, iw, ido, idl1;
- int ipll;
- DoubleLargeArray ch = new DoubleLargeArray(nl, false);
- final long twon = 2 * nl;
- nf = (long) wtable_rl.getDouble(1 + twon);
- na = 0;
- l1 = 1;
- iw = nl;
- for (long k1 = 1; k1 <= nf; k1++) {
- ipll = (int) wtable_rl.getDouble(k1 + 1 + twon);
- l2 = ipll * l1;
- ido = nl / l2;
- idl1 = ido * l1;
- switch (ipll) {
- case 2:
- if (na == 0) {
- radb2(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb2(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- radb3(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb3(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 4:
- if (na == 0) {
- radb4(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb4(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- radb5(ido, l1, a, offa, ch, 0, iw);
- } else {
- radb5(ido, l1, ch, 0, a, offa, iw);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- radbg(ido, ipll, l1, idl1, a, offa, ch, 0, iw);
- } else {
- radbg(ido, ipll, l1, idl1, ch, 0, a, offa, iw);
- }
- if (ido == 1) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * ido;
- }
- if (na == 0) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, nl);
- }
-
- /*-------------------------------------------------
- radf2: Real FFT's forward processing of factor 2
- -------------------------------------------------*/
- void radf2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- int i, ic, idx0, idx1, idx2, idx3, idx4;
- double t1i, t1r, w1r, w1i;
- int iw1;
- iw1 = offset;
- idx0 = l1 * ido;
- idx1 = 2 * ido;
- for (int k = 0; k < l1; k++) {
- int oidx1 = out_off + k * idx1;
- int oidx2 = oidx1 + idx1 - 1;
- int iidx1 = in_off + k * ido;
- int iidx2 = iidx1 + idx0;
-
- double i1r = in[iidx1];
- double i2r = in[iidx2];
-
- out[oidx1] = i1r + i2r;
- out[oidx2] = i1r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; k++) {
- idx1 = k * ido;
- idx2 = 2 * idx1;
- idx3 = idx2 + ido;
- idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int oidx1 = out_off + i + idx2;
- int oidx2 = out_off + ic + idx3;
- int iidx1 = in_off + i + idx1;
- int iidx2 = in_off + i + idx4;
-
- double a1i = in[iidx1 - 1];
- double a1r = in[iidx1];
- double a2i = in[iidx2 - 1];
- double a2r = in[iidx2];
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
-
- t1r = w1r * a2i + w1i * a2r;
- t1i = w1r * a2r - w1i * a2i;
-
- out[oidx1] = a1r + t1i;
- out[oidx1 - 1] = a1i + t1r;
-
- out[oidx2] = t1i - a1r;
- out[oidx2 - 1] = a1i - t1r;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- idx2 = 2 * idx1;
- for (int k = 0; k < l1; k++) {
- idx1 = k * ido;
- int oidx1 = out_off + idx2 + ido;
- int iidx1 = in_off + ido - 1 + idx1;
-
- out[oidx1] = -in[iidx1 + idx0];
- out[oidx1 - 1] = in[iidx1];
- }
- }
-
- /*-------------------------------------------------
- radf2: Real FFT's forward processing of factor 2
- -------------------------------------------------*/
- void radf2(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- long i, ic, idx0, idx1, idx2, idx3, idx4;
- double t1i, t1r, w1r, w1i;
- long iw1;
- iw1 = offset;
- idx0 = l1 * ido;
- idx1 = 2 * ido;
- for (long k = 0; k < l1; k++) {
- long oidx1 = out_off + k * idx1;
- long oidx2 = oidx1 + idx1 - 1;
- long iidx1 = in_off + k * ido;
- long iidx2 = iidx1 + idx0;
-
- double i1r = in.getDouble(iidx1);
- double i2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1, i1r + i2r);
- out.setDouble(oidx2, i1r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; k++) {
- idx1 = k * ido;
- idx2 = 2 * idx1;
- idx3 = idx2 + ido;
- idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long oidx1 = out_off + i + idx2;
- long oidx2 = out_off + ic + idx3;
- long iidx1 = in_off + i + idx1;
- long iidx2 = in_off + i + idx4;
-
- double a1i = in.getDouble(iidx1 - 1);
- double a1r = in.getDouble(iidx1);
- double a2i = in.getDouble(iidx2 - 1);
- double a2r = in.getDouble(iidx2);
-
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
-
- t1r = w1r * a2i + w1i * a2r;
- t1i = w1r * a2r - w1i * a2i;
-
- out.setDouble(oidx1, a1r + t1i);
- out.setDouble(oidx1 - 1, a1i + t1r);
-
- out.setDouble(oidx2, t1i - a1r);
- out.setDouble(oidx2 - 1, a1i - t1r);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- idx2 = 2 * idx1;
- for (long k = 0; k < l1; k++) {
- idx1 = k * ido;
- long oidx1 = out_off + idx2 + ido;
- long iidx1 = in_off + ido - 1 + idx1;
-
- out.setDouble(oidx1, -in.getDouble(iidx1 + idx0));
- out.setDouble(oidx1 - 1, in.getDouble(iidx1));
- }
- }
-
- /*-------------------------------------------------
- radb2: Real FFT's backward processing of factor 2
- -------------------------------------------------*/
- void radb2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- int i, ic;
- double t1i, t1r, w1r, w1i;
- int iw1 = offset;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int idx3 = idx2 + ido;
- int oidx1 = out_off + idx1;
- int iidx1 = in_off + idx2;
- int iidx2 = in_off + ido - 1 + idx3;
- double i1r = in[iidx1];
- double i2r = in[iidx2];
- out[oidx1] = i1r + i2r;
- out[oidx1 + idx0] = i1r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx5 = i - 1 + iw1;
- int idx6 = out_off + i;
- int idx7 = in_off + i;
- int idx8 = in_off + ic;
- w1r = wtable_r[idx5 - 1];
- w1i = wtable_r[idx5];
- int iidx1 = idx7 + idx2;
- int iidx2 = idx8 + idx3;
- int oidx1 = idx6 + idx1;
- int oidx2 = idx6 + idx4;
- t1r = in[iidx1 - 1] - in[iidx2 - 1];
- t1i = in[iidx1] + in[iidx2];
- double i1i = in[iidx1];
- double i1r = in[iidx1 - 1];
- double i2i = in[iidx2];
- double i2r = in[iidx2 - 1];
-
- out[oidx1 - 1] = i1r + i2r;
- out[oidx1] = i1i - i2i;
- out[oidx2 - 1] = w1r * t1r - w1i * t1i;
- out[oidx2] = w1r * t1i + w1i * t1r;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 2 * idx1;
- int oidx1 = out_off + ido - 1 + idx1;
- int iidx1 = in_off + idx2 + ido;
- out[oidx1] = 2 * in[iidx1 - 1];
- out[oidx1 + idx0] = -2 * in[iidx1];
- }
- }
-
- /*-------------------------------------------------
- radb2: Real FFT's backward processing of factor 2
- -------------------------------------------------*/
- void radb2(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- long i, ic;
- double t1i, t1r, w1r, w1i;
- long iw1 = offset;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long idx3 = idx2 + ido;
- long oidx1 = out_off + idx1;
- long iidx1 = in_off + idx2;
- long iidx2 = in_off + ido - 1 + idx3;
- double i1r = in.getDouble(iidx1);
- double i2r = in.getDouble(iidx2);
- out.setDouble(oidx1, i1r + i2r);
- out.setDouble(oidx1 + idx0, i1r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx1 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx5 = i - 1 + iw1;
- long idx6 = out_off + i;
- long idx7 = in_off + i;
- long idx8 = in_off + ic;
- w1r = wtable_rl.getDouble(idx5 - 1);
- w1i = wtable_rl.getDouble(idx5);
- long iidx1 = idx7 + idx2;
- long iidx2 = idx8 + idx3;
- long oidx1 = idx6 + idx1;
- long oidx2 = idx6 + idx4;
- t1r = in.getDouble(iidx1 - 1) - in.getDouble(iidx2 - 1);
- t1i = in.getDouble(iidx1) + in.getDouble(iidx2);
- double i1i = in.getDouble(iidx1);
- double i1r = in.getDouble(iidx1 - 1);
- double i2i = in.getDouble(iidx2);
- double i2r = in.getDouble(iidx2 - 1);
-
- out.setDouble(oidx1 - 1, i1r + i2r);
- out.setDouble(oidx1, i1i - i2i);
- out.setDouble(oidx2 - 1, w1r * t1r - w1i * t1i);
- out.setDouble(oidx2, w1r * t1i + w1i * t1r);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 2 * idx1;
- long oidx1 = out_off + ido - 1 + idx1;
- long iidx1 = in_off + idx2 + ido;
- out.setDouble(oidx1, 2 * in.getDouble(iidx1 - 1));
- out.setDouble(oidx1 + idx0, -2 * in.getDouble(iidx1));
- }
- }
-
- /*-------------------------------------------------
- radf3: Real FFT's forward processing of factor 3
- -------------------------------------------------*/
- void radf3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- int i, ic;
- double ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
- int iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx3 = 2 * idx0;
- int idx4 = (3 * k + 1) * ido;
- int iidx1 = in_off + idx1;
- int iidx2 = iidx1 + idx0;
- int iidx3 = iidx1 + idx3;
- double i1r = in[iidx1];
- double i2r = in[iidx2];
- double i3r = in[iidx3];
- cr2 = i2r + i3r;
- out[out_off + 3 * idx1] = i1r + cr2;
- out[out_off + idx4 + ido] = taui * (i3r - i2r);
- out[out_off + ido - 1 + idx4] = i1r + taur * cr2;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int idx4 = 3 * idx3;
- int idx5 = idx3 + idx0;
- int idx6 = idx5 + idx0;
- int idx7 = idx4 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
-
- int idx9 = in_off + i;
- int idx10 = out_off + i;
- int idx11 = out_off + ic;
- int iidx1 = idx9 + idx3;
- int iidx2 = idx9 + idx5;
- int iidx3 = idx9 + idx6;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- cr2 = dr2 + dr3;
- ci2 = di2 + di3;
- tr2 = i1i + taur * cr2;
- ti2 = i1r + taur * ci2;
- tr3 = taui * (di2 - di3);
- ti3 = taui * (dr3 - dr2);
-
- int oidx1 = idx10 + idx4;
- int oidx2 = idx11 + idx7;
- int oidx3 = idx10 + idx8;
-
- out[oidx1 - 1] = i1i + cr2;
- out[oidx1] = i1r + ci2;
- out[oidx2 - 1] = tr2 - tr3;
- out[oidx2] = ti3 - ti2;
- out[oidx3 - 1] = tr2 + tr3;
- out[oidx3] = ti2 + ti3;
- }
- }
- }
-
- /*-------------------------------------------------
- radf3: Real FFT's forward processing of factor 3
- -------------------------------------------------*/
- void radf3(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- long i, ic;
- double ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3, w1r, w2r, w1i, w2i;
- long iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx3 = 2 * idx0;
- long idx4 = (3 * k + 1) * ido;
- long iidx1 = in_off + idx1;
- long iidx2 = iidx1 + idx0;
- long iidx3 = iidx1 + idx3;
- double i1r = in.getDouble(iidx1);
- double i2r = in.getDouble(iidx2);
- double i3r = in.getDouble(iidx3);
- cr2 = i2r + i3r;
- out.setDouble(out_off + 3 * idx1, i1r + cr2);
- out.setDouble(out_off + idx4 + ido, taui * (i3r - i2r));
- out.setDouble(out_off + ido - 1 + idx4, i1r + taur * cr2);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long idx4 = 3 * idx3;
- long idx5 = idx3 + idx0;
- long idx6 = idx5 + idx0;
- long idx7 = idx4 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
-
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
-
- long idx9 = in_off + i;
- long idx10 = out_off + i;
- long idx11 = out_off + ic;
- long iidx1 = idx9 + idx3;
- long iidx2 = idx9 + idx5;
- long iidx3 = idx9 + idx6;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- cr2 = dr2 + dr3;
- ci2 = di2 + di3;
- tr2 = i1i + taur * cr2;
- ti2 = i1r + taur * ci2;
- tr3 = taui * (di2 - di3);
- ti3 = taui * (dr3 - dr2);
-
- long oidx1 = idx10 + idx4;
- long oidx2 = idx11 + idx7;
- long oidx3 = idx10 + idx8;
-
- out.setDouble(oidx1 - 1, i1i + cr2);
- out.setDouble(oidx1, i1r + ci2);
- out.setDouble(oidx2 - 1, tr2 - tr3);
- out.setDouble(oidx2, ti3 - ti2);
- out.setDouble(oidx3 - 1, tr2 + tr3);
- out.setDouble(oidx3, ti2 + ti3);
- }
- }
- }
-
- /*-------------------------------------------------
- radb3: Real FFT's backward processing of factor 3
- -------------------------------------------------*/
- void radb3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- int i, ic;
- double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
- int iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int iidx1 = in_off + 3 * idx1;
- int iidx2 = iidx1 + 2 * ido;
- double i1i = in[iidx1];
-
- tr2 = 2 * in[iidx2 - 1];
- cr2 = i1i + taur * tr2;
- ci3 = 2 * taui * in[iidx2];
-
- out[out_off + idx1] = i1i + tr2;
- out[out_off + (k + l1) * ido] = cr2 - ci3;
- out[out_off + (k + 2 * l1) * ido] = cr2 + ci3;
- }
- if (ido == 1) {
- return;
- }
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 3 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx1 + idx0;
- int idx6 = idx5 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = in_off + i;
- int idx8 = in_off + ic;
- int idx9 = out_off + i;
- int iidx1 = idx7 + idx2;
- int iidx2 = idx7 + idx4;
- int iidx3 = idx8 + idx3;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
-
- tr2 = i2i + i3i;
- cr2 = i1i + taur * tr2;
- ti2 = i2r - i3r;
- ci2 = i1r + taur * ti2;
- cr3 = taui * (i2i - i3i);
- ci3 = taui * (i2r + i3r);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
-
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
-
- int oidx1 = idx9 + idx1;
- int oidx2 = idx9 + idx5;
- int oidx3 = idx9 + idx6;
-
- out[oidx1 - 1] = i1i + tr2;
- out[oidx1] = i1r + ti2;
- out[oidx2 - 1] = w1r * dr2 - w1i * di2;
- out[oidx2] = w1r * di2 + w1i * dr2;
- out[oidx3 - 1] = w2r * dr3 - w2i * di3;
- out[oidx3] = w2r * di3 + w2i * dr3;
- }
- }
- }
-
- /*-------------------------------------------------
- radb3: Real FFT's backward processing of factor 3
- -------------------------------------------------*/
- void radb3(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- long i, ic;
- double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2, w1r, w2r, w1i, w2i;
- long iw1, iw2;
- iw1 = offset;
- iw2 = iw1 + ido;
-
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long iidx1 = in_off + 3 * idx1;
- long iidx2 = iidx1 + 2 * ido;
- double i1i = in.getDouble(iidx1);
-
- tr2 = 2 * in.getDouble(iidx2 - 1);
- cr2 = i1i + taur * tr2;
- ci3 = 2 * taui * in.getDouble(iidx2);
-
- out.setDouble(out_off + idx1, i1i + tr2);
- out.setDouble(out_off + (k + l1) * ido, cr2 - ci3);
- out.setDouble(out_off + (k + 2 * l1) * ido, cr2 + ci3);
- }
- if (ido == 1) {
- return;
- }
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 3 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx1 + idx0;
- long idx6 = idx5 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = in_off + i;
- long idx8 = in_off + ic;
- long idx9 = out_off + i;
- long iidx1 = idx7 + idx2;
- long iidx2 = idx7 + idx4;
- long iidx3 = idx8 + idx3;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
-
- tr2 = i2i + i3i;
- cr2 = i1i + taur * tr2;
- ti2 = i2r - i3r;
- ci2 = i1r + taur * ti2;
- cr3 = taui * (i2i - i3i);
- ci3 = taui * (i2r + i3r);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
-
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
-
- long oidx1 = idx9 + idx1;
- long oidx2 = idx9 + idx5;
- long oidx3 = idx9 + idx6;
-
- out.setDouble(oidx1 - 1, i1i + tr2);
- out.setDouble(oidx1, i1r + ti2);
- out.setDouble(oidx2 - 1, w1r * dr2 - w1i * di2);
- out.setDouble(oidx2, w1r * di2 + w1i * dr2);
- out.setDouble(oidx3 - 1, w2r * dr3 - w2i * di3);
- out.setDouble(oidx3, w2r * di3 + w2i * dr3);
- }
- }
- }
-
- /*-------------------------------------------------
- radf4: Real FFT's forward processing of factor 4
- -------------------------------------------------*/
- void radf4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double hsqt2 = 0.707106781186547572737310929369414225;
- int i, ic;
- double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = offset + ido;
- iw3 = iw2 + ido;
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- double i1r = in[in_off + idx1];
- double i2r = in[in_off + idx3];
- double i3r = in[in_off + idx4];
- double i4r = in[in_off + idx5];
-
- tr1 = i2r + i4r;
- tr2 = i1r + i3r;
-
- int oidx1 = out_off + idx2;
- int oidx2 = out_off + idx6 + ido;
-
- out[oidx1] = tr1 + tr2;
- out[oidx2 - 1 + ido + ido] = tr2 - tr1;
- out[oidx2 - 1] = i1r - i3r;
- out[oidx2] = i4r - i2r;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 + idx0;
- int idx3 = idx2 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = 4 * idx1;
- int idx6 = idx5 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
-
- int idx9 = in_off + i;
- int idx10 = out_off + i;
- int idx11 = out_off + ic;
- int iidx1 = idx9 + idx1;
- int iidx2 = idx9 + idx2;
- int iidx3 = idx9 + idx3;
- int iidx4 = idx9 + idx4;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
-
- cr2 = w1r * i2i + w1i * i2r;
- ci2 = w1r * i2r - w1i * i2i;
- cr3 = w2r * i3i + w2i * i3r;
- ci3 = w2r * i3r - w2i * i3i;
- cr4 = w3r * i4i + w3i * i4r;
- ci4 = w3r * i4r - w3i * i4i;
- tr1 = cr2 + cr4;
- tr4 = cr4 - cr2;
- ti1 = ci2 + ci4;
- ti4 = ci2 - ci4;
- ti2 = i1r + ci3;
- ti3 = i1r - ci3;
- tr2 = i1i + cr3;
- tr3 = i1i - cr3;
-
- int oidx1 = idx10 + idx5;
- int oidx2 = idx11 + idx6;
- int oidx3 = idx10 + idx7;
- int oidx4 = idx11 + idx8;
-
- out[oidx1 - 1] = tr1 + tr2;
- out[oidx4 - 1] = tr2 - tr1;
- out[oidx1] = ti1 + ti2;
- out[oidx4] = ti1 - ti2;
- out[oidx3 - 1] = ti4 + tr3;
- out[oidx2 - 1] = tr3 - ti4;
- out[oidx3] = tr4 + ti3;
- out[oidx2] = tr4 - ti3;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- int idx9 = in_off + ido;
- int idx10 = out_off + ido;
-
- double i1i = in[idx9 - 1 + idx1];
- double i2i = in[idx9 - 1 + idx3];
- double i3i = in[idx9 - 1 + idx4];
- double i4i = in[idx9 - 1 + idx5];
-
- ti1 = -hsqt2 * (i2i + i4i);
- tr1 = hsqt2 * (i2i - i4i);
-
- out[idx10 - 1 + idx2] = tr1 + i1i;
- out[idx10 - 1 + idx7] = i1i - tr1;
- out[out_off + idx6] = ti1 - i3i;
- out[out_off + idx8] = ti1 + i3i;
- }
- }
-
- /*-------------------------------------------------
- radf4: Real FFT's forward processing of factor 4
- -------------------------------------------------*/
- void radf4(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double hsqt2 = 0.707106781186547572737310929369414225;
- long i, ic;
- double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = offset + ido;
- iw3 = iw2 + ido;
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- double i1r = in.getDouble(in_off + idx1);
- double i2r = in.getDouble(in_off + idx3);
- double i3r = in.getDouble(in_off + idx4);
- double i4r = in.getDouble(in_off + idx5);
-
- tr1 = i2r + i4r;
- tr2 = i1r + i3r;
-
- long oidx1 = out_off + idx2;
- long oidx2 = out_off + idx6 + ido;
-
- out.setDouble(oidx1, tr1 + tr2);
- out.setDouble(oidx2 - 1 + ido + ido, tr2 - tr1);
- out.setDouble(oidx2 - 1, i1r - i3r);
- out.setDouble(oidx2, i4r - i2r);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 + idx0;
- long idx3 = idx2 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = 4 * idx1;
- long idx6 = idx5 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
- w3r = wtable_rl.getDouble(widx3 - 1);
- w3i = wtable_rl.getDouble(widx3);
-
- long idx9 = in_off + i;
- long idx10 = out_off + i;
- long idx11 = out_off + ic;
- long iidx1 = idx9 + idx1;
- long iidx2 = idx9 + idx2;
- long iidx3 = idx9 + idx3;
- long iidx4 = idx9 + idx4;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
-
- cr2 = w1r * i2i + w1i * i2r;
- ci2 = w1r * i2r - w1i * i2i;
- cr3 = w2r * i3i + w2i * i3r;
- ci3 = w2r * i3r - w2i * i3i;
- cr4 = w3r * i4i + w3i * i4r;
- ci4 = w3r * i4r - w3i * i4i;
- tr1 = cr2 + cr4;
- tr4 = cr4 - cr2;
- ti1 = ci2 + ci4;
- ti4 = ci2 - ci4;
- ti2 = i1r + ci3;
- ti3 = i1r - ci3;
- tr2 = i1i + cr3;
- tr3 = i1i - cr3;
-
- long oidx1 = idx10 + idx5;
- long oidx2 = idx11 + idx6;
- long oidx3 = idx10 + idx7;
- long oidx4 = idx11 + idx8;
-
- out.setDouble(oidx1 - 1, tr1 + tr2);
- out.setDouble(oidx4 - 1, tr2 - tr1);
- out.setDouble(oidx1, ti1 + ti2);
- out.setDouble(oidx4, ti1 - ti2);
- out.setDouble(oidx3 - 1, ti4 + tr3);
- out.setDouble(oidx2 - 1, tr3 - ti4);
- out.setDouble(oidx3, tr4 + ti3);
- out.setDouble(oidx2, tr4 - ti3);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- long idx9 = in_off + ido;
- long idx10 = out_off + ido;
-
- double i1i = in.getDouble(idx9 - 1 + idx1);
- double i2i = in.getDouble(idx9 - 1 + idx3);
- double i3i = in.getDouble(idx9 - 1 + idx4);
- double i4i = in.getDouble(idx9 - 1 + idx5);
-
- ti1 = -hsqt2 * (i2i + i4i);
- tr1 = hsqt2 * (i2i - i4i);
-
- out.setDouble(idx10 - 1 + idx2, tr1 + i1i);
- out.setDouble(idx10 - 1 + idx7, i1i - tr1);
- out.setDouble(out_off + idx6, ti1 - i3i);
- out.setDouble(out_off + idx8, ti1 + i3i);
- }
- }
-
- /*-------------------------------------------------
- radb4: Real FFT's backward processing of factor 4
- -------------------------------------------------*/
- void radb4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double sqrt2 = 1.41421356237309514547462185873882845;
- int i, ic;
- double ci2, ci3, ci4, cr2, cr3, cr4;
- double ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
-
- double i1r = in[in_off + idx2];
- double i2r = in[in_off + idx7];
- double i3r = in[in_off + ido - 1 + idx8];
- double i4r = in[in_off + ido - 1 + idx6];
-
- tr1 = i1r - i3r;
- tr2 = i1r + i3r;
- tr3 = i4r + i4r;
- tr4 = i2r + i2r;
-
- out[out_off + idx1] = tr2 + tr3;
- out[out_off + idx3] = tr1 - tr4;
- out[out_off + idx4] = tr2 - tr3;
- out[out_off + idx5] = tr1 + tr4;
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = idx1 + idx0;
- int idx3 = idx2 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = 4 * idx1;
- int idx6 = idx5 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
-
- int idx12 = in_off + i;
- int idx13 = in_off + ic;
- int idx14 = out_off + i;
-
- int iidx1 = idx12 + idx5;
- int iidx2 = idx13 + idx6;
- int iidx3 = idx12 + idx7;
- int iidx4 = idx13 + idx8;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
-
- ti1 = i1r + i4r;
- ti2 = i1r - i4r;
- ti3 = i3r - i2r;
- tr4 = i3r + i2r;
- tr1 = i1i - i4i;
- tr2 = i1i + i4i;
- ti4 = i3i - i2i;
- tr3 = i3i + i2i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 - tr4;
- cr4 = tr1 + tr4;
- ci2 = ti1 + ti4;
- ci4 = ti1 - ti4;
-
- int oidx1 = idx14 + idx1;
- int oidx2 = idx14 + idx2;
- int oidx3 = idx14 + idx3;
- int oidx4 = idx14 + idx4;
-
- out[oidx1 - 1] = tr2 + tr3;
- out[oidx1] = ti2 + ti3;
- out[oidx2 - 1] = w1r * cr2 - w1i * ci2;
- out[oidx2] = w1r * ci2 + w1i * cr2;
- out[oidx3 - 1] = w2r * cr3 - w2i * ci3;
- out[oidx3] = w2r * ci3 + w2i * cr3;
- out[oidx4 - 1] = w3r * cr4 - w3i * ci4;
- out[oidx4] = w3r * ci4 + w3i * cr4;
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 4 * idx1;
- int idx3 = idx1 + idx0;
- int idx4 = idx3 + idx0;
- int idx5 = idx4 + idx0;
- int idx6 = idx2 + ido;
- int idx7 = idx6 + ido;
- int idx8 = idx7 + ido;
- int idx9 = in_off + ido;
- int idx10 = out_off + ido;
-
- double i1r = in[idx9 - 1 + idx2];
- double i2r = in[idx9 - 1 + idx7];
- double i3r = in[in_off + idx6];
- double i4r = in[in_off + idx8];
-
- ti1 = i3r + i4r;
- ti2 = i4r - i3r;
- tr1 = i1r - i2r;
- tr2 = i1r + i2r;
-
- out[idx10 - 1 + idx1] = tr2 + tr2;
- out[idx10 - 1 + idx3] = sqrt2 * (tr1 - ti1);
- out[idx10 - 1 + idx4] = ti2 + ti2;
- out[idx10 - 1 + idx5] = -sqrt2 * (tr1 + ti1);
- }
- }
-
- /*-------------------------------------------------
- radb4: Real FFT's backward processing of factor 4
- -------------------------------------------------*/
- void radb4(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double sqrt2 = 1.41421356237309514547462185873882845;
- long i, ic;
- double ci2, ci3, ci4, cr2, cr3, cr4;
- double ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4, w1r, w1i, w2r, w2i, w3r, w3i;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
-
- double i1r = in.getDouble(in_off + idx2);
- double i2r = in.getDouble(in_off + idx7);
- double i3r = in.getDouble(in_off + ido - 1 + idx8);
- double i4r = in.getDouble(in_off + ido - 1 + idx6);
-
- tr1 = i1r - i3r;
- tr2 = i1r + i3r;
- tr3 = i4r + i4r;
- tr4 = i2r + i2r;
-
- out.setDouble(out_off + idx1, tr2 + tr3);
- out.setDouble(out_off + idx3, tr1 - tr4);
- out.setDouble(out_off + idx4, tr2 - tr3);
- out.setDouble(out_off + idx5, tr1 + tr4);
- }
- if (ido < 2) {
- return;
- }
- if (ido != 2) {
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = idx1 + idx0;
- long idx3 = idx2 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = 4 * idx1;
- long idx6 = idx5 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
- w3r = wtable_rl.getDouble(widx3 - 1);
- w3i = wtable_rl.getDouble(widx3);
-
- long idx12 = in_off + i;
- long idx13 = in_off + ic;
- long idx14 = out_off + i;
-
- long iidx1 = idx12 + idx5;
- long iidx2 = idx13 + idx6;
- long iidx3 = idx12 + idx7;
- long iidx4 = idx13 + idx8;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
-
- ti1 = i1r + i4r;
- ti2 = i1r - i4r;
- ti3 = i3r - i2r;
- tr4 = i3r + i2r;
- tr1 = i1i - i4i;
- tr2 = i1i + i4i;
- ti4 = i3i - i2i;
- tr3 = i3i + i2i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 - tr4;
- cr4 = tr1 + tr4;
- ci2 = ti1 + ti4;
- ci4 = ti1 - ti4;
-
- long oidx1 = idx14 + idx1;
- long oidx2 = idx14 + idx2;
- long oidx3 = idx14 + idx3;
- long oidx4 = idx14 + idx4;
-
- out.setDouble(oidx1 - 1, tr2 + tr3);
- out.setDouble(oidx1, ti2 + ti3);
- out.setDouble(oidx2 - 1, w1r * cr2 - w1i * ci2);
- out.setDouble(oidx2, w1r * ci2 + w1i * cr2);
- out.setDouble(oidx3 - 1, w2r * cr3 - w2i * ci3);
- out.setDouble(oidx3, w2r * ci3 + w2i * cr3);
- out.setDouble(oidx4 - 1, w3r * cr4 - w3i * ci4);
- out.setDouble(oidx4, w3r * ci4 + w3i * cr4);
- }
- }
- if (ido % 2 == 1) {
- return;
- }
- }
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 4 * idx1;
- long idx3 = idx1 + idx0;
- long idx4 = idx3 + idx0;
- long idx5 = idx4 + idx0;
- long idx6 = idx2 + ido;
- long idx7 = idx6 + ido;
- long idx8 = idx7 + ido;
- long idx9 = in_off + ido;
- long idx10 = out_off + ido;
-
- double i1r = in.getDouble(idx9 - 1 + idx2);
- double i2r = in.getDouble(idx9 - 1 + idx7);
- double i3r = in.getDouble(in_off + idx6);
- double i4r = in.getDouble(in_off + idx8);
-
- ti1 = i3r + i4r;
- ti2 = i4r - i3r;
- tr1 = i1r - i2r;
- tr2 = i1r + i2r;
-
- out.setDouble(idx10 - 1 + idx1, tr2 + tr2);
- out.setDouble(idx10 - 1 + idx3, sqrt2 * (tr1 - ti1));
- out.setDouble(idx10 - 1 + idx4, ti2 + ti2);
- out.setDouble(idx10 - 1 + idx5, -sqrt2 * (tr1 + ti1));
- }
- }
-
- /*-------------------------------------------------
- radf5: Real FFT's forward processing of factor 5
- -------------------------------------------------*/
- void radf5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- int i, ic;
- double ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- int iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- int idx11 = out_off + ido - 1;
-
- double i1r = in[in_off + idx1];
- double i2r = in[in_off + idx7];
- double i3r = in[in_off + idx8];
- double i4r = in[in_off + idx9];
- double i5r = in[in_off + idx10];
-
- cr2 = i5r + i2r;
- ci5 = i5r - i2r;
- cr3 = i4r + i3r;
- ci4 = i4r - i3r;
-
- out[out_off + idx2] = i1r + cr2 + cr3;
- out[idx11 + idx3] = i1r + tr11 * cr2 + tr12 * cr3;
- out[out_off + idx4] = ti11 * ci5 + ti12 * ci4;
- out[idx11 + idx5] = i1r + tr12 * cr2 + tr11 * cr3;
- out[out_off + idx6] = ti12 * ci5 - ti11 * ci4;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- int widx4 = i - 1 + iw4;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
- w4r = wtable_r[widx4 - 1];
- w4i = wtable_r[widx4];
-
- ic = ido - i;
- int idx15 = in_off + i;
- int idx16 = out_off + i;
- int idx17 = out_off + ic;
-
- int iidx1 = idx15 + idx1;
- int iidx2 = idx15 + idx7;
- int iidx3 = idx15 + idx8;
- int iidx4 = idx15 + idx9;
- int iidx5 = idx15 + idx10;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
- double i5i = in[iidx5 - 1];
- double i5r = in[iidx5];
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- dr4 = w3r * i4i + w3i * i4r;
- di4 = w3r * i4r - w3i * i4i;
- dr5 = w4r * i5i + w4i * i5r;
- di5 = w4r * i5r - w4i * i5i;
-
- cr2 = dr2 + dr5;
- ci5 = dr5 - dr2;
- cr5 = di2 - di5;
- ci2 = di2 + di5;
- cr3 = dr3 + dr4;
- ci4 = dr4 - dr3;
- cr4 = di3 - di4;
- ci3 = di3 + di4;
-
- tr2 = i1i + tr11 * cr2 + tr12 * cr3;
- ti2 = i1r + tr11 * ci2 + tr12 * ci3;
- tr3 = i1i + tr12 * cr2 + tr11 * cr3;
- ti3 = i1r + tr12 * ci2 + tr11 * ci3;
- tr5 = ti11 * cr5 + ti12 * cr4;
- ti5 = ti11 * ci5 + ti12 * ci4;
- tr4 = ti12 * cr5 - ti11 * cr4;
- ti4 = ti12 * ci5 - ti11 * ci4;
-
- int oidx1 = idx16 + idx2;
- int oidx2 = idx17 + idx3;
- int oidx3 = idx16 + idx4;
- int oidx4 = idx17 + idx5;
- int oidx5 = idx16 + idx6;
-
- out[oidx1 - 1] = i1i + cr2 + cr3;
- out[oidx1] = i1r + ci2 + ci3;
- out[oidx3 - 1] = tr2 + tr5;
- out[oidx2 - 1] = tr2 - tr5;
- out[oidx3] = ti2 + ti5;
- out[oidx2] = ti5 - ti2;
- out[oidx5 - 1] = tr3 + tr4;
- out[oidx4 - 1] = tr3 - tr4;
- out[oidx5] = ti3 + ti4;
- out[oidx4] = ti4 - ti3;
- }
- }
- }
-
- /*-------------------------------------------------
- radf5: Real FFT's forward processing of factor 5
- -------------------------------------------------*/
- void radf5(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- long i, ic;
- double ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3, dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- long iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- long idx11 = out_off + ido - 1;
-
- double i1r = in.getDouble(in_off + idx1);
- double i2r = in.getDouble(in_off + idx7);
- double i3r = in.getDouble(in_off + idx8);
- double i4r = in.getDouble(in_off + idx9);
- double i5r = in.getDouble(in_off + idx10);
-
- cr2 = i5r + i2r;
- ci5 = i5r - i2r;
- cr3 = i4r + i3r;
- ci4 = i4r - i3r;
-
- out.setDouble(out_off + idx2, i1r + cr2 + cr3);
- out.setDouble(idx11 + idx3, i1r + tr11 * cr2 + tr12 * cr3);
- out.setDouble(out_off + idx4, ti11 * ci5 + ti12 * ci4);
- out.setDouble(idx11 + idx5, i1r + tr12 * cr2 + tr11 * cr3);
- out.setDouble(out_off + idx6, ti12 * ci5 - ti11 * ci4);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- long widx4 = i - 1 + iw4;
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
- w3r = wtable_rl.getDouble(widx3 - 1);
- w3i = wtable_rl.getDouble(widx3);
- w4r = wtable_rl.getDouble(widx4 - 1);
- w4i = wtable_rl.getDouble(widx4);
-
- ic = ido - i;
- long idx15 = in_off + i;
- long idx16 = out_off + i;
- long idx17 = out_off + ic;
-
- long iidx1 = idx15 + idx1;
- long iidx2 = idx15 + idx7;
- long iidx3 = idx15 + idx8;
- long iidx4 = idx15 + idx9;
- long iidx5 = idx15 + idx10;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
- double i5i = in.getDouble(iidx5 - 1);
- double i5r = in.getDouble(iidx5);
-
- dr2 = w1r * i2i + w1i * i2r;
- di2 = w1r * i2r - w1i * i2i;
- dr3 = w2r * i3i + w2i * i3r;
- di3 = w2r * i3r - w2i * i3i;
- dr4 = w3r * i4i + w3i * i4r;
- di4 = w3r * i4r - w3i * i4i;
- dr5 = w4r * i5i + w4i * i5r;
- di5 = w4r * i5r - w4i * i5i;
-
- cr2 = dr2 + dr5;
- ci5 = dr5 - dr2;
- cr5 = di2 - di5;
- ci2 = di2 + di5;
- cr3 = dr3 + dr4;
- ci4 = dr4 - dr3;
- cr4 = di3 - di4;
- ci3 = di3 + di4;
-
- tr2 = i1i + tr11 * cr2 + tr12 * cr3;
- ti2 = i1r + tr11 * ci2 + tr12 * ci3;
- tr3 = i1i + tr12 * cr2 + tr11 * cr3;
- ti3 = i1r + tr12 * ci2 + tr11 * ci3;
- tr5 = ti11 * cr5 + ti12 * cr4;
- ti5 = ti11 * ci5 + ti12 * ci4;
- tr4 = ti12 * cr5 - ti11 * cr4;
- ti4 = ti12 * ci5 - ti11 * ci4;
-
- long oidx1 = idx16 + idx2;
- long oidx2 = idx17 + idx3;
- long oidx3 = idx16 + idx4;
- long oidx4 = idx17 + idx5;
- long oidx5 = idx16 + idx6;
-
- out.setDouble(oidx1 - 1, i1i + cr2 + cr3);
- out.setDouble(oidx1, i1r + ci2 + ci3);
- out.setDouble(oidx3 - 1, tr2 + tr5);
- out.setDouble(oidx2 - 1, tr2 - tr5);
- out.setDouble(oidx3, ti2 + ti5);
- out.setDouble(oidx2, ti5 - ti2);
- out.setDouble(oidx5 - 1, tr3 + tr4);
- out.setDouble(oidx4 - 1, tr3 - tr4);
- out.setDouble(oidx5, ti3 + ti4);
- out.setDouble(oidx4, ti4 - ti3);
- }
- }
- }
-
- /*-------------------------------------------------
- radb5: Real FFT's backward processing of factor 5
- -------------------------------------------------*/
- void radb5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- int i, ic;
- double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- int iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- int idx11 = in_off + ido - 1;
-
- double i1r = in[in_off + idx2];
-
- ti5 = 2 * in[in_off + idx4];
- ti4 = 2 * in[in_off + idx6];
- tr2 = 2 * in[idx11 + idx3];
- tr3 = 2 * in[idx11 + idx5];
- cr2 = i1r + tr11 * tr2 + tr12 * tr3;
- cr3 = i1r + tr12 * tr2 + tr11 * tr3;
- ci5 = ti11 * ti5 + ti12 * ti4;
- ci4 = ti12 * ti5 - ti11 * ti4;
-
- out[out_off + idx1] = i1r + tr2 + tr3;
- out[out_off + idx7] = cr2 - ci5;
- out[out_off + idx8] = cr3 - ci4;
- out[out_off + idx9] = cr3 + ci4;
- out[out_off + idx10] = cr2 + ci5;
- }
- if (ido == 1) {
- return;
- }
- for (int k = 0; k < l1; ++k) {
- int idx1 = k * ido;
- int idx2 = 5 * idx1;
- int idx3 = idx2 + ido;
- int idx4 = idx3 + ido;
- int idx5 = idx4 + ido;
- int idx6 = idx5 + ido;
- int idx7 = idx1 + idx0;
- int idx8 = idx7 + idx0;
- int idx9 = idx8 + idx0;
- int idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- int widx1 = i - 1 + iw1;
- int widx2 = i - 1 + iw2;
- int widx3 = i - 1 + iw3;
- int widx4 = i - 1 + iw4;
- w1r = wtable_r[widx1 - 1];
- w1i = wtable_r[widx1];
- w2r = wtable_r[widx2 - 1];
- w2i = wtable_r[widx2];
- w3r = wtable_r[widx3 - 1];
- w3i = wtable_r[widx3];
- w4r = wtable_r[widx4 - 1];
- w4i = wtable_r[widx4];
-
- int idx15 = in_off + i;
- int idx16 = in_off + ic;
- int idx17 = out_off + i;
-
- int iidx1 = idx15 + idx2;
- int iidx2 = idx16 + idx3;
- int iidx3 = idx15 + idx4;
- int iidx4 = idx16 + idx5;
- int iidx5 = idx15 + idx6;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
- double i5i = in[iidx5 - 1];
- double i5r = in[iidx5];
-
- ti5 = i3r + i2r;
- ti2 = i3r - i2r;
- ti4 = i5r + i4r;
- ti3 = i5r - i4r;
- tr5 = i3i - i2i;
- tr2 = i3i + i2i;
- tr4 = i5i - i4i;
- tr3 = i5i + i4i;
-
- cr2 = i1i + tr11 * tr2 + tr12 * tr3;
- ci2 = i1r + tr11 * ti2 + tr12 * ti3;
- cr3 = i1i + tr12 * tr2 + tr11 * tr3;
- ci3 = i1r + tr12 * ti2 + tr11 * ti3;
- cr5 = ti11 * tr5 + ti12 * tr4;
- ci5 = ti11 * ti5 + ti12 * ti4;
- cr4 = ti12 * tr5 - ti11 * tr4;
- ci4 = ti12 * ti5 - ti11 * ti4;
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- int oidx1 = idx17 + idx1;
- int oidx2 = idx17 + idx7;
- int oidx3 = idx17 + idx8;
- int oidx4 = idx17 + idx9;
- int oidx5 = idx17 + idx10;
-
- out[oidx1 - 1] = i1i + tr2 + tr3;
- out[oidx1] = i1r + ti2 + ti3;
- out[oidx2 - 1] = w1r * dr2 - w1i * di2;
- out[oidx2] = w1r * di2 + w1i * dr2;
- out[oidx3 - 1] = w2r * dr3 - w2i * di3;
- out[oidx3] = w2r * di3 + w2i * dr3;
- out[oidx4 - 1] = w3r * dr4 - w3i * di4;
- out[oidx4] = w3r * di4 + w3i * dr4;
- out[oidx5 - 1] = w4r * dr5 - w4i * di5;
- out[oidx5] = w4r * di5 + w4i * dr5;
- }
- }
- }
-
- /*-------------------------------------------------
- radb5: Real FFT's backward processing of factor 5
- -------------------------------------------------*/
- void radb5(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- long i, ic;
- double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5, w1r, w1i, w2r, w2i, w3r, w3i, w4r, w4i;
- long iw1, iw2, iw3, iw4;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- long idx11 = in_off + ido - 1;
-
- double i1r = in.getDouble(in_off + idx2);
-
- ti5 = 2 * in.getDouble(in_off + idx4);
- ti4 = 2 * in.getDouble(in_off + idx6);
- tr2 = 2 * in.getDouble(idx11 + idx3);
- tr3 = 2 * in.getDouble(idx11 + idx5);
- cr2 = i1r + tr11 * tr2 + tr12 * tr3;
- cr3 = i1r + tr12 * tr2 + tr11 * tr3;
- ci5 = ti11 * ti5 + ti12 * ti4;
- ci4 = ti12 * ti5 - ti11 * ti4;
-
- out.setDouble(out_off + idx1, i1r + tr2 + tr3);
- out.setDouble(out_off + idx7, cr2 - ci5);
- out.setDouble(out_off + idx8, cr3 - ci4);
- out.setDouble(out_off + idx9, cr3 + ci4);
- out.setDouble(out_off + idx10, cr2 + ci5);
- }
- if (ido == 1) {
- return;
- }
- for (long k = 0; k < l1; ++k) {
- long idx1 = k * ido;
- long idx2 = 5 * idx1;
- long idx3 = idx2 + ido;
- long idx4 = idx3 + ido;
- long idx5 = idx4 + ido;
- long idx6 = idx5 + ido;
- long idx7 = idx1 + idx0;
- long idx8 = idx7 + idx0;
- long idx9 = idx8 + idx0;
- long idx10 = idx9 + idx0;
- for (i = 2; i < ido; i += 2) {
- ic = ido - i;
- long widx1 = i - 1 + iw1;
- long widx2 = i - 1 + iw2;
- long widx3 = i - 1 + iw3;
- long widx4 = i - 1 + iw4;
- w1r = wtable_rl.getDouble(widx1 - 1);
- w1i = wtable_rl.getDouble(widx1);
- w2r = wtable_rl.getDouble(widx2 - 1);
- w2i = wtable_rl.getDouble(widx2);
- w3r = wtable_rl.getDouble(widx3 - 1);
- w3i = wtable_rl.getDouble(widx3);
- w4r = wtable_rl.getDouble(widx4 - 1);
- w4i = wtable_rl.getDouble(widx4);
-
- long idx15 = in_off + i;
- long idx16 = in_off + ic;
- long idx17 = out_off + i;
-
- long iidx1 = idx15 + idx2;
- long iidx2 = idx16 + idx3;
- long iidx3 = idx15 + idx4;
- long iidx4 = idx16 + idx5;
- long iidx5 = idx15 + idx6;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
- double i5i = in.getDouble(iidx5 - 1);
- double i5r = in.getDouble(iidx5);
-
- ti5 = i3r + i2r;
- ti2 = i3r - i2r;
- ti4 = i5r + i4r;
- ti3 = i5r - i4r;
- tr5 = i3i - i2i;
- tr2 = i3i + i2i;
- tr4 = i5i - i4i;
- tr3 = i5i + i4i;
-
- cr2 = i1i + tr11 * tr2 + tr12 * tr3;
- ci2 = i1r + tr11 * ti2 + tr12 * ti3;
- cr3 = i1i + tr12 * tr2 + tr11 * tr3;
- ci3 = i1r + tr12 * ti2 + tr11 * ti3;
- cr5 = ti11 * tr5 + ti12 * tr4;
- ci5 = ti11 * ti5 + ti12 * ti4;
- cr4 = ti12 * tr5 - ti11 * tr4;
- ci4 = ti12 * ti5 - ti11 * ti4;
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- long oidx1 = idx17 + idx1;
- long oidx2 = idx17 + idx7;
- long oidx3 = idx17 + idx8;
- long oidx4 = idx17 + idx9;
- long oidx5 = idx17 + idx10;
-
- out.setDouble(oidx1 - 1, i1i + tr2 + tr3);
- out.setDouble(oidx1, i1r + ti2 + ti3);
- out.setDouble(oidx2 - 1, w1r * dr2 - w1i * di2);
- out.setDouble(oidx2, w1r * di2 + w1i * dr2);
- out.setDouble(oidx3 - 1, w2r * dr3 - w2i * di3);
- out.setDouble(oidx3, w2r * di3 + w2i * dr3);
- out.setDouble(oidx4 - 1, w3r * dr4 - w3i * di4);
- out.setDouble(oidx4, w3r * di4 + w3i * dr4);
- out.setDouble(oidx5 - 1, w4r * dr5 - w4i * di5);
- out.setDouble(oidx5, w4r * di5 + w4i * dr5);
- }
- }
- }
-
- /*---------------------------------------------------------
- radfg: Real FFT's forward processing of general factor
- --------------------------------------------------------*/
- void radfg(final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- int idij, ipph, j2, ic, jc, lc, is, nbd;
- double dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
- int iw1 = offset;
-
- arg = TWO_PI / (double) ip;
- dcp = Math.cos(arg);
- dsp = Math.sin(arg);
- ipph = (ip + 1) / 2;
- nbd = (ido - 1) / 2;
- if (ido != 1) {
- for (int ik = 0; ik < idl1; ik++) {
- out[out_off + ik] = in[in_off + ik];
- }
- for (int j = 1; j < ip; j++) {
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido + idx1;
- out[out_off + idx2] = in[in_off + idx2];
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- int idx1 = j * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int oidx1 = idx5 + idx3;
- int iidx1 = idx4 + idx3;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
-
- out[oidx1 - 1] = w1r * i1i + w1i * i1r;
- out[oidx1] = w1r * i1r - w1i * i1i;
- }
- }
- }
- } else {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = is - 1;
- int idx3 = k * ido + idx1;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int oidx1 = out_off + i + idx3;
- int iidx1 = in_off + i + idx3;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
-
- out[oidx1 - 1] = w1r * i1i + w1i * i1r;
- out[oidx1] = w1r * i1r - w1i * i1i;
- }
- }
- }
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- for (int i = 2; i < ido; i += 2) {
- int idx5 = in_off + i;
- int idx6 = out_off + i;
- int iidx1 = idx5 + idx3;
- int iidx2 = idx5 + idx4;
- int oidx1 = idx6 + idx3;
- int oidx2 = idx6 + idx4;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- double o2i = out[oidx2 - 1];
- double o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx1] = o1r + o2r;
-
- in[iidx2 - 1] = o1r - o2r;
- in[iidx2] = o2i - o1i;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx5 = in_off + i;
- int idx6 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- int iidx1 = idx5 + idx3;
- int iidx2 = idx5 + idx4;
- int oidx1 = idx6 + idx3;
- int oidx2 = idx6 + idx4;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- double o2i = out[oidx2 - 1];
- double o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2 - 1] = o1r - o2r;
- in[iidx2] = o2i - o1i;
- }
- }
- }
- }
- } else {
- System.arraycopy(out, out_off, in, in_off, idl1);
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int idx4 = k * ido + idx2;
- int oidx1 = out_off + idx3;
- int oidx2 = out_off + idx4;
- double o1r = out[oidx1];
- double o2r = out[oidx2];
-
- in[in_off + idx3] = o1r + o2r;
- in[in_off + idx4] = o2r - o1r;
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- int idx0 = (ip - 1) * idl1;
- for (int l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- int idx1 = l * idl1;
- int idx2 = lc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx3 = out_off + ik;
- int idx4 = in_off + ik;
- out[idx3 + idx1] = in[idx4] + ar1 * in[idx4 + idl1];
- out[idx3 + idx2] = ai1 * in[idx4 + idx0];
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- int idx3 = j * idl1;
- int idx4 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx5 = out_off + ik;
- int idx6 = in_off + ik;
- out[idx5 + idx1] += ar2 * in[idx6 + idx3];
- out[idx5 + idx2] += ai2 * in[idx6 + idx4];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idx1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- out[out_off + ik] += in[in_off + ik + idx1];
- }
- }
-
- if (ido >= l1) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 * ip;
- for (int i = 0; i < ido; i++) {
- in[in_off + i + idx2] = out[out_off + i + idx1];
- }
- }
- } else {
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- in[in_off + i + idx1 * ip] = out[out_off + i + idx1];
- }
- }
- }
- int idx01 = ip * ido;
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido;
- int idx5 = idx4 + idx1;
- int idx6 = idx4 + idx2;
- int idx7 = k * idx01;
- in[in_off + ido - 1 + idx3 - ido + idx7] = out[out_off + idx5];
- in[in_off + idx3 + idx7] = out[out_off + idx6];
- }
- }
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * idx01;
- int idx5 = k * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx6 = in_off + i;
- int idx7 = in_off + ic;
- int idx8 = out_off + i;
- int iidx1 = idx6 + idx3 + idx4;
- int iidx2 = idx7 + idx3 - ido + idx4;
- int oidx1 = idx8 + idx5 + idx1;
- int oidx2 = idx8 + idx5 + idx2;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- double o2i = out[oidx2 - 1];
- double o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx2 - 1] = o1i - o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2] = o2r - o1r;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx6 = in_off + i;
- int idx7 = in_off + ic;
- int idx8 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * idx01;
- int idx5 = k * ido;
- int iidx1 = idx6 + idx3 + idx4;
- int iidx2 = idx7 + idx3 - ido + idx4;
- int oidx1 = idx8 + idx5 + idx1;
- int oidx2 = idx8 + idx5 + idx2;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- double o2i = out[oidx2 - 1];
- double o2r = out[oidx2];
-
- in[iidx1 - 1] = o1i + o2i;
- in[iidx2 - 1] = o1i - o2i;
- in[iidx1] = o1r + o2r;
- in[iidx2] = o2r - o1r;
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radfg: Real FFT's forward processing of general factor
- --------------------------------------------------------*/
- void radfg(final long ido, final long ip, final long l1, final long idl1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- long idij, ipph, j2, ic, jc, lc, is, nbd;
- double dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h, w1r, w1i;
- long iw1 = offset;
-
- arg = TWO_PI / (double) ip;
- dcp = Math.cos(arg);
- dsp = Math.sin(arg);
- ipph = (ip + 1) / 2;
- nbd = (ido - 1) / 2;
- if (ido != 1) {
- for (long ik = 0; ik < idl1; ik++) {
- out.setDouble(out_off + ik, in.getDouble(in_off + ik));
- }
- for (long j = 1; j < ip; j++) {
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido + idx1;
- out.setDouble(out_off + idx2, in.getDouble(in_off + idx2));
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- long idx1 = j * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- w1r = wtable_rl.getDouble(idx2 - 1);
- w1i = wtable_rl.getDouble(idx2);
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long oidx1 = idx5 + idx3;
- long iidx1 = idx4 + idx3;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
-
- out.setDouble(oidx1 - 1, w1r * i1i + w1i * i1r);
- out.setDouble(oidx1, w1r * i1r - w1i * i1i);
- }
- }
- }
- } else {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = is - 1;
- long idx3 = k * ido + idx1;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getDouble(idx2 - 1);
- w1i = wtable_rl.getDouble(idx2);
- long oidx1 = out_off + i + idx3;
- long iidx1 = in_off + i + idx3;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
-
- out.setDouble(oidx1 - 1, w1r * i1i + w1i * i1r);
- out.setDouble(oidx1, w1r * i1r - w1i * i1i);
- }
- }
- }
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- for (long i = 2; i < ido; i += 2) {
- long idx5 = in_off + i;
- long idx6 = out_off + i;
- long iidx1 = idx5 + idx3;
- long iidx2 = idx5 + idx4;
- long oidx1 = idx6 + idx3;
- long oidx2 = idx6 + idx4;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- double o2i = out.getDouble(oidx2 - 1);
- double o2r = out.getDouble(oidx2);
-
- in.setDouble(iidx1 - 1, o1i + o2i);
- in.setDouble(iidx1, o1r + o2r);
-
- in.setDouble(iidx2 - 1, o1r - o2r);
- in.setDouble(iidx2, o2i - o1i);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx5 = in_off + i;
- long idx6 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- long iidx1 = idx5 + idx3;
- long iidx2 = idx5 + idx4;
- long oidx1 = idx6 + idx3;
- long oidx2 = idx6 + idx4;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- double o2i = out.getDouble(oidx2 - 1);
- double o2r = out.getDouble(oidx2);
-
- in.setDouble(iidx1 - 1, o1i + o2i);
- in.setDouble(iidx1, o1r + o2r);
- in.setDouble(iidx2 - 1, o1r - o2r);
- in.setDouble(iidx2, o2i - o1i);
- }
- }
- }
- }
- } else {
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long idx4 = k * ido + idx2;
- long oidx1 = out_off + idx3;
- long oidx2 = out_off + idx4;
- double o1r = out.getDouble(oidx1);
- double o2r = out.getDouble(oidx2);
-
- in.setDouble(in_off + idx3, o1r + o2r);
- in.setDouble(in_off + idx4, o2r - o1r);
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- long idx0 = (ip - 1) * idl1;
- for (long l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- long idx1 = l * idl1;
- long idx2 = lc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx3 = out_off + ik;
- long idx4 = in_off + ik;
- out.setDouble(idx3 + idx1, in.getDouble(idx4) + ar1 * in.getDouble(idx4 + idl1));
- out.setDouble(idx3 + idx2, ai1 * in.getDouble(idx4 + idx0));
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- long idx3 = j * idl1;
- long idx4 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx5 = out_off + ik;
- long idx6 = in_off + ik;
- out.setDouble(idx5 + idx1, out.getDouble(idx5 + idx1) + ar2 * in.getDouble(idx6 + idx3));
- out.setDouble(idx5 + idx2, out.getDouble(idx5 + idx2) + ai2 * in.getDouble(idx6 + idx4));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idx1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- out.setDouble(out_off + ik, out.getDouble(out_off + ik) + in.getDouble(in_off + ik + idx1));
- }
- }
-
- if (ido >= l1) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 * ip;
- for (long i = 0; i < ido; i++) {
- in.setDouble(in_off + i + idx2, out.getDouble(out_off + i + idx1));
- }
- }
- } else {
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- in.setDouble(in_off + i + idx1 * ip, out.getDouble(out_off + i + idx1));
- }
- }
- }
- long idx01 = ip * ido;
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido;
- long idx5 = idx4 + idx1;
- long idx6 = idx4 + idx2;
- long idx7 = k * idx01;
- in.setDouble(in_off + ido - 1 + idx3 - ido + idx7, out.getDouble(out_off + idx5));
- in.setDouble(in_off + idx3 + idx7, out.getDouble(out_off + idx6));
- }
- }
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * idx01;
- long idx5 = k * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx6 = in_off + i;
- long idx7 = in_off + ic;
- long idx8 = out_off + i;
- long iidx1 = idx6 + idx3 + idx4;
- long iidx2 = idx7 + idx3 - ido + idx4;
- long oidx1 = idx8 + idx5 + idx1;
- long oidx2 = idx8 + idx5 + idx2;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- double o2i = out.getDouble(oidx2 - 1);
- double o2r = out.getDouble(oidx2);
-
- in.setDouble(iidx1 - 1, o1i + o2i);
- in.setDouble(iidx2 - 1, o1i - o2i);
- in.setDouble(iidx1, o1r + o2r);
- in.setDouble(iidx2, o2r - o1r);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx6 = in_off + i;
- long idx7 = in_off + ic;
- long idx8 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * idx01;
- long idx5 = k * ido;
- long iidx1 = idx6 + idx3 + idx4;
- long iidx2 = idx7 + idx3 - ido + idx4;
- long oidx1 = idx8 + idx5 + idx1;
- long oidx2 = idx8 + idx5 + idx2;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- double o2i = out.getDouble(oidx2 - 1);
- double o2r = out.getDouble(oidx2);
-
- in.setDouble(iidx1 - 1, o1i + o2i);
- in.setDouble(iidx2 - 1, o1i - o2i);
- in.setDouble(iidx1, o1r + o2r);
- in.setDouble(iidx2, o2r - o1r);
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radbg: Real FFT's backward processing of general factor
- --------------------------------------------------------*/
- void radbg(final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset) {
- int idij, ipph, j2, ic, jc, lc, is;
- double dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
- int nbd;
- double dcp, arg, dsp, ar1h, ar2h;
- int iw1 = offset;
-
- arg = TWO_PI / (double) ip;
- dcp = Math.cos(arg);
- dsp = Math.sin(arg);
- nbd = (ido - 1) / 2;
- ipph = (ip + 1) / 2;
- int idx0 = ip * ido;
- if (ido >= l1) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = k * idx0;
- for (int i = 0; i < ido; i++) {
- out[out_off + i + idx1] = in[in_off + i + idx2];
- }
- }
- } else {
- for (int i = 0; i < ido; i++) {
- int idx1 = out_off + i;
- int idx2 = in_off + i;
- for (int k = 0; k < l1; k++) {
- out[idx1 + k * ido] = in[idx2 + k * idx0];
- }
- }
- }
- int iidx0 = in_off + ido - 1;
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = j2 * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido;
- int idx5 = idx4 * ip;
- int iidx1 = iidx0 + idx3 + idx5 - ido;
- int iidx2 = in_off + idx3 + idx5;
- double i1r = in[iidx1];
- double i2r = in[iidx2];
-
- out[out_off + idx4 + idx1] = i1r + i1r;
- out[out_off + idx4 + idx2] = i2r + i2r;
- }
- }
-
- if (ido != 1) {
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = 2 * j * ido;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido + idx1;
- int idx5 = k * ido + idx2;
- int idx6 = k * ip * ido + idx3;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = out_off + i;
- int idx8 = in_off + ic;
- int idx9 = in_off + i;
- int oidx1 = idx7 + idx4;
- int oidx2 = idx7 + idx5;
- int iidx1 = idx9 + idx6;
- int iidx2 = idx8 + idx6 - ido;
- double a1i = in[iidx1 - 1];
- double a1r = in[iidx1];
- double a2i = in[iidx2 - 1];
- double a2r = in[iidx2];
-
- out[oidx1 - 1] = a1i + a2i;
- out[oidx2 - 1] = a1i - a2i;
- out[oidx1] = a1r - a2r;
- out[oidx2] = a1r + a2r;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- int idx3 = 2 * j * ido;
- for (int i = 2; i < ido; i += 2) {
- ic = ido - i;
- int idx7 = out_off + i;
- int idx8 = in_off + ic;
- int idx9 = in_off + i;
- for (int k = 0; k < l1; k++) {
- int idx4 = k * ido + idx1;
- int idx5 = k * ido + idx2;
- int idx6 = k * ip * ido + idx3;
- int oidx1 = idx7 + idx4;
- int oidx2 = idx7 + idx5;
- int iidx1 = idx9 + idx6;
- int iidx2 = idx8 + idx6 - ido;
- double a1i = in[iidx1 - 1];
- double a1r = in[iidx1];
- double a2i = in[iidx2 - 1];
- double a2r = in[iidx2];
-
- out[oidx1 - 1] = a1i + a2i;
- out[oidx2 - 1] = a1i - a2i;
- out[oidx1] = a1r - a2r;
- out[oidx2] = a1r + a2r;
- }
- }
- }
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- int idx01 = (ip - 1) * idl1;
- for (int l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- int idx1 = l * idl1;
- int idx2 = lc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx3 = in_off + ik;
- int idx4 = out_off + ik;
- in[idx3 + idx1] = out[idx4] + ar1 * out[idx4 + idl1];
- in[idx3 + idx2] = ai1 * out[idx4 + idx01];
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- int idx5 = j * idl1;
- int idx6 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx7 = in_off + ik;
- int idx8 = out_off + ik;
- in[idx7 + idx1] += ar2 * out[idx8 + idx5];
- in[idx7 + idx2] += ai2 * out[idx8 + idx6];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idx1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx2 = out_off + ik;
- out[idx2] += out[idx2 + idx1];
- }
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int oidx1 = out_off + idx3;
- int iidx1 = in_off + idx3 + idx1;
- int iidx2 = in_off + idx3 + idx2;
- double i1r = in[iidx1];
- double i2r = in[iidx2];
-
- out[oidx1 + idx1] = i1r - i2r;
- out[oidx1 + idx2] = i1r + i2r;
- }
- }
-
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx4 = out_off + i;
- int idx5 = in_off + i;
- int oidx1 = idx4 + idx3 + idx1;
- int oidx2 = idx4 + idx3 + idx2;
- int iidx1 = idx5 + idx3 + idx1;
- int iidx2 = idx5 + idx3 + idx2;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
-
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * l1 * ido;
- int idx2 = jc * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- int idx4 = out_off + i;
- int idx5 = in_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int oidx1 = idx4 + idx3 + idx1;
- int oidx2 = idx4 + idx3 + idx2;
- int iidx1 = idx5 + idx3 + idx1;
- int iidx2 = idx5 + idx3 + idx2;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
-
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- }
- }
- System.arraycopy(out, out_off, in, in_off, idl1);
- for (int j = 1; j < ip; j++) {
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido + idx1;
- in[in_off + idx2] = out[out_off + idx2];
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- int idx1 = j * l1 * ido;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido + idx1;
- int iidx1 = idx4 + idx3;
- int oidx1 = idx5 + idx3;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
-
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- } else {
- is = -ido;
- for (int j = 1; j < ip; j++) {
- is += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = is - 1;
- int idx3 = k * ido + idx1;
- for (int i = 2; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1;
- w1r = wtable_r[idx2 - 1];
- w1i = wtable_r[idx2];
- int idx4 = in_off + i;
- int idx5 = out_off + i;
- int iidx1 = idx4 + idx3;
- int oidx1 = idx5 + idx3;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
-
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
-
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- radbg: Real FFT's backward processing of general factor
- --------------------------------------------------------*/
- void radbg(final long ido, final long ip, final long l1, final long idl1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset) {
- long idij, ipph, j2, ic, jc, lc, is;
- double dc2, ai1, ai2, ar1, ar2, ds2, w1r, w1i;
- long nbd;
- double dcp, arg, dsp, ar1h, ar2h;
- long iw1 = offset;
-
- arg = TWO_PI / (double) ip;
- dcp = Math.cos(arg);
- dsp = Math.sin(arg);
- nbd = (ido - 1) / 2;
- ipph = (ip + 1) / 2;
- long idx0 = ip * ido;
- if (ido >= l1) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = k * idx0;
- for (long i = 0; i < ido; i++) {
- out.setDouble(out_off + i + idx1, in.getDouble(in_off + i + idx2));
- }
- }
- } else {
- for (long i = 0; i < ido; i++) {
- long idx1 = out_off + i;
- long idx2 = in_off + i;
- for (long k = 0; k < l1; k++) {
- out.setDouble(idx1 + k * ido, in.getDouble(idx2 + k * idx0));
- }
- }
- }
- long iidx0 = in_off + ido - 1;
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- j2 = 2 * j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = j2 * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido;
- long idx5 = idx4 * ip;
- long iidx1 = iidx0 + idx3 + idx5 - ido;
- long iidx2 = in_off + idx3 + idx5;
- double i1r = in.getDouble(iidx1);
- double i2r = in.getDouble(iidx2);
-
- out.setDouble(out_off + idx4 + idx1, i1r + i1r);
- out.setDouble(out_off + idx4 + idx2, i2r + i2r);
- }
- }
-
- if (ido != 1) {
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = 2 * j * ido;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido + idx1;
- long idx5 = k * ido + idx2;
- long idx6 = k * ip * ido + idx3;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = out_off + i;
- long idx8 = in_off + ic;
- long idx9 = in_off + i;
- long oidx1 = idx7 + idx4;
- long oidx2 = idx7 + idx5;
- long iidx1 = idx9 + idx6;
- long iidx2 = idx8 + idx6 - ido;
- double a1i = in.getDouble(iidx1 - 1);
- double a1r = in.getDouble(iidx1);
- double a2i = in.getDouble(iidx2 - 1);
- double a2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1 - 1, a1i + a2i);
- out.setDouble(oidx2 - 1, a1i - a2i);
- out.setDouble(oidx1, a1r - a2r);
- out.setDouble(oidx2, a1r + a2r);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- long idx3 = 2 * j * ido;
- for (long i = 2; i < ido; i += 2) {
- ic = ido - i;
- long idx7 = out_off + i;
- long idx8 = in_off + ic;
- long idx9 = in_off + i;
- for (long k = 0; k < l1; k++) {
- long idx4 = k * ido + idx1;
- long idx5 = k * ido + idx2;
- long idx6 = k * ip * ido + idx3;
- long oidx1 = idx7 + idx4;
- long oidx2 = idx7 + idx5;
- long iidx1 = idx9 + idx6;
- long iidx2 = idx8 + idx6 - ido;
- double a1i = in.getDouble(iidx1 - 1);
- double a1r = in.getDouble(iidx1);
- double a2i = in.getDouble(iidx2 - 1);
- double a2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1 - 1, a1i + a2i);
- out.setDouble(oidx2 - 1, a1i - a2i);
- out.setDouble(oidx1, a1r - a2r);
- out.setDouble(oidx2, a1r + a2r);
- }
- }
- }
- }
- }
-
- ar1 = 1;
- ai1 = 0;
- long idx01 = (ip - 1) * idl1;
- for (long l = 1; l < ipph; l++) {
- lc = ip - l;
- ar1h = dcp * ar1 - dsp * ai1;
- ai1 = dcp * ai1 + dsp * ar1;
- ar1 = ar1h;
- long idx1 = l * idl1;
- long idx2 = lc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx3 = in_off + ik;
- long idx4 = out_off + ik;
- in.setDouble(idx3 + idx1, out.getDouble(idx4) + ar1 * out.getDouble(idx4 + idl1));
- in.setDouble(idx3 + idx2, ai1 * out.getDouble(idx4 + idx01));
- }
- dc2 = ar1;
- ds2 = ai1;
- ar2 = ar1;
- ai2 = ai1;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- ar2h = dc2 * ar2 - ds2 * ai2;
- ai2 = dc2 * ai2 + ds2 * ar2;
- ar2 = ar2h;
- long idx5 = j * idl1;
- long idx6 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx7 = in_off + ik;
- long idx8 = out_off + ik;
- in.setDouble(idx7 + idx1, in.getDouble(idx7 + idx1) + ar2 * out.getDouble(idx8 + idx5));
- in.setDouble(idx7 + idx2, in.getDouble(idx7 + idx2) + ai2 * out.getDouble(idx8 + idx6));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idx1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx2 = out_off + ik;
- out.setDouble(idx2, out.getDouble(idx2) + out.getDouble(idx2 + idx1));
- }
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long oidx1 = out_off + idx3;
- long iidx1 = in_off + idx3 + idx1;
- long iidx2 = in_off + idx3 + idx2;
- double i1r = in.getDouble(iidx1);
- double i2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1 + idx1, i1r - i2r);
- out.setDouble(oidx1 + idx2, i1r + i2r);
- }
- }
-
- if (ido == 1) {
- return;
- }
- if (nbd >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx4 = out_off + i;
- long idx5 = in_off + i;
- long oidx1 = idx4 + idx3 + idx1;
- long oidx2 = idx4 + idx3 + idx2;
- long iidx1 = idx5 + idx3 + idx1;
- long iidx2 = idx5 + idx3 + idx2;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1 - 1, i1i - i2r);
- out.setDouble(oidx2 - 1, i1i + i2r);
- out.setDouble(oidx1, i1r + i2i);
- out.setDouble(oidx2, i1r - i2i);
- }
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * l1 * ido;
- long idx2 = jc * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- long idx4 = out_off + i;
- long idx5 = in_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long oidx1 = idx4 + idx3 + idx1;
- long oidx2 = idx4 + idx3 + idx2;
- long iidx1 = idx5 + idx3 + idx1;
- long iidx2 = idx5 + idx3 + idx2;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
-
- out.setDouble(oidx1 - 1, i1i - i2r);
- out.setDouble(oidx2 - 1, i1i + i2r);
- out.setDouble(oidx1, i1r + i2i);
- out.setDouble(oidx2, i1r - i2i);
- }
- }
- }
- }
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- for (long j = 1; j < ip; j++) {
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido + idx1;
- in.setDouble(in_off + idx2, out.getDouble(out_off + idx2));
- }
- }
- if (nbd <= l1) {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- idij = is - 1;
- long idx1 = j * l1 * ido;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getDouble(idx2 - 1);
- w1i = wtable_rl.getDouble(idx2);
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido + idx1;
- long iidx1 = idx4 + idx3;
- long oidx1 = idx5 + idx3;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
-
- in.setDouble(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setDouble(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- } else {
- is = -ido;
- for (long j = 1; j < ip; j++) {
- is += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = is - 1;
- long idx3 = k * ido + idx1;
- for (long i = 2; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1;
- w1r = wtable_rl.getDouble(idx2 - 1);
- w1i = wtable_rl.getDouble(idx2);
- long idx4 = in_off + i;
- long idx5 = out_off + i;
- long iidx1 = idx4 + idx3;
- long oidx1 = idx5 + idx3;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
-
- in.setDouble(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setDouble(iidx1, w1r * o1r + w1i * o1i);
-
- }
- }
- }
- }
- }
-
- /*---------------------------------------------------------
- cfftf1: further processing of Complex forward FFT
- --------------------------------------------------------*/
- void cfftf(double a[], int offa, int isign) {
- int idot;
- int l1, l2;
- int na, nf, ipll, iw, ido, idl1;
- int[] nac = new int[1];
- final int twon = 2 * n;
-
- int iw1, iw2;
- double[] ch = new double[twon];
-
- iw1 = twon;
- iw2 = 4 * n;
- nac[0] = 0;
- nf = (int) wtable[1 + iw2];
- na = 0;
- l1 = 1;
- iw = iw1;
- for (int k1 = 2; k1 <= nf + 1; k1++) {
- ipll = (int) wtable[k1 + iw2];
- l2 = ipll * l1;
- ido = n / l2;
- idot = ido + ido;
- idl1 = idot * l1;
- switch (ipll) {
- case 4:
- if (na == 0) {
- passf4(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf4(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 2:
- if (na == 0) {
- passf2(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf2(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- passf3(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf3(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- passf5(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf5(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
- } else {
- passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
- }
- if (nac[0] != 0) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * idot;
- }
- if (na == 0) {
- return;
- }
- System.arraycopy(ch, 0, a, offa, twon);
-
- }
-
- /*---------------------------------------------------------
- cfftf1: further processing of Complex forward FFT
- --------------------------------------------------------*/
- void cfftf(DoubleLargeArray a, long offa, int isign) {
- long idot;
- long l1, l2;
- long na, nf, iw, ido, idl1;
- int[] nac = new int[1];
- final long twon = 2 * nl;
- int ipll;
-
- long iw1, iw2;
- DoubleLargeArray ch = new DoubleLargeArray(twon, false);
-
- iw1 = twon;
- iw2 = 4 * nl;
- nac[0] = 0;
- nf = (long) wtablel.getDouble(1 + iw2);
- na = 0;
- l1 = 1;
- iw = iw1;
- for (long k1 = 2; k1 <= nf + 1; k1++) {
- ipll = (int) wtablel.getDouble(k1 + iw2);
- l2 = ipll * l1;
- ido = nl / l2;
- idot = ido + ido;
- idl1 = idot * l1;
- switch (ipll) {
- case 4:
- if (na == 0) {
- passf4(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf4(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 2:
- if (na == 0) {
- passf2(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf2(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 3:
- if (na == 0) {
- passf3(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf3(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- case 5:
- if (na == 0) {
- passf5(idot, l1, a, offa, ch, 0, iw, isign);
- } else {
- passf5(idot, l1, ch, 0, a, offa, iw, isign);
- }
- na = 1 - na;
- break;
- default:
- if (na == 0) {
- passfg(nac, idot, ipll, l1, idl1, a, offa, ch, 0, iw, isign);
- } else {
- passfg(nac, idot, ipll, l1, idl1, ch, 0, a, offa, iw, isign);
- }
- if (nac[0] != 0) {
- na = 1 - na;
- }
- break;
- }
- l1 = l2;
- iw += (ipll - 1) * idot;
- }
- if (na == 0) {
- return;
- }
- Utilities.arraycopy(ch, 0, a, offa, twon);
-
- }
-
- /*----------------------------------------------------------------------
- passf2: Complex FFT's forward/backward processing of factor 2;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf2(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
- double t1i, t1r;
- int iw1;
- iw1 = offset;
- int idx = ido * l1;
- if (ido <= 2) {
- for (int k = 0; k < l1; k++) {
- int idx0 = k * ido;
- int iidx1 = in_off + 2 * idx0;
- int iidx2 = iidx1 + ido;
- double a1r = in[iidx1];
- double a1i = in[iidx1 + 1];
- double a2r = in[iidx2];
- double a2i = in[iidx2 + 1];
-
- int oidx1 = out_off + idx0;
- int oidx2 = oidx1 + idx;
- out[oidx1] = a1r + a2r;
- out[oidx1 + 1] = a1i + a2i;
- out[oidx2] = a1r - a2r;
- out[oidx2 + 1] = a1i - a2i;
- }
- } else {
- for (int k = 0; k < l1; k++) {
- for (int i = 0; i < ido - 1; i += 2) {
- int idx0 = k * ido;
- int iidx1 = in_off + i + 2 * idx0;
- int iidx2 = iidx1 + ido;
- double i1r = in[iidx1];
- double i1i = in[iidx1 + 1];
- double i2r = in[iidx2];
- double i2i = in[iidx2 + 1];
-
- int widx1 = i + iw1;
- double w1r = wtable[widx1];
- double w1i = isign * wtable[widx1 + 1];
-
- t1r = i1r - i2r;
- t1i = i1i - i2i;
-
- int oidx1 = out_off + i + idx0;
- int oidx2 = oidx1 + idx;
- out[oidx1] = i1r + i2r;
- out[oidx1 + 1] = i1i + i2i;
- out[oidx2] = w1r * t1r - w1i * t1i;
- out[oidx2 + 1] = w1r * t1i + w1i * t1r;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf2: Complex FFT's forward/backward processing of factor 2;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf2(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset, final long isign) {
- double t1i, t1r;
- long iw1;
- iw1 = offset;
- long idx = ido * l1;
- if (ido <= 2) {
- for (long k = 0; k < l1; k++) {
- long idx0 = k * ido;
- long iidx1 = in_off + 2 * idx0;
- long iidx2 = iidx1 + ido;
- double a1r = in.getDouble(iidx1);
- double a1i = in.getDouble(iidx1 + 1);
- double a2r = in.getDouble(iidx2);
- double a2i = in.getDouble(iidx2 + 1);
-
- long oidx1 = out_off + idx0;
- long oidx2 = oidx1 + idx;
- out.setDouble(oidx1, a1r + a2r);
- out.setDouble(oidx1 + 1, a1i + a2i);
- out.setDouble(oidx2, a1r - a2r);
- out.setDouble(oidx2 + 1, a1i - a2i);
- }
- } else {
- for (long k = 0; k < l1; k++) {
- for (long i = 0; i < ido - 1; i += 2) {
- long idx0 = k * ido;
- long iidx1 = in_off + i + 2 * idx0;
- long iidx2 = iidx1 + ido;
- double i1r = in.getDouble(iidx1);
- double i1i = in.getDouble(iidx1 + 1);
- double i2r = in.getDouble(iidx2);
- double i2i = in.getDouble(iidx2 + 1);
-
- long widx1 = i + iw1;
- double w1r = wtablel.getDouble(widx1);
- double w1i = isign * wtablel.getDouble(widx1 + 1);
-
- t1r = i1r - i2r;
- t1i = i1i - i2i;
-
- long oidx1 = out_off + i + idx0;
- long oidx2 = oidx1 + idx;
- out.setDouble(oidx1, i1r + i2r);
- out.setDouble(oidx1 + 1, i1i + i2i);
- out.setDouble(oidx2, w1r * t1r - w1i * t1i);
- out.setDouble(oidx2 + 1, w1r * t1i + w1i * t1r);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf3: Complex FFT's forward/backward processing of factor 3;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf3(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
- int iw1, iw2;
-
- iw1 = offset;
- iw2 = iw1 + ido;
-
- final int idxt = l1 * ido;
-
- if (ido == 2) {
- for (int k = 1; k <= l1; k++) {
- int iidx1 = in_off + (3 * k - 2) * ido;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- double i1r = in[iidx1];
- double i1i = in[iidx1 + 1];
- double i2r = in[iidx2];
- double i2i = in[iidx2 + 1];
- double i3r = in[iidx3];
- double i3i = in[iidx3 + 1];
-
- tr2 = i1r + i2r;
- cr2 = i3r + taur * tr2;
- ti2 = i1i + i2i;
- ci2 = i3i + taur * ti2;
- cr3 = isign * taui * (i1r - i2r);
- ci3 = isign * taui * (i1i - i2i);
-
- int oidx1 = out_off + (k - 1) * ido;
- int oidx2 = oidx1 + idxt;
- int oidx3 = oidx2 + idxt;
- out[oidx1] = in[iidx3] + tr2;
- out[oidx1 + 1] = i3i + ti2;
- out[oidx2] = cr2 - ci3;
- out[oidx2 + 1] = ci2 + cr3;
- out[oidx3] = cr2 + ci3;
- out[oidx3 + 1] = ci2 - cr3;
- }
- } else {
- for (int k = 1; k <= l1; k++) {
- int idx1 = in_off + (3 * k - 2) * ido;
- int idx2 = out_off + (k - 1) * ido;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- double a1r = in[iidx1];
- double a1i = in[iidx1 + 1];
- double a2r = in[iidx2];
- double a2i = in[iidx2 + 1];
- double a3r = in[iidx3];
- double a3i = in[iidx3 + 1];
-
- tr2 = a1r + a2r;
- cr2 = a3r + taur * tr2;
- ti2 = a1i + a2i;
- ci2 = a3i + taur * ti2;
- cr3 = isign * taui * (a1r - a2r);
- ci3 = isign * taui * (a1i - a2i);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- double w1r = wtable[widx1];
- double w1i = isign * wtable[widx1 + 1];
- double w2r = wtable[widx2];
- double w2i = isign * wtable[widx2 + 1];
-
- int oidx1 = i + idx2;
- int oidx2 = oidx1 + idxt;
- int oidx3 = oidx2 + idxt;
- out[oidx1] = a3r + tr2;
- out[oidx1 + 1] = a3i + ti2;
- out[oidx2] = w1r * dr2 - w1i * di2;
- out[oidx2 + 1] = w1r * di2 + w1i * dr2;
- out[oidx3] = w2r * dr3 - w2i * di3;
- out[oidx3 + 1] = w2r * di3 + w2i * dr3;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf3: Complex FFT's forward/backward processing of factor 3;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf3(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset, final long isign) {
- final double taur = -0.5;
- final double taui = 0.866025403784438707610604524234076962;
- double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
- long iw1, iw2;
-
- iw1 = offset;
- iw2 = iw1 + ido;
-
- final long idxt = l1 * ido;
-
- if (ido == 2) {
- for (long k = 1; k <= l1; k++) {
- long iidx1 = in_off + (3 * k - 2) * ido;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- double i1r = in.getDouble(iidx1);
- double i1i = in.getDouble(iidx1 + 1);
- double i2r = in.getDouble(iidx2);
- double i2i = in.getDouble(iidx2 + 1);
- double i3r = in.getDouble(iidx3);
- double i3i = in.getDouble(iidx3 + 1);
-
- tr2 = i1r + i2r;
- cr2 = i3r + taur * tr2;
- ti2 = i1i + i2i;
- ci2 = i3i + taur * ti2;
- cr3 = isign * taui * (i1r - i2r);
- ci3 = isign * taui * (i1i - i2i);
-
- long oidx1 = out_off + (k - 1) * ido;
- long oidx2 = oidx1 + idxt;
- long oidx3 = oidx2 + idxt;
- out.setDouble(oidx1, in.getDouble(iidx3) + tr2);
- out.setDouble(oidx1 + 1, i3i + ti2);
- out.setDouble(oidx2, cr2 - ci3);
- out.setDouble(oidx2 + 1, ci2 + cr3);
- out.setDouble(oidx3, cr2 + ci3);
- out.setDouble(oidx3 + 1, ci2 - cr3);
- }
- } else {
- for (long k = 1; k <= l1; k++) {
- long idx1 = in_off + (3 * k - 2) * ido;
- long idx2 = out_off + (k - 1) * ido;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- double a1r = in.getDouble(iidx1);
- double a1i = in.getDouble(iidx1 + 1);
- double a2r = in.getDouble(iidx2);
- double a2i = in.getDouble(iidx2 + 1);
- double a3r = in.getDouble(iidx3);
- double a3i = in.getDouble(iidx3 + 1);
-
- tr2 = a1r + a2r;
- cr2 = a3r + taur * tr2;
- ti2 = a1i + a2i;
- ci2 = a3i + taur * ti2;
- cr3 = isign * taui * (a1r - a2r);
- ci3 = isign * taui * (a1i - a2i);
- dr2 = cr2 - ci3;
- dr3 = cr2 + ci3;
- di2 = ci2 + cr3;
- di3 = ci2 - cr3;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- double w1r = wtablel.getDouble(widx1);
- double w1i = isign * wtablel.getDouble(widx1 + 1);
- double w2r = wtablel.getDouble(widx2);
- double w2i = isign * wtablel.getDouble(widx2 + 1);
-
- long oidx1 = i + idx2;
- long oidx2 = oidx1 + idxt;
- long oidx3 = oidx2 + idxt;
- out.setDouble(oidx1, a3r + tr2);
- out.setDouble(oidx1 + 1, a3i + ti2);
- out.setDouble(oidx2, w1r * dr2 - w1i * di2);
- out.setDouble(oidx2 + 1, w1r * di2 + w1i * dr2);
- out.setDouble(oidx3, w2r * dr3 - w2i * di3);
- out.setDouble(oidx3 + 1, w2r * di3 + w2i * dr3);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf4: Complex FFT's forward/backward processing of factor 4;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf4(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
- double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
- int iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- int idx0 = l1 * ido;
- if (ido == 2) {
- for (int k = 0; k < l1; k++) {
- int idxt1 = k * ido;
- int iidx1 = in_off + 4 * idxt1 + 1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx2 + ido;
- int iidx4 = iidx3 + ido;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- tr4 = i4r - i2r;
- ti3 = i2r + i4r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
-
- int oidx1 = out_off + idxt1;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- out[oidx1] = tr2 + tr3;
- out[oidx1 + 1] = ti2 + ti3;
- out[oidx2] = tr1 + isign * tr4;
- out[oidx2 + 1] = ti1 + isign * ti4;
- out[oidx3] = tr2 - tr3;
- out[oidx3 + 1] = ti2 - ti3;
- out[oidx4] = tr1 - isign * tr4;
- out[oidx4 + 1] = ti1 - isign * ti4;
- }
- } else {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = in_off + 1 + 4 * idx1;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx2;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx2 + ido;
- int iidx4 = iidx3 + ido;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- ti3 = i2r + i4r;
- tr4 = i4r - i2r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 + isign * tr4;
- cr4 = tr1 - isign * tr4;
- ci2 = ti1 + isign * ti4;
- ci4 = ti1 - isign * ti4;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- int widx3 = i + iw3;
- double w1r = wtable[widx1];
- double w1i = isign * wtable[widx1 + 1];
- double w2r = wtable[widx2];
- double w2i = isign * wtable[widx2 + 1];
- double w3r = wtable[widx3];
- double w3i = isign * wtable[widx3 + 1];
-
- int oidx1 = out_off + i + idx1;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- out[oidx1] = tr2 + tr3;
- out[oidx1 + 1] = ti2 + ti3;
- out[oidx2] = w1r * cr2 - w1i * ci2;
- out[oidx2 + 1] = w1r * ci2 + w1i * cr2;
- out[oidx3] = w2r * cr3 - w2i * ci3;
- out[oidx3 + 1] = w2r * ci3 + w2i * cr3;
- out[oidx4] = w3r * cr4 - w3i * ci4;
- out[oidx4 + 1] = w3r * ci4 + w3i * cr4;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf4: Complex FFT's forward/backward processing of factor 4;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf4(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset, final int isign) {
- double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
- long iw1, iw2, iw3;
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
-
- long idx0 = l1 * ido;
- if (ido == 2) {
- for (long k = 0; k < l1; k++) {
- long idxt1 = k * ido;
- long iidx1 = in_off + 4 * idxt1 + 1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx2 + ido;
- long iidx4 = iidx3 + ido;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- tr4 = i4r - i2r;
- ti3 = i2r + i4r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
-
- long oidx1 = out_off + idxt1;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- out.setDouble(oidx1, tr2 + tr3);
- out.setDouble(oidx1 + 1, ti2 + ti3);
- out.setDouble(oidx2, tr1 + isign * tr4);
- out.setDouble(oidx2 + 1, ti1 + isign * ti4);
- out.setDouble(oidx3, tr2 - tr3);
- out.setDouble(oidx3 + 1, ti2 - ti3);
- out.setDouble(oidx4, tr1 - isign * tr4);
- out.setDouble(oidx4 + 1, ti1 - isign * ti4);
- }
- } else {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = in_off + 1 + 4 * idx1;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx2;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx2 + ido;
- long iidx4 = iidx3 + ido;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
-
- ti1 = i1r - i3r;
- ti2 = i1r + i3r;
- ti3 = i2r + i4r;
- tr4 = i4r - i2r;
- tr1 = i1i - i3i;
- tr2 = i1i + i3i;
- ti4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr3 = tr2 - tr3;
- ci3 = ti2 - ti3;
- cr2 = tr1 + isign * tr4;
- cr4 = tr1 - isign * tr4;
- ci2 = ti1 + isign * ti4;
- ci4 = ti1 - isign * ti4;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- long widx3 = i + iw3;
- double w1r = wtablel.getDouble(widx1);
- double w1i = isign * wtablel.getDouble(widx1 + 1);
- double w2r = wtablel.getDouble(widx2);
- double w2i = isign * wtablel.getDouble(widx2 + 1);
- double w3r = wtablel.getDouble(widx3);
- double w3i = isign * wtablel.getDouble(widx3 + 1);
-
- long oidx1 = out_off + i + idx1;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- out.setDouble(oidx1, tr2 + tr3);
- out.setDouble(oidx1 + 1, ti2 + ti3);
- out.setDouble(oidx2, w1r * cr2 - w1i * ci2);
- out.setDouble(oidx2 + 1, w1r * ci2 + w1i * cr2);
- out.setDouble(oidx3, w2r * cr3 - w2i * ci3);
- out.setDouble(oidx3 + 1, w2r * ci3 + w2i * cr3);
- out.setDouble(oidx4, w3r * cr4 - w3i * ci4);
- out.setDouble(oidx4 + 1, w3r * ci4 + w3i * cr4);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf5: Complex FFT's forward/backward processing of factor 5;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf5(final int ido, final int l1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) /* isign==-1 for forward transform and+1 for backward transform */ {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
- int iw1, iw2, iw3, iw4;
-
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- int idx0 = l1 * ido;
-
- if (ido == 2) {
- for (int k = 1; k <= l1; ++k) {
- int iidx1 = in_off + (5 * k - 4) * ido + 1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- int iidx4 = iidx2 + ido;
- int iidx5 = iidx4 + ido;
-
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
- double i5i = in[iidx5 - 1];
- double i5r = in[iidx5];
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
-
- int oidx1 = out_off + (k - 1) * ido;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- int oidx5 = oidx4 + idx0;
- out[oidx1] = i3i + tr2 + tr3;
- out[oidx1 + 1] = i3r + ti2 + ti3;
- out[oidx2] = cr2 - ci5;
- out[oidx2 + 1] = ci2 + cr5;
- out[oidx3] = cr3 - ci4;
- out[oidx3 + 1] = ci3 + cr4;
- out[oidx4] = cr3 + ci4;
- out[oidx4 + 1] = ci3 - cr4;
- out[oidx5] = cr2 + ci5;
- out[oidx5 + 1] = ci2 - cr5;
- }
- } else {
- for (int k = 1; k <= l1; k++) {
- int idx1 = in_off + 1 + (k * 5 - 4) * ido;
- int idx2 = out_off + (k - 1) * ido;
- for (int i = 0; i < ido - 1; i += 2) {
- int iidx1 = i + idx1;
- int iidx2 = iidx1 + ido;
- int iidx3 = iidx1 - ido;
- int iidx4 = iidx2 + ido;
- int iidx5 = iidx4 + ido;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
- double i3i = in[iidx3 - 1];
- double i3r = in[iidx3];
- double i4i = in[iidx4 - 1];
- double i4r = in[iidx4];
- double i5i = in[iidx5 - 1];
- double i5r = in[iidx5];
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- int widx1 = i + iw1;
- int widx2 = i + iw2;
- int widx3 = i + iw3;
- int widx4 = i + iw4;
- double w1r = wtable[widx1];
- double w1i = isign * wtable[widx1 + 1];
- double w2r = wtable[widx2];
- double w2i = isign * wtable[widx2 + 1];
- double w3r = wtable[widx3];
- double w3i = isign * wtable[widx3 + 1];
- double w4r = wtable[widx4];
- double w4i = isign * wtable[widx4 + 1];
-
- int oidx1 = i + idx2;
- int oidx2 = oidx1 + idx0;
- int oidx3 = oidx2 + idx0;
- int oidx4 = oidx3 + idx0;
- int oidx5 = oidx4 + idx0;
- out[oidx1] = i3i + tr2 + tr3;
- out[oidx1 + 1] = i3r + ti2 + ti3;
- out[oidx2] = w1r * dr2 - w1i * di2;
- out[oidx2 + 1] = w1r * di2 + w1i * dr2;
- out[oidx3] = w2r * dr3 - w2i * di3;
- out[oidx3 + 1] = w2r * di3 + w2i * dr3;
- out[oidx4] = w3r * dr4 - w3i * di4;
- out[oidx4 + 1] = w3r * di4 + w3i * dr4;
- out[oidx5] = w4r * dr5 - w4i * di5;
- out[oidx5 + 1] = w4r * di5 + w4i * dr5;
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passf5: Complex FFT's forward/backward processing of factor 5;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passf5(final long ido, final long l1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset, final long isign) /* isign==-1 for forward transform and+1 for backward transform */ {
- final double tr11 = 0.309016994374947451262869435595348477;
- final double ti11 = 0.951056516295153531181938433292089030;
- final double tr12 = -0.809016994374947340240566973079694435;
- final double ti12 = 0.587785252292473248125759255344746634;
- double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4, ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
- long iw1, iw2, iw3, iw4;
-
- iw1 = offset;
- iw2 = iw1 + ido;
- iw3 = iw2 + ido;
- iw4 = iw3 + ido;
-
- long idx0 = l1 * ido;
-
- if (ido == 2) {
- for (long k = 1; k <= l1; ++k) {
- long iidx1 = in_off + (5 * k - 4) * ido + 1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- long iidx4 = iidx2 + ido;
- long iidx5 = iidx4 + ido;
-
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
- double i5i = in.getDouble(iidx5 - 1);
- double i5r = in.getDouble(iidx5);
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
-
- long oidx1 = out_off + (k - 1) * ido;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- long oidx5 = oidx4 + idx0;
- out.setDouble(oidx1, i3i + tr2 + tr3);
- out.setDouble(oidx1 + 1, i3r + ti2 + ti3);
- out.setDouble(oidx2, cr2 - ci5);
- out.setDouble(oidx2 + 1, ci2 + cr5);
- out.setDouble(oidx3, cr3 - ci4);
- out.setDouble(oidx3 + 1, ci3 + cr4);
- out.setDouble(oidx4, cr3 + ci4);
- out.setDouble(oidx4 + 1, ci3 - cr4);
- out.setDouble(oidx5, cr2 + ci5);
- out.setDouble(oidx5 + 1, ci2 - cr5);
- }
- } else {
- for (long k = 1; k <= l1; k++) {
- long idx1 = in_off + 1 + (k * 5 - 4) * ido;
- long idx2 = out_off + (k - 1) * ido;
- for (long i = 0; i < ido - 1; i += 2) {
- long iidx1 = i + idx1;
- long iidx2 = iidx1 + ido;
- long iidx3 = iidx1 - ido;
- long iidx4 = iidx2 + ido;
- long iidx5 = iidx4 + ido;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
- double i3i = in.getDouble(iidx3 - 1);
- double i3r = in.getDouble(iidx3);
- double i4i = in.getDouble(iidx4 - 1);
- double i4r = in.getDouble(iidx4);
- double i5i = in.getDouble(iidx5 - 1);
- double i5r = in.getDouble(iidx5);
-
- ti5 = i1r - i5r;
- ti2 = i1r + i5r;
- ti4 = i2r - i4r;
- ti3 = i2r + i4r;
- tr5 = i1i - i5i;
- tr2 = i1i + i5i;
- tr4 = i2i - i4i;
- tr3 = i2i + i4i;
- cr2 = i3i + tr11 * tr2 + tr12 * tr3;
- ci2 = i3r + tr11 * ti2 + tr12 * ti3;
- cr3 = i3i + tr12 * tr2 + tr11 * tr3;
- ci3 = i3r + tr12 * ti2 + tr11 * ti3;
- cr5 = isign * (ti11 * tr5 + ti12 * tr4);
- ci5 = isign * (ti11 * ti5 + ti12 * ti4);
- cr4 = isign * (ti12 * tr5 - ti11 * tr4);
- ci4 = isign * (ti12 * ti5 - ti11 * ti4);
- dr3 = cr3 - ci4;
- dr4 = cr3 + ci4;
- di3 = ci3 + cr4;
- di4 = ci3 - cr4;
- dr5 = cr2 + ci5;
- dr2 = cr2 - ci5;
- di5 = ci2 - cr5;
- di2 = ci2 + cr5;
-
- long widx1 = i + iw1;
- long widx2 = i + iw2;
- long widx3 = i + iw3;
- long widx4 = i + iw4;
- double w1r = wtablel.getDouble(widx1);
- double w1i = isign * wtablel.getDouble(widx1 + 1);
- double w2r = wtablel.getDouble(widx2);
- double w2i = isign * wtablel.getDouble(widx2 + 1);
- double w3r = wtablel.getDouble(widx3);
- double w3i = isign * wtablel.getDouble(widx3 + 1);
- double w4r = wtablel.getDouble(widx4);
- double w4i = isign * wtablel.getDouble(widx4 + 1);
-
- long oidx1 = i + idx2;
- long oidx2 = oidx1 + idx0;
- long oidx3 = oidx2 + idx0;
- long oidx4 = oidx3 + idx0;
- long oidx5 = oidx4 + idx0;
- out.setDouble(oidx1, i3i + tr2 + tr3);
- out.setDouble(oidx1 + 1, i3r + ti2 + ti3);
- out.setDouble(oidx2, w1r * dr2 - w1i * di2);
- out.setDouble(oidx2 + 1, w1r * di2 + w1i * dr2);
- out.setDouble(oidx3, w2r * dr3 - w2i * di3);
- out.setDouble(oidx3 + 1, w2r * di3 + w2i * dr3);
- out.setDouble(oidx4, w3r * dr4 - w3i * di4);
- out.setDouble(oidx4 + 1, w3r * di4 + w3i * dr4);
- out.setDouble(oidx5, w4r * dr5 - w4i * di5);
- out.setDouble(oidx5 + 1, w4r * di5 + w4i * dr5);
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passfg: Complex FFT's forward/backward processing of general factor;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passfg(final int nac[], final int ido, final int ip, final int l1, final int idl1, final double in[], final int in_off, final double out[], final int out_off, final int offset, final int isign) {
- int idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
- double w1r, w1i, w2i, w2r;
- int iw1;
-
- iw1 = offset;
- idot = ido / 2;
- ipph = (ip + 1) / 2;
- idp = ip * ido;
- if (ido >= l1) {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * ido;
- int idx2 = jc * ido;
- for (int k = 0; k < l1; k++) {
- int idx3 = k * ido;
- int idx4 = idx3 + idx1 * l1;
- int idx5 = idx3 + idx2 * l1;
- int idx6 = idx3 * ip;
- for (int i = 0; i < ido; i++) {
- int oidx1 = out_off + i;
- double i1r = in[in_off + i + idx1 + idx6];
- double i2r = in[in_off + i + idx2 + idx6];
- out[oidx1 + idx4] = i1r + i2r;
- out[oidx1 + idx5] = i1r - i2r;
- }
- }
- }
- for (int k = 0; k < l1; k++) {
- int idxt1 = k * ido;
- int idxt2 = idxt1 * ip;
- for (int i = 0; i < ido; i++) {
- out[out_off + i + idxt1] = in[in_off + i + idxt2];
- }
- }
- } else {
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idxt1 = j * l1 * ido;
- int idxt2 = jc * l1 * ido;
- int idxt3 = j * ido;
- int idxt4 = jc * ido;
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- int idx2 = idx1 * ip;
- int idx3 = out_off + i;
- int idx4 = in_off + i;
- double i1r = in[idx4 + idxt3 + idx2];
- double i2r = in[idx4 + idxt4 + idx2];
- out[idx3 + idx1 + idxt1] = i1r + i2r;
- out[idx3 + idx1 + idxt2] = i1r - i2r;
- }
- }
- }
- for (int i = 0; i < ido; i++) {
- for (int k = 0; k < l1; k++) {
- int idx1 = k * ido;
- out[out_off + i + idx1] = in[in_off + i + idx1 * ip];
- }
- }
- }
-
- idl = 2 - ido;
- inc = 0;
- int idxt0 = (ip - 1) * idl1;
- for (l = 1; l < ipph; l++) {
- lc = ip - l;
- idl += ido;
- int idxt1 = l * idl1;
- int idxt2 = lc * idl1;
- int idxt3 = idl + iw1;
- w1r = wtable[idxt3 - 2];
- w1i = isign * wtable[idxt3 - 1];
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = in_off + ik;
- int idx2 = out_off + ik;
- in[idx1 + idxt1] = out[idx2] + w1r * out[idx2 + idl1];
- in[idx1 + idxt2] = w1i * out[idx2 + idxt0];
- }
- idlj = idl;
- inc += ido;
- for (int j = 2; j < ipph; j++) {
- jc = ip - j;
- idlj += inc;
- if (idlj > idp) {
- idlj -= idp;
- }
- int idxt4 = idlj + iw1;
- w2r = wtable[idxt4 - 2];
- w2i = isign * wtable[idxt4 - 1];
- int idxt5 = j * idl1;
- int idxt6 = jc * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = in_off + ik;
- int idx2 = out_off + ik;
- in[idx1 + idxt1] += w2r * out[idx2 + idxt5];
- in[idx1 + idxt2] += w2i * out[idx2 + idxt6];
- }
- }
- }
- for (int j = 1; j < ipph; j++) {
- int idxt1 = j * idl1;
- for (int ik = 0; ik < idl1; ik++) {
- int idx1 = out_off + ik;
- out[idx1] += out[idx1 + idxt1];
- }
- }
- for (int j = 1; j < ipph; j++) {
- jc = ip - j;
- int idx1 = j * idl1;
- int idx2 = jc * idl1;
- for (int ik = 1; ik < idl1; ik += 2) {
- int idx3 = out_off + ik;
- int idx4 = in_off + ik;
- int iidx1 = idx4 + idx1;
- int iidx2 = idx4 + idx2;
- double i1i = in[iidx1 - 1];
- double i1r = in[iidx1];
- double i2i = in[iidx2 - 1];
- double i2r = in[iidx2];
-
- int oidx1 = idx3 + idx1;
- int oidx2 = idx3 + idx2;
- out[oidx1 - 1] = i1i - i2r;
- out[oidx2 - 1] = i1i + i2r;
- out[oidx1] = i1r + i2i;
- out[oidx2] = i1r - i2i;
- }
- }
- nac[0] = 1;
- if (ido == 2) {
- return;
- }
- nac[0] = 0;
- System.arraycopy(out, out_off, in, in_off, idl1);
- int idx0 = l1 * ido;
- for (int j = 1; j < ip; j++) {
- int idx1 = j * idx0;
- for (int k = 0; k < l1; k++) {
- int idx2 = k * ido;
- int oidx1 = out_off + idx2 + idx1;
- int iidx1 = in_off + idx2 + idx1;
- in[iidx1] = out[oidx1];
- in[iidx1 + 1] = out[oidx1 + 1];
- }
- }
- if (idot <= l1) {
- idij = 0;
- for (int j = 1; j < ip; j++) {
- idij += 2;
- int idx1 = j * l1 * ido;
- for (int i = 3; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij + iw1 - 1;
- w1r = wtable[idx2 - 1];
- w1i = isign * wtable[idx2];
- int idx3 = in_off + i;
- int idx4 = out_off + i;
- for (int k = 0; k < l1; k++) {
- int idx5 = k * ido + idx1;
- int iidx1 = idx3 + idx5;
- int oidx1 = idx4 + idx5;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- } else {
- idj = 2 - ido;
- for (int j = 1; j < ip; j++) {
- idj += ido;
- int idx1 = j * l1 * ido;
- for (int k = 0; k < l1; k++) {
- idij = idj;
- int idx3 = k * ido + idx1;
- for (int i = 3; i < ido; i += 2) {
- idij += 2;
- int idx2 = idij - 1 + iw1;
- w1r = wtable[idx2 - 1];
- w1i = isign * wtable[idx2];
- int iidx1 = in_off + i + idx3;
- int oidx1 = out_off + i + idx3;
- double o1i = out[oidx1 - 1];
- double o1r = out[oidx1];
- in[iidx1 - 1] = w1r * o1i - w1i * o1r;
- in[iidx1] = w1r * o1r + w1i * o1i;
- }
- }
- }
- }
- }
-
- /*----------------------------------------------------------------------
- passfg: Complex FFT's forward/backward processing of general factor;
- isign is +1 for backward and -1 for forward transforms
- ----------------------------------------------------------------------*/
- void passfg(final int nac[], final long ido, final long ip, final long l1, final long idl1, final DoubleLargeArray in, final long in_off, final DoubleLargeArray out, final long out_off, final long offset, final long isign) {
- long idij, idlj, idot, ipph, l, jc, lc, idj, idl, inc, idp;
- double w1r, w1i, w2i, w2r;
- long iw1;
-
- iw1 = offset;
- idot = ido / 2;
- ipph = (ip + 1) / 2;
- idp = ip * ido;
- if (ido >= l1) {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * ido;
- long idx2 = jc * ido;
- for (long k = 0; k < l1; k++) {
- long idx3 = k * ido;
- long idx4 = idx3 + idx1 * l1;
- long idx5 = idx3 + idx2 * l1;
- long idx6 = idx3 * ip;
- for (long i = 0; i < ido; i++) {
- long oidx1 = out_off + i;
- double i1r = in.getDouble(in_off + i + idx1 + idx6);
- double i2r = in.getDouble(in_off + i + idx2 + idx6);
- out.setDouble(oidx1 + idx4, i1r + i2r);
- out.setDouble(oidx1 + idx5, i1r - i2r);
- }
- }
- }
- for (long k = 0; k < l1; k++) {
- long idxt1 = k * ido;
- long idxt2 = idxt1 * ip;
- for (long i = 0; i < ido; i++) {
- out.setDouble(out_off + i + idxt1, in.getDouble(in_off + i + idxt2));
- }
- }
- } else {
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idxt1 = j * l1 * ido;
- long idxt2 = jc * l1 * ido;
- long idxt3 = j * ido;
- long idxt4 = jc * ido;
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- long idx2 = idx1 * ip;
- long idx3 = out_off + i;
- long idx4 = in_off + i;
- double i1r = in.getDouble(idx4 + idxt3 + idx2);
- double i2r = in.getDouble(idx4 + idxt4 + idx2);
- out.setDouble(idx3 + idx1 + idxt1, i1r + i2r);
- out.setDouble(idx3 + idx1 + idxt2, i1r - i2r);
- }
- }
- }
- for (long i = 0; i < ido; i++) {
- for (long k = 0; k < l1; k++) {
- long idx1 = k * ido;
- out.setDouble(out_off + i + idx1, in.getDouble(in_off + i + idx1 * ip));
- }
- }
- }
-
- idl = 2 - ido;
- inc = 0;
- long idxt0 = (ip - 1) * idl1;
- for (l = 1; l < ipph; l++) {
- lc = ip - l;
- idl += ido;
- long idxt1 = l * idl1;
- long idxt2 = lc * idl1;
- long idxt3 = idl + iw1;
- w1r = wtablel.getDouble(idxt3 - 2);
- w1i = isign * wtablel.getDouble(idxt3 - 1);
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = in_off + ik;
- long idx2 = out_off + ik;
- in.setDouble(idx1 + idxt1, out.getDouble(idx2) + w1r * out.getDouble(idx2 + idl1));
- in.setDouble(idx1 + idxt2, w1i * out.getDouble(idx2 + idxt0));
- }
- idlj = idl;
- inc += ido;
- for (long j = 2; j < ipph; j++) {
- jc = ip - j;
- idlj += inc;
- if (idlj > idp) {
- idlj -= idp;
- }
- long idxt4 = idlj + iw1;
- w2r = wtablel.getDouble(idxt4 - 2);
- w2i = isign * wtablel.getDouble(idxt4 - 1);
- long idxt5 = j * idl1;
- long idxt6 = jc * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = in_off + ik;
- long idx2 = out_off + ik;
- in.setDouble(idx1 + idxt1, in.getDouble(idx1 + idxt1) + w2r * out.getDouble(idx2 + idxt5));
- in.setDouble(idx1 + idxt2, in.getDouble(idx1 + idxt2) + w2i * out.getDouble(idx2 + idxt6));
- }
- }
- }
- for (long j = 1; j < ipph; j++) {
- long idxt1 = j * idl1;
- for (long ik = 0; ik < idl1; ik++) {
- long idx1 = out_off + ik;
- out.setDouble(idx1, out.getDouble(idx1) + out.getDouble(idx1 + idxt1));
- }
- }
- for (long j = 1; j < ipph; j++) {
- jc = ip - j;
- long idx1 = j * idl1;
- long idx2 = jc * idl1;
- for (long ik = 1; ik < idl1; ik += 2) {
- long idx3 = out_off + ik;
- long idx4 = in_off + ik;
- long iidx1 = idx4 + idx1;
- long iidx2 = idx4 + idx2;
- double i1i = in.getDouble(iidx1 - 1);
- double i1r = in.getDouble(iidx1);
- double i2i = in.getDouble(iidx2 - 1);
- double i2r = in.getDouble(iidx2);
-
- long oidx1 = idx3 + idx1;
- long oidx2 = idx3 + idx2;
- out.setDouble(oidx1 - 1, i1i - i2r);
- out.setDouble(oidx2 - 1, i1i + i2r);
- out.setDouble(oidx1, i1r + i2i);
- out.setDouble(oidx2, i1r - i2i);
- }
- }
- nac[0] = 1;
- if (ido == 2) {
- return;
- }
- nac[0] = 0;
- Utilities.arraycopy(out, out_off, in, in_off, idl1);
- long idx0 = l1 * ido;
- for (long j = 1; j < ip; j++) {
- long idx1 = j * idx0;
- for (long k = 0; k < l1; k++) {
- long idx2 = k * ido;
- long oidx1 = out_off + idx2 + idx1;
- long iidx1 = in_off + idx2 + idx1;
- in.setDouble(iidx1, out.getDouble(oidx1));
- in.setDouble(iidx1 + 1, out.getDouble(oidx1 + 1));
- }
- }
- if (idot <= l1) {
- idij = 0;
- for (long j = 1; j < ip; j++) {
- idij += 2;
- long idx1 = j * l1 * ido;
- for (long i = 3; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij + iw1 - 1;
- w1r = wtablel.getDouble(idx2 - 1);
- w1i = isign * wtablel.getDouble(idx2);
- long idx3 = in_off + i;
- long idx4 = out_off + i;
- for (long k = 0; k < l1; k++) {
- long idx5 = k * ido + idx1;
- long iidx1 = idx3 + idx5;
- long oidx1 = idx4 + idx5;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- in.setDouble(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setDouble(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- } else {
- idj = 2 - ido;
- for (long j = 1; j < ip; j++) {
- idj += ido;
- long idx1 = j * l1 * ido;
- for (long k = 0; k < l1; k++) {
- idij = idj;
- long idx3 = k * ido + idx1;
- for (long i = 3; i < ido; i += 2) {
- idij += 2;
- long idx2 = idij - 1 + iw1;
- w1r = wtablel.getDouble(idx2 - 1);
- w1i = isign * wtablel.getDouble(idx2);
- long iidx1 = in_off + i + idx3;
- long oidx1 = out_off + i + idx3;
- double o1i = out.getDouble(oidx1 - 1);
- double o1r = out.getDouble(oidx1);
- in.setDouble(iidx1 - 1, w1r * o1i - w1i * o1r);
- in.setDouble(iidx1, w1r * o1r + w1i * o1i);
- }
- }
- }
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/DoubleFFT_2D.java b/src/main/java/org/jtransforms/fft/DoubleFFT_2D.java
deleted file mode 100644
index 866eb3b..0000000
--- a/src/main/java/org/jtransforms/fft/DoubleFFT_2D.java
+++ /dev/null
@@ -1,3940 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * Computes 2D Discrete Fourier Transform (DFT) of complex and real, double
- * precision data. The sizes of both dimensions can be arbitrary numbers. This
- * is a parallel implementation of split-radix and mixed-radix algorithms
- * optimized for SMP systems. a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two double values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - */ - public void complexForward(final double[] a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, r * columns); - } - cdft2d_sub(-1, a, true); - } - columns = columns / 2; - } else { - final int rowStride = 2 * columns; - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a, r * rowStride); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx0 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - temp[idx1] = a[idx2]; - temp[idx1 + 1] = a[idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - a[idx2] = temp[idx1]; - a[idx2 + 1] = temp[idx1 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, r * rowStride); - } - double[] temp = new double[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx0 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - temp[idx1] = a[idx2]; - temp[idx1 + 1] = a[idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx1 = 2 * r; - int idx2 = r * rowStride + idx0; - a[idx2] = temp[idx1]; - a[idx2 + 1] = temp[idx1 + 1]; - } - } - } - } - } - - /** - * Computes 2D forward DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two double values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - */ - public void complexForward(final DoubleLargeArray a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columnsl = 2 * columnsl; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, r * columnsl); - } - cdft2d_sub(-1, a, true); - } - columnsl = columnsl / 2; - } else { - final long rowStride = 2 * columnsl; - if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (long r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a, r * rowStride); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columnsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstColumn = l * p; - final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long c = firstColumn; c < lastColumn; c++) { - long idx0 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - temp.setDouble(idx1, a.getDouble(idx2)); - temp.setDouble(idx1 + 1, a.getDouble(idx2 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - a.setDouble(idx2, temp.getDouble(idx1)); - a.setDouble(idx2 + 1, temp.getDouble(idx1 + 1)); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (long r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, r * rowStride); - } - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long c = 0; c < columnsl; c++) { - long idx0 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - temp.setDouble(idx1, a.getDouble(idx2)); - temp.setDouble(idx1 + 1, a.getDouble(idx2 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx1 = 2 * r; - long idx2 = r * rowStride + idx0; - a.setDouble(idx2, temp.getDouble(idx1)); - a.setDouble(idx2 + 1, temp.getDouble(idx1 + 1)); - } - } - } - } - } - - /** - * Computes 2D forward DFT of complex data leaving the result in - *
a. The data is stored in 2D array. Complex data is
- * represented by 2 double values in sequence: the real and imaginary part,
- * i.e. the input array must be of size rows by 2*columns. The physical
- * layout of the input data has to be as follows:- * a[k1][2*k2] = Re[k1][k2], - * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - */ - public void complexForward(final double[][] a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, -1, a, true); - cdft2d_subth(-1, a, true); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[r]); - } - cdft2d_sub(-1, a, true); - } - columns = columns / 2; - } else { - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexForward(a[r]); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[r]); - } - double[] temp = new double[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two double values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - * @param scale - * if true then scaling is performed - * - */ - public void complexInverse(final double[] a, final boolean scale) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, r * columns, scale); - } - cdft2d_sub(1, a, scale); - } - columns = columns / 2; - } else { - final int rowspan = 2 * columns; - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - temp[idx2] = a[idx3]; - temp[idx2 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - a[idx3] = temp[idx2]; - a[idx3 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - double[] temp = new double[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - temp[idx2] = a[idx3]; - temp[idx2 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - int idx3 = r * rowspan + idx1; - a[idx3] = temp[idx2]; - a[idx3 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 1D array in row-major order.
- * Complex number is stored as two double values in sequence: the real and
- * imaginary part, i.e. the input array must be of size rows*2*columns. The
- * physical layout of the input data has to be as follows:- * a[k1*2*columns+2*k2] = Re[k1][k2], - * a[k1*2*columns+2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - * @param scale - * if true then scaling is performed - * - */ - public void complexInverse(final DoubleLargeArray a, final boolean scale) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columnsl = 2 * columnsl; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, r * columnsl, scale); - } - cdft2d_sub(1, a, scale); - } - columnsl = columnsl / 2; - } else { - final long rowspan = 2 * columnsl; - if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (long r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columnsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstColumn = l * p; - final long lastColumn = (l == (nthreads - 1)) ? columnsl : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long c = firstColumn; c < lastColumn; c++) { - long idx1 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - temp.setDouble(idx2, a.getDouble(idx3)); - temp.setDouble(idx2 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - a.setDouble(idx3, temp.getDouble(idx2)); - a.setDouble(idx3 + 1, temp.getDouble(idx2 + 1)); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, r * rowspan, scale); - } - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long c = 0; c < columnsl; c++) { - long idx1 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - temp.setDouble(idx2, a.getDouble(idx3)); - temp.setDouble(idx2 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx2 = 2 * r; - long idx3 = r * rowspan + idx1; - a.setDouble(idx3, temp.getDouble(idx2)); - a.setDouble(idx3 + 1, temp.getDouble(idx2 + 1)); - } - } - } - } - } - - /** - * Computes 2D inverse DFT of complex data leaving the result in - *
a. The data is stored in 2D array. Complex data is
- * represented by 2 double values in sequence: the real and imaginary part,
- * i.e. the input array must be of size rows by 2*columns. The physical
- * layout of the input data has to be as follows:- * a[k1][2*k2] = Re[k1][k2], - * a[k1][2*k2+1] = Im[k1][k2], 0<=k1<rows, 0<=k2<columns, - *- * - * @param a - * data to transform - * @param scale - * if true then scaling is performed - * - */ - public void complexInverse(final double[][] a, final boolean scale) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - columns = 2 * columns; - if ((nthreads > 1) && useThreads) { - xdft2d0_subth1(0, 1, a, scale); - cdft2d_subth(1, a, scale); - } else { - - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[r], scale); - } - cdft2d_sub(1, a, scale); - } - columns = columns / 2; - } else { - if ((nthreads > 1) && useThreads && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int r = firstRow; r < lastRow; r++) { - fftColumns.complexInverse(a[r], scale); - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - p = columns / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstColumn = l * p; - final int lastColumn = (l == (nthreads - 1)) ? columns : firstColumn + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int c = firstColumn; c < lastColumn; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - } else { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[r], scale); - } - double[] temp = new double[2 * rows]; - for (int c = 0; c < columns; c++) { - int idx1 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - temp[idx2] = a[r][idx1]; - temp[idx2 + 1] = a[r][idx1 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx2 = 2 * r; - a[r][idx1] = temp[idx2]; - a[r][idx1 + 1] = temp[idx2 + 1]; - } - } - } - } - } - - /** - * Computes 2D forward DFT of real data leaving the result in
a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForward(double[] a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForward(DoubleLargeArray a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the output data is as
- * follows:
- *
- * - * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1][0] = Re[k1][0] = Re[rows-k1][0], - * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], - * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0][0] = Re[0][0], - * a[0][1] = Re[0][columns/2], - * a[rows/2][0] = Re[rows/2][0], - * a[rows/2][1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForward(double[][] a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data. To get back the original data, use
- * complexInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForwardFull(double[] a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data. To get back the original data, use
- * complexInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForwardFull(DoubleLargeArray a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows by 2*columns, with only the first rows by
- * columns elements filled with real data. To get back the original data,
- * use complexInverse on the output of this method.
- *
- * @param a
- * data to transform
- */
- public void realForwardFull(double[][] a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth1(1, 1, a, true);
- cdft2d_subth(-1, a, true);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
- cdft2d_sub(-1, a, true);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverse(double[] a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a, r * columns, scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * - * a[k1*columns+2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1*columns+2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1*columns] = Re[k1][0] = Re[rows-k1][0], - * a[k1*columns+1] = Im[k1][0] = -Im[rows-k1][0], - * a[(rows-k1)*columns+1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[(rows-k1)*columns] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0] = Re[0][0], - * a[1] = Re[0][columns/2], - * a[(rows/2)*columns] = Re[rows/2][0], - * a[(rows/2)*columns+1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverse(DoubleLargeArray a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse(a, r * columnsl, scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of both dimensions are
- * power-of-two numbers. The physical layout of the input data has to be as
- * follows:
- *
- * - * a[k1][2*k2] = Re[k1][k2] = Re[rows-k1][columns-k2], - * a[k1][2*k2+1] = Im[k1][k2] = -Im[rows-k1][columns-k2], - * 0<k1<rows, 0<k2<columns/2, - * a[0][2*k2] = Re[0][k2] = Re[0][columns-k2], - * a[0][2*k2+1] = Im[0][k2] = -Im[0][columns-k2], - * 0<k2<columns/2, - * a[k1][0] = Re[k1][0] = Re[rows-k1][0], - * a[k1][1] = Im[k1][0] = -Im[rows-k1][0], - * a[rows-k1][1] = Re[k1][columns/2] = Re[rows-k1][columns/2], - * a[rows-k1][0] = -Im[k1][columns/2] = Im[rows-k1][columns/2], - * 0<k1<rows/2, - * a[0][0] = Re[0][0], - * a[0][1] = Re[0][columns/2], - * a[rows/2][0] = Re[rows/2][0], - * a[rows/2][1] = Re[rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverse(double[][] a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft2d_sub(-1, a);
- cdft2d_subth(1, a, scale);
- xdft2d0_subth1(1, -1, a, scale);
- } else {
- rdft2d_sub(-1, a);
- cdft2d_sub(1, a, scale);
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a[r], scale);
- }
- }
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverseFull(double[] a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows*2*columns, with only the first rows*columns
- * elements filled with real data.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverseFull(DoubleLargeArray a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 2D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size rows by 2*columns, with only the first rows by
- * columns elements filled with real data.
- *
- * @param a
- * data to transform
- *
- * @param scale
- * if true then scaling is performed
- */
- public void realInverseFull(double[][] a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft2d0_subth2(1, -1, a, scale);
- cdft2d_subth(1, a, scale);
- rdft2d_sub(1, a);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
- cdft2d_sub(1, a, scale);
- rdft2d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- private void mixedRadixRealForwardFull(final double[][] a)
- {
- final int n2d2 = columns / 2 + 1;
- final double[][] temp = new double[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a[i]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
-
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[r]);
- }
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
-
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealForwardFull(final double[] a)
- {
- final int rowStride = 2 * columns;
- final int n2d2 = columns / 2 + 1;
- final double[][] temp = new double[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a, i * columns);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, r * columns);
- }
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realForwardFull(temp[0]);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[c]);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp[n2d2 - 1]);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexForward(temp[n2d2 - 1]);
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealForwardFull(final DoubleLargeArray a)
- {
- final long rowStride = 2 * columnsl;
- final long n2d2 = columnsl / 2 + 1;
- final DoubleLargeArray temp = new DoubleLargeArray(n2d2 * 2 * rowsl, false);
- final long temp_stride = 2 * rowsl;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstRow; i < lastRow; i++) {
- fftColumns.realForward(a, i * columnsl);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl)); //first column is always real
- }
- fftRows.realForwardFull(temp);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = 1 + l * p;
- final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long c = firstColumn; c < lastColumn; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getDouble(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexForward(temp, c * temp_stride);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getDouble(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getDouble(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
- }
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getDouble(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getDouble(c * temp_stride + idx1 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = 1 + l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long r = firstRow; r < lastRow; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getDouble(idx4));
- a.setDouble(idx3 + 1, -a.getDouble(idx4 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, r * columnsl);
- }
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl)); //first column is always real
- }
- fftRows.realForwardFull(temp);
-
- for (long c = 1; c < n2d2 - 1; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getDouble(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexForward(temp, c * temp_stride);
- }
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getDouble(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realForwardFull(temp, (n2d2 - 1) * temp_stride);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getDouble(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexForward(temp, (n2d2 - 1) * temp_stride);
- }
-
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getDouble(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getDouble(c * temp_stride + idx1 + 1));
- }
- }
-
- //fill symmetric
- for (long r = 1; r < rowsl; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getDouble(idx4));
- a.setDouble(idx3 + 1, -a.getDouble(idx4 + 1));
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final double[][] a, final boolean scale)
- {
- final int n2d2 = columns / 2 + 1;
- final double[][] temp = new double[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a[i], 0, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
-
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r][0]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- temp[c][idx1] = a[r][idx2];
- temp[c][idx1 + 1] = a[r][idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r][1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = n2d2 - 1;
- temp[idx2][idx1] = a[r][2 * idx2];
- temp[idx2][idx1 + 1] = a[r][1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
-
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx2 = 2 * c;
- a[r][idx2] = temp[c][idx1];
- a[r][idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx3 = rows - r;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[0][idx1] = a[0][idx2];
- a[0][idx1 + 1] = -a[0][idx2 + 1];
- a[r][idx1] = a[idx3][idx2];
- a[r][idx1 + 1] = -a[idx3][idx2 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final double[] a, final boolean scale)
- {
- final int rowStride = 2 * columns;
- final int n2d2 = columns / 2 + 1;
- final double[][] temp = new double[n2d2][2 * rows];
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rows >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a, i * columns, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstColumn = 1 + l * p;
- final int lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int c = firstColumn; c < lastColumn; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
- }
-
- p = rows / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = 1 + l * p;
- final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int r = firstRow; r < lastRow; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- for (int r = 0; r < rows; r++) {
- temp[0][r] = a[r * columns]; //first column is always real
- }
- fftRows.realInverseFull(temp[0], scale);
-
- for (int c = 1; c < n2d2 - 1; c++) {
- int idx0 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns + idx0;
- temp[c][idx1] = a[idx2];
- temp[c][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[c], scale);
- }
-
- if ((columns % 2) == 0) {
- for (int r = 0; r < rows; r++) {
- temp[n2d2 - 1][r] = a[r * columns + 1];
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp[n2d2 - 1], scale);
-
- } else {
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- int idx2 = r * columns;
- int idx3 = n2d2 - 1;
- temp[idx3][idx1] = a[idx2 + 2 * idx3];
- temp[idx3][idx1 + 1] = a[idx2 + 1];
- }
- fftRows.complexInverse(temp[n2d2 - 1], scale);
- }
-
- for (int r = 0; r < rows; r++) {
- int idx1 = 2 * r;
- for (int c = 0; c < n2d2; c++) {
- int idx0 = 2 * c;
- int idx2 = r * rowStride + idx0;
- a[idx2] = temp[c][idx1];
- a[idx2 + 1] = temp[c][idx1 + 1];
- }
- }
-
- //fill symmetric
- for (int r = 1; r < rows; r++) {
- int idx5 = r * rowStride;
- int idx6 = (rows - r + 1) * rowStride;
- for (int c = n2d2; c < columns; c++) {
- int idx1 = 2 * c;
- int idx2 = 2 * (columns - c);
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- int idx3 = idx5 + idx1;
- int idx4 = idx6 - idx1;
- a[idx3] = a[idx4];
- a[idx3 + 1] = -a[idx4 + 1];
- }
- }
- }
- }
-
- private void mixedRadixRealInverseFull(final DoubleLargeArray a, final boolean scale)
- {
- final long rowStride = 2 * columnsl;
- final long n2d2 = columnsl / 2 + 1;
- final DoubleLargeArray temp = new DoubleLargeArray(n2d2 * 2 * rowsl, false);
- final long temp_stride = 2 * rowsl;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (rowsl >= nthreads) && (n2d2 - 2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long i = firstRow; i < lastRow; i++) {
- fftColumns.realInverse2(a, i * columnsl, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl)); //first column is always real
- }
- fftRows.realInverseFull(temp, scale);
-
- p = (n2d2 - 2) / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstColumn = 1 + l * p;
- final long lastColumn = (l == (nthreads - 1)) ? n2d2 - 1 : firstColumn + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long c = firstColumn; c < lastColumn; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getDouble(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexInverse(temp, c * temp_stride, scale);
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getDouble(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getDouble(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
- }
-
- p = rowsl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long r = firstRow; r < lastRow; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getDouble(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getDouble(c * temp_stride + idx1 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = 1 + l * p;
- final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long r = firstRow; r < lastRow; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getDouble(idx4));
- a.setDouble(idx3 + 1, -a.getDouble(idx4 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble(r, a.getDouble(r * columnsl)); //first column is always real
- }
- fftRows.realInverseFull(temp, scale);
-
- for (long c = 1; c < n2d2 - 1; c++) {
- long idx0 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl + idx0;
- temp.setDouble(c * temp_stride + idx1, a.getDouble(idx2));
- temp.setDouble(c * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexInverse(temp, c * temp_stride, scale);
- }
-
- if ((columnsl % 2) == 0) {
- for (long r = 0; r < rowsl; r++) {
- temp.setDouble((n2d2 - 1) * temp_stride + r, a.getDouble(r * columnsl + 1));
- //imaginary part = 0;
- }
- fftRows.realInverseFull(temp, (n2d2 - 1) * temp_stride, scale);
-
- } else {
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- long idx2 = r * columnsl;
- long idx3 = n2d2 - 1;
- temp.setDouble(idx3 * temp_stride + idx1, a.getDouble(idx2 + 2 * idx3));
- temp.setDouble(idx3 * temp_stride + idx1 + 1, a.getDouble(idx2 + 1));
- }
- fftRows.complexInverse(temp, (n2d2 - 1) * temp_stride, scale);
- }
-
- for (long r = 0; r < rowsl; r++) {
- long idx1 = 2 * r;
- for (long c = 0; c < n2d2; c++) {
- long idx0 = 2 * c;
- long idx2 = r * rowStride + idx0;
- a.setDouble(idx2, temp.getDouble(c * temp_stride + idx1));
- a.setDouble(idx2 + 1, temp.getDouble(c * temp_stride + idx1 + 1));
- }
- }
-
- //fill symmetric
- for (long r = 1; r < rowsl; r++) {
- long idx5 = r * rowStride;
- long idx6 = (rowsl - r + 1) * rowStride;
- for (long c = n2d2; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx2 = 2 * (columnsl - c);
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
- long idx3 = idx5 + idx1;
- long idx4 = idx6 - idx1;
- a.setDouble(idx3, a.getDouble(idx4));
- a.setDouble(idx3 + 1, -a.getDouble(idx4 + 1));
- }
- }
- }
- }
-
- private void rdft2d_sub(int isgn, double[] a)
- {
- int n1h, j;
- double xi;
- int idx1, idx2;
-
- n1h = rows >> 1;
- if (isgn < 0) {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- idx1 = i * columns;
- idx2 = j * columns;
- xi = a[idx1] - a[idx2];
- a[idx1] += a[idx2];
- a[idx2] = xi;
- xi = a[idx2 + 1] - a[idx1 + 1];
- a[idx1 + 1] += a[idx2 + 1];
- a[idx2 + 1] = xi;
- }
- } else {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- idx1 = i * columns;
- idx2 = j * columns;
- a[idx2] = 0.5f * (a[idx1] - a[idx2]);
- a[idx1] -= a[idx2];
- a[idx2 + 1] = 0.5f * (a[idx1 + 1] + a[idx2 + 1]);
- a[idx1 + 1] -= a[idx2 + 1];
- }
- }
- }
-
- private void rdft2d_sub(int isgn, DoubleLargeArray a)
- {
- long n1h, j;
- double xi;
- long idx1, idx2;
-
- n1h = rowsl >> 1;
- if (isgn < 0) {
- for (long i = 1; i < n1h; i++) {
- j = rowsl - i;
- idx1 = i * columnsl;
- idx2 = j * columnsl;
- xi = a.getDouble(idx1) - a.getDouble(idx2);
- a.setDouble(idx1, a.getDouble(idx1) + a.getDouble(idx2));
- a.setDouble(idx2, xi);
- xi = a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1));
- a.setDouble(idx2 + 1, xi);
- }
- } else {
- for (long i = 1; i < n1h; i++) {
- j = rowsl - i;
- idx1 = i * columnsl;
- idx2 = j * columnsl;
- a.setDouble(idx2, 0.5f * (a.getDouble(idx1) - a.getDouble(idx2)));
- a.setDouble(idx1, a.getDouble(idx1) - a.getDouble(idx2));
- a.setDouble(idx2 + 1, 0.5f * (a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1)));
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) - a.getDouble(idx2 + 1));
- }
- }
- }
-
- private void rdft2d_sub(int isgn, double[][] a)
- {
- int n1h, j;
- double xi;
-
- n1h = rows >> 1;
- if (isgn < 0) {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- xi = a[i][0] - a[j][0];
- a[i][0] += a[j][0];
- a[j][0] = xi;
- xi = a[j][1] - a[i][1];
- a[i][1] += a[j][1];
- a[j][1] = xi;
- }
- } else {
- for (int i = 1; i < n1h; i++) {
- j = rows - i;
- a[j][0] = 0.5f * (a[i][0] - a[j][0]);
- a[i][0] -= a[j][0];
- a[j][1] = 0.5f * (a[i][1] + a[j][1]);
- a[i][1] -= a[j][1];
- }
- }
- }
-
- private void cdft2d_sub(int isgn, double[] a, boolean scale)
- {
- int idx1, idx2, idx3, idx4, idx5;
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
-
- private void cdft2d_sub(int isgn, DoubleLargeArray a, boolean scale)
- {
- long idx1, idx2, idx3, idx4, idx5;
- long nt = 8 * rowsl;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- } else {
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
-
- private void cdft2d_sub(int isgn, double[][] a, boolean scale)
- {
- int idx2, idx3, idx4, idx5;
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- t[idx3] = a[r][2];
- t[idx3 + 1] = a[r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- a[r][2] = t[idx3];
- a[r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- t[idx3] = a[r][2];
- t[idx3 + 1] = a[r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- a[r][2] = t[idx3];
- a[r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][0];
- t[idx2 + 1] = a[r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][0] = t[idx2];
- a[r][1] = t[idx2 + 1];
- }
- }
- }
- }
-
- private void xdft2d0_subth1(final int icr, final int isgn, final double[] a, final boolean scale)
- {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a, r * columns, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse(a, r * columns, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth1(final long icr, final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- final int nthreads = (int) (ConcurrencyUtils.getNumberOfThreads() > rowsl ? rowsl : ConcurrencyUtils.getNumberOfThreads());
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexInverse(a, r * columnsl, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realInverse(a, r * columnsl, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final int icr, final int isgn, final double[] a, final boolean scale)
- {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a, r * columns, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a, r * columns);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse2(a, r * columns, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final long icr, final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.complexInverse(a, r * columnsl, scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realForward(a, r * columnsl);
- }
- } else {
- for (long r = n0; r < rowsl; r += nthreads) {
- fftColumns.realInverse2(a, r * columnsl, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth1(final int icr, final int isgn, final double[][] a, final boolean scale)
- {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a[r], scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse(a[r], scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft2d0_subth2(final int icr, final int isgn, final double[][] a, final boolean scale)
- {
- final int nthreads = ConcurrencyUtils.getNumberOfThreads() > rows ? rows : ConcurrencyUtils.getNumberOfThreads();
-
- Future>[] futures = new Future[nthreads];
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- if (icr == 0) {
- if (isgn == -1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.complexInverse(a[r], scale);
- }
- }
- } else {
- if (isgn == 1) {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realForward(a[r]);
- }
- } else {
- for (int r = n0; r < rows; r += nthreads) {
- fftColumns.realInverse2(a[r], 0, scale);
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final double[] a, final boolean scale)
- {
- int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthread; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx1, idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = r * columns + 2 * n0;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- int nthread = (int) Math.min(columnsl / 2, ConcurrencyUtils.getNumberOfThreads());
- long nt = 8 * rowsl;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthread; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- long idx1, idx2, idx3, idx4, idx5;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 4 * nthreads) {
- for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- } else {
- if (columnsl > 4 * nthreads) {
- for (long c = 8 * n0; c < columnsl; c += 8 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 4 * n0;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2 * nthreads) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = r * columnsl + 2 * n0;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft2d_subth(final int isgn, final double[][] a, final boolean scale)
- {
- int nthread = Math.min(columns / 2, ConcurrencyUtils.getNumberOfThreads());
- int nt = 8 * rows;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthread];
- final int nthreads = nthread;
- for (int i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][4 * n0];
- t[idx2 + 1] = a[r][4 * n0 + 1];
- t[idx3] = a[r][4 * n0 + 2];
- t[idx3 + 1] = a[r][4 * n0 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][4 * n0] = t[idx2];
- a[r][4 * n0 + 1] = t[idx2 + 1];
- a[r][4 * n0 + 2] = t[idx3];
- a[r][4 * n0 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + 1] = a[r][2 * n0 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + 1];
- }
- }
- } else {
- if (columns > 4 * nthreads) {
- for (int c = 8 * n0; c < columns; c += 8 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[r][c];
- t[idx2 + 1] = a[r][c + 1];
- t[idx3] = a[r][c + 2];
- t[idx3 + 1] = a[r][c + 3];
- t[idx4] = a[r][c + 4];
- t[idx4 + 1] = a[r][c + 5];
- t[idx5] = a[r][c + 6];
- t[idx5 + 1] = a[r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[r][c] = t[idx2];
- a[r][c + 1] = t[idx2 + 1];
- a[r][c + 2] = t[idx3];
- a[r][c + 3] = t[idx3 + 1];
- a[r][c + 4] = t[idx4];
- a[r][c + 5] = t[idx4 + 1];
- a[r][c + 6] = t[idx5];
- a[r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[r][4 * n0];
- t[idx2 + 1] = a[r][4 * n0 + 1];
- t[idx3] = a[r][4 * n0 + 2];
- t[idx3 + 1] = a[r][4 * n0 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[r][4 * n0] = t[idx2];
- a[r][4 * n0 + 1] = t[idx2 + 1];
- a[r][4 * n0 + 2] = t[idx3];
- a[r][4 * n0 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2 * nthreads) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[r][2 * n0];
- t[idx2 + 1] = a[r][2 * n0 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[r][2 * n0] = t[idx2];
- a[r][2 * n0 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void fillSymmetric(final double[] a)
- {
- final int twon2 = 2 * columns;
- int idx1, idx2, idx3, idx4;
- int n1d2 = rows / 2;
-
- for (int r = (rows - 1); r >= 1; r--) {
- idx1 = r * columns;
- idx2 = 2 * idx1;
- for (int c = 0; c < columns; c += 2) {
- a[idx2 + c] = a[idx1 + c];
- a[idx1 + c] = 0;
- a[idx2 + c + 1] = a[idx1 + c + 1];
- a[idx1 + c + 1] = 0;
- }
- }
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int l1k = n1d2 / nthreads;
- final int newn2 = 2 * columns;
- for (int i = 0; i < nthreads; i++) {
- final int l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0)
- l1offa = i * l1k + 1;
- else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx1, idx2, idx3, idx4;
-
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx2 = (rows - r) * newn2;
- idx3 = idx1 + columns;
- a[idx3] = a[idx2 + 1];
- a[idx3 + 1] = -a[idx2];
- }
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx3 = (rows - r + 1) * newn2;
- for (int c = columns + 2; c < newn2; c += 2) {
- idx2 = idx3 - c;
- idx4 = idx1 + c;
- a[idx4] = a[idx2];
- a[idx4 + 1] = -a[idx2 + 1];
-
- }
- }
- for (int r = l2offa; r < l2stopa; r++) {
- idx3 = ((rows - r) % rows) * newn2;
- idx4 = r * newn2;
- for (int c = 0; c < newn2; c += 2) {
- idx1 = idx3 + (newn2 - c) % newn2;
- idx2 = idx4 + c;
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rows - r) * twon2;
- a[idx2 + columns] = a[idx3 + 1];
- a[idx2 + columns + 1] = -a[idx3];
- }
-
- for (int r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rows - r + 1) * twon2;
- for (int c = columns + 2; c < twon2; c += 2) {
- a[idx2 + c] = a[idx3 - c];
- a[idx2 + c + 1] = -a[idx3 - c + 1];
-
- }
- }
- for (int r = 0; r <= rows / 2; r++) {
- idx1 = r * twon2;
- idx4 = ((rows - r) % rows) * twon2;
- for (int c = 0; c < twon2; c += 2) {
- idx2 = idx1 + c;
- idx3 = idx4 + (twon2 - c) % twon2;
- a[idx3] = a[idx2];
- a[idx3 + 1] = -a[idx2 + 1];
- }
- }
- }
- a[columns] = -a[1];
- a[1] = 0;
- idx1 = n1d2 * twon2;
- a[idx1 + columns] = -a[idx1 + 1];
- a[idx1 + 1] = 0;
- a[idx1 + columns + 1] = 0;
- }
-
- private void fillSymmetric(final DoubleLargeArray a)
- {
- final long twon2 = 2 * columnsl;
- long idx1, idx2, idx3, idx4;
- long n1d2 = rowsl / 2;
-
- for (long r = (rowsl - 1); r >= 1; r--) {
- idx1 = r * columnsl;
- idx2 = 2 * idx1;
- for (long c = 0; c < columnsl; c += 2) {
- a.setDouble(idx2 + c, a.getDouble(idx1 + c));
- a.setDouble(idx1 + c, 0);
- a.setDouble(idx2 + c + 1, a.getDouble(idx1 + c + 1));
- a.setDouble(idx1 + c + 1, 0);
- }
- }
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long l1k = n1d2 / nthreads;
- final long newn2 = 2 * columnsl;
- for (int i = 0; i < nthreads; i++) {
- final long l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0)
- l1offa = i * l1k + 1;
- else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- long idx1, idx2, idx3, idx4;
-
- for (long r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx2 = (rowsl - r) * newn2;
- idx3 = idx1 + columnsl;
- a.setDouble(idx3, a.getDouble(idx2 + 1));
- a.setDouble(idx3 + 1, -a.getDouble(idx2));
- }
- for (long r = l1offa; r < l1stopa; r++) {
- idx1 = r * newn2;
- idx3 = (rowsl - r + 1) * newn2;
- for (long c = columnsl + 2; c < newn2; c += 2) {
- idx2 = idx3 - c;
- idx4 = idx1 + c;
- a.setDouble(idx4, a.getDouble(idx2));
- a.setDouble(idx4 + 1, -a.getDouble(idx2 + 1));
-
- }
- }
- for (long r = l2offa; r < l2stopa; r++) {
- idx3 = ((rowsl - r) % rowsl) * newn2;
- idx4 = r * newn2;
- for (long c = 0; c < newn2; c += 2) {
- idx1 = idx3 + (newn2 - c) % newn2;
- idx2 = idx4 + c;
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (long r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rowsl - r) * twon2;
- a.setDouble(idx2 + columnsl, a.getDouble(idx3 + 1));
- a.setDouble(idx2 + columnsl + 1, -a.getDouble(idx3));
- }
-
- for (long r = 1; r < n1d2; r++) {
- idx2 = r * twon2;
- idx3 = (rowsl - r + 1) * twon2;
- for (long c = columnsl + 2; c < twon2; c += 2) {
- a.setDouble(idx2 + c, a.getDouble(idx3 - c));
- a.setDouble(idx2 + c + 1, -a.getDouble(idx3 - c + 1));
-
- }
- }
- for (long r = 0; r <= rowsl / 2; r++) {
- idx1 = r * twon2;
- idx4 = ((rowsl - r) % rowsl) * twon2;
- for (long c = 0; c < twon2; c += 2) {
- idx2 = idx1 + c;
- idx3 = idx4 + (twon2 - c) % twon2;
- a.setDouble(idx3, a.getDouble(idx2));
- a.setDouble(idx3 + 1, -a.getDouble(idx2 + 1));
- }
- }
- }
- a.setDouble(columnsl, -a.getDouble(1));
- a.setDouble(1, 0);
- idx1 = n1d2 * twon2;
- a.setDouble(idx1 + columnsl, -a.getDouble(idx1 + 1));
- a.setDouble(idx1 + 1, 0);
- a.setDouble(idx1 + columnsl + 1, 0);
- }
-
- private void fillSymmetric(final double[][] a)
- {
- final int newn2 = 2 * columns;
- int n1d2 = rows / 2;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int l1k = n1d2 / nthreads;
- for (int i = 0; i < nthreads; i++) {
- final int l1offa, l1stopa, l2offa, l2stopa;
- if (i == 0)
- l1offa = i * l1k + 1;
- else {
- l1offa = i * l1k;
- }
- l1stopa = i * l1k + l1k;
- l2offa = i * l1k;
- if (i == nthreads - 1) {
- l2stopa = i * l1k + l1k + 1;
- } else {
- l2stopa = i * l1k + l1k;
- }
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx1, idx2;
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = rows - r;
- a[r][columns] = a[idx1][1];
- a[r][columns + 1] = -a[idx1][0];
- }
- for (int r = l1offa; r < l1stopa; r++) {
- idx1 = rows - r;
- for (int c = columns + 2; c < newn2; c += 2) {
- idx2 = newn2 - c;
- a[r][c] = a[idx1][idx2];
- a[r][c + 1] = -a[idx1][idx2 + 1];
-
- }
- }
- for (int r = l2offa; r < l2stopa; r++) {
- idx1 = (rows - r) % rows;
- for (int c = 0; c < newn2; c = c + 2) {
- idx2 = (newn2 - c) % newn2;
- a[idx1][idx2] = a[r][c];
- a[idx1][idx2 + 1] = -a[r][c + 1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int r = 1; r < n1d2; r++) {
- int idx1 = rows - r;
- a[r][columns] = a[idx1][1];
- a[r][columns + 1] = -a[idx1][0];
- }
- for (int r = 1; r < n1d2; r++) {
- int idx1 = rows - r;
- for (int c = columns + 2; c < newn2; c += 2) {
- int idx2 = newn2 - c;
- a[r][c] = a[idx1][idx2];
- a[r][c + 1] = -a[idx1][idx2 + 1];
- }
- }
- for (int r = 0; r <= rows / 2; r++) {
- int idx1 = (rows - r) % rows;
- for (int c = 0; c < newn2; c += 2) {
- int idx2 = (newn2 - c) % newn2;
- a[idx1][idx2] = a[r][c];
- a[idx1][idx2 + 1] = -a[r][c + 1];
- }
- }
- }
- a[0][columns] = -a[0][1];
- a[0][1] = 0;
- a[n1d2][columns] = -a[n1d2][1];
- a[n1d2][1] = 0;
- a[n1d2][columns + 1] = 0;
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/DoubleFFT_3D.java b/src/main/java/org/jtransforms/fft/DoubleFFT_3D.java
deleted file mode 100644
index fbc355c..0000000
--- a/src/main/java/org/jtransforms/fft/DoubleFFT_3D.java
+++ /dev/null
@@ -1,7448 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-import java.util.concurrent.Future;
-import org.jtransforms.utils.ConcurrencyUtils;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.Utilities;
-
-/**
- * Computes 3D Discrete Fourier Transform (DFT) of complex and real, double
- * precision data. The sizes of all three dimensions can be arbitrary numbers.
- * This is a parallel implementation of split-radix and mixed-radix algorithms
- * optimized for SMP systems. a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. element
- * (i,j,k) of 3D array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. Complex number is stored as two
- * double values in sequence: the real and imaginary part, i.e. the input
- * array must be of size slices*rows*2*columns. The physical layout of the
- * input data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3], - * a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - */ - public void complexForward(final double[] a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - int oldn3 = columns; - columns = 2 * columns; - sliceStride = rows * columns; - rowStride = columns; - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, -1, a, true); - cdft3db_subth(-1, a, true); - } else { - xdft3da_sub2(0, -1, a, true); - cdft3db_sub(-1, a, true); - } - columns = oldn3; - sliceStride = rows * columns; - rowStride = columns; - } else { - sliceStride = 2 * rows * columns; - rowStride = 2 * columns; - if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = slices / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int s = firstSlice; s < lastSlice; s++) { - int idx1 = s * sliceStride; - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, idx1 + r * rowStride); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int s = firstSlice; s < lastSlice; s++) { - int idx1 = s * sliceStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * slices]; - for (int r = firstRow; r < lastRow; r++) { - int idx1 = r * rowStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftSlices.complexForward(temp); - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (int s = 0; s < slices; s++) { - int idx1 = s * sliceStride; - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a, idx1 + r * rowStride); - } - } - - double[] temp = new double[2 * rows]; - for (int s = 0; s < slices; s++) { - int idx1 = s * sliceStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - - temp = new double[2 * slices]; - for (int r = 0; r < rows; r++) { - int idx1 = r * rowStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftSlices.complexForward(temp); - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - sliceStride = rows * columns; - rowStride = columns; - } - } - - /** - * Computes 3D forward DFT of complex data leaving the result in - *
a. The data is stored in 1D array addressed in slice-major,
- * then row-major, then column-major, in order of significance, i.e. element
- * (i,j,k) of 3D array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. Complex number is stored as two
- * double values in sequence: the real and imaginary part, i.e. the input
- * array must be of size slices*rows*2*columns. The physical layout of the
- * input data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3], - * a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - */ - public void complexForward(final DoubleLargeArray a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - long oldn3 = columnsl; - columnsl = 2 * columnsl; - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, -1, a, true); - cdft3db_subth(-1, a, true); - } else { - xdft3da_sub2(0, -1, a, true); - cdft3db_sub(-1, a, true); - } - columnsl = oldn3; - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - } else { - sliceStridel = 2 * rowsl * columnsl; - rowStridel = 2 * columnsl; - if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = slicesl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstSlice = l * p; - final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (long s = firstSlice; s < lastSlice; s++) { - long idx1 = s * sliceStridel; - for (long r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, idx1 + r * rowStridel); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final long firstSlice = l * p; - final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long s = firstSlice; s < lastSlice; s++) { - long idx1 = s * sliceStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * slicesl, false); - for (long r = firstRow; r < lastRow; r++) { - long idx1 = r * rowStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftSlices.complexForward(temp); - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (long s = 0; s < slicesl; s++) { - long idx1 = s * sliceStridel; - for (long r = 0; r < rowsl; r++) { - fftColumns.complexForward(a, idx1 + r * rowStridel); - } - } - - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long s = 0; s < slicesl; s++) { - long idx1 = s * sliceStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexForward(temp); - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - - temp = new DoubleLargeArray(2 * slicesl, false); - for (long r = 0; r < rowsl; r++) { - long idx1 = r * rowStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftSlices.complexForward(temp); - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - } - } - - /** - * Computes 3D forward DFT of complex data leaving the result in - *
a. The data is stored in 3D array. Complex data is
- * represented by 2 double values in sequence: the real and imaginary part,
- * i.e. the input array must be of size slices by rows by 2*columns. The
- * physical layout of the input data is as follows:
- *
- * * - * a[k1][k2][2*k3] = Re[k1][k2][k3], a[k1][k2][2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - */ - public void complexForward(final double[][][] a) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - int oldn3 = columns; - columns = 2 * columns; - - sliceStride = rows * columns; - rowStride = columns; - - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, -1, a, true); - cdft3db_subth(-1, a, true); - } else { - xdft3da_sub2(0, -1, a, true); - cdft3db_sub(-1, a, true); - } - columns = oldn3; - sliceStride = rows * columns; - rowStride = columns; - } else { - if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = slices / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int s = firstSlice; s < lastSlice; s++) { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[s][r]); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int s = firstSlice; s < lastSlice; s++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * slices]; - for (int r = firstRow; r < lastRow; r++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftSlices.complexForward(temp); - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (int s = 0; s < slices; s++) { - for (int r = 0; r < rows; r++) { - fftColumns.complexForward(a[s][r]); - } - } - - double[] temp = new double[2 * rows]; - for (int s = 0; s < slices; s++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftRows.complexForward(temp); - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - - temp = new double[2 * slices]; - for (int r = 0; r < rows; r++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftSlices.complexForward(temp); - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - } - } - - /** - * Computes 3D inverse DFT of complex data leaving the result in - *
a. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. Complex number is stored as two
- * double values in sequence: the real and imaginary part, i.e. the input
- * array must be of size slices*rows*2*columns. The physical layout of the
- * input data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3], - * a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(final double[] a, final boolean scale) - { - - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - - if (isPowerOfTwo) { - int oldn3 = columns; - columns = 2 * columns; - sliceStride = rows * columns; - rowStride = columns; - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, 1, a, scale); - cdft3db_subth(1, a, scale); - } else { - xdft3da_sub2(0, 1, a, scale); - cdft3db_sub(1, a, scale); - } - columns = oldn3; - sliceStride = rows * columns; - rowStride = columns; - } else { - sliceStride = 2 * rows * columns; - rowStride = 2 * columns; - if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = slices / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int s = firstSlice; s < lastSlice; s++) { - int idx1 = s * sliceStride; - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, idx1 + r * rowStride, scale); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int s = firstSlice; s < lastSlice; s++) { - int idx1 = s * sliceStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * slices]; - for (int r = firstRow; r < lastRow; r++) { - int idx1 = r * rowStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftSlices.complexInverse(temp, scale); - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (int s = 0; s < slices; s++) { - int idx1 = s * sliceStride; - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a, idx1 + r * rowStride, scale); - } - } - double[] temp = new double[2 * rows]; - for (int s = 0; s < slices; s++) { - int idx1 = s * sliceStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx3 = idx1 + idx2 + r * rowStride; - int idx4 = 2 * r; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - temp = new double[2 * slices]; - for (int r = 0; r < rows; r++) { - int idx1 = r * rowStride; - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - temp[idx4] = a[idx3]; - temp[idx4 + 1] = a[idx3 + 1]; - } - fftSlices.complexInverse(temp, scale); - for (int s = 0; s < slices; s++) { - int idx3 = s * sliceStride + idx1 + idx2; - int idx4 = 2 * s; - a[idx3] = temp[idx4]; - a[idx3 + 1] = temp[idx4 + 1]; - } - } - } - } - sliceStride = rows * columns; - rowStride = columns; - } - } - - /** - * Computes 3D inverse DFT of complex data leaving the result in - *
a. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. Complex number is stored as two
- * double values in sequence: the real and imaginary part, i.e. the input
- * array must be of size slices*rows*2*columns. The physical layout of the
- * input data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3], - * a[k1*sliceStride + k2*rowStride + 2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(final DoubleLargeArray a, final boolean scale) - { - - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - - if (isPowerOfTwo) { - long oldn3 = columnsl; - columnsl = 2 * columnsl; - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, 1, a, scale); - cdft3db_subth(1, a, scale); - } else { - xdft3da_sub2(0, 1, a, scale); - cdft3db_sub(1, a, scale); - } - columnsl = oldn3; - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - } else { - sliceStridel = 2 * rowsl * columnsl; - rowStridel = 2 * columnsl; - if ((nthreads > 1) && useThreads && (slicesl >= nthreads) && (rowsl >= nthreads) && (columnsl >= nthreads)) { - Future>[] futures = new Future[nthreads]; - long p = slicesl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstSlice = l * p; - final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (long s = firstSlice; s < lastSlice; s++) { - long idx1 = s * sliceStridel; - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, idx1 + r * rowStridel, scale); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final long firstSlice = l * p; - final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long s = firstSlice; s < lastSlice; s++) { - long idx1 = s * sliceStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rowsl / nthreads; - for (int l = 0; l < nthreads; l++) { - final long firstRow = l * p; - final long lastRow = (l == (nthreads - 1)) ? rowsl : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - DoubleLargeArray temp = new DoubleLargeArray(2 * slicesl, false); - for (long r = firstRow; r < lastRow; r++) { - long idx1 = r * rowStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftSlices.complexInverse(temp, scale); - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (long s = 0; s < slicesl; s++) { - long idx1 = s * sliceStridel; - for (long r = 0; r < rowsl; r++) { - fftColumns.complexInverse(a, idx1 + r * rowStridel, scale); - } - } - DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false); - for (long s = 0; s < slicesl; s++) { - long idx1 = s * sliceStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftRows.complexInverse(temp, scale); - for (long r = 0; r < rowsl; r++) { - long idx3 = idx1 + idx2 + r * rowStridel; - long idx4 = 2 * r; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - temp = new DoubleLargeArray(2 * slicesl, false); - for (long r = 0; r < rowsl; r++) { - long idx1 = r * rowStridel; - for (long c = 0; c < columnsl; c++) { - long idx2 = 2 * c; - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - temp.setDouble(idx4, a.getDouble(idx3)); - temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1)); - } - fftSlices.complexInverse(temp, scale); - for (long s = 0; s < slicesl; s++) { - long idx3 = s * sliceStridel + idx1 + idx2; - long idx4 = 2 * s; - a.setDouble(idx3, temp.getDouble(idx4)); - a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1)); - } - } - } - } - sliceStridel = rowsl * columnsl; - rowStridel = columnsl; - } - } - - /** - * Computes 3D inverse DFT of complex data leaving the result in - *
a. The data is stored in a 3D array. Complex data is
- * represented by 2 double values in sequence: the real and imaginary part,
- * i.e. the input array must be of size slices by rows by 2*columns. The
- * physical layout of the input data is as follows:
- *
- * * - * a[k1][k2][2*k3] = Re[k1][k2][k3], a[k1][k2][2*k3+1] = Im[k1][k2][k3], - * 0<=k1<slices, 0<=k2<rows, 0<=k3<columns, - *- * - * @param a data to transform - * @param scale if true then scaling is performed - */ - public void complexInverse(final double[][][] a, final boolean scale) - { - int nthreads = ConcurrencyUtils.getNumberOfThreads(); - if (isPowerOfTwo) { - int oldn3 = columns; - columns = 2 * columns; - sliceStride = rows * columns; - rowStride = columns; - if ((nthreads > 1) && useThreads) { - xdft3da_subth2(0, 1, a, scale); - cdft3db_subth(1, a, scale); - } else { - xdft3da_sub2(0, 1, a, scale); - cdft3db_sub(1, a, scale); - } - columns = oldn3; - sliceStride = rows * columns; - rowStride = columns; - } else { - if ((nthreads > 1) && useThreads && (slices >= nthreads) && (rows >= nthreads) && (columns >= nthreads)) { - Future>[] futures = new Future[nthreads]; - int p = slices / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - for (int s = firstSlice; s < lastSlice; s++) { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[s][r], scale); - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - for (int l = 0; l < nthreads; l++) { - final int firstSlice = l * p; - final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * rows]; - for (int s = firstSlice; s < lastSlice; s++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - p = rows / nthreads; - for (int l = 0; l < nthreads; l++) { - final int firstRow = l * p; - final int lastRow = (l == (nthreads - 1)) ? rows : firstRow + p; - - futures[l] = ConcurrencyUtils.submit(new Runnable() - { - public void run() - { - double[] temp = new double[2 * slices]; - for (int r = firstRow; r < lastRow; r++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftSlices.complexInverse(temp, scale); - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - }); - } - ConcurrencyUtils.waitForCompletion(futures); - - } else { - for (int s = 0; s < slices; s++) { - for (int r = 0; r < rows; r++) { - fftColumns.complexInverse(a[s][r], scale); - } - } - double[] temp = new double[2 * rows]; - for (int s = 0; s < slices; s++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftRows.complexInverse(temp, scale); - for (int r = 0; r < rows; r++) { - int idx4 = 2 * r; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - temp = new double[2 * slices]; - for (int r = 0; r < rows; r++) { - for (int c = 0; c < columns; c++) { - int idx2 = 2 * c; - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - temp[idx4] = a[s][r][idx2]; - temp[idx4 + 1] = a[s][r][idx2 + 1]; - } - fftSlices.complexInverse(temp, scale); - for (int s = 0; s < slices; s++) { - int idx4 = 2 * s; - a[s][r][idx2] = temp[idx4]; - a[s][r][idx2 + 1] = temp[idx4 + 1]; - } - } - } - } - } - } - - /** - * Computes 3D forward DFT of real data leaving the result in
a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. The physical layout of the output
- * data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1*sliceStride + - * k2*rowStride + 2*k3+1] = Im[k1][k2][k3] = - * -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], 0<=k1<slices, - * 0<=k2<rows, 0<k3<columns/2, a[k1*sliceStride + k2*rowStride] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1*sliceStride + - * k2*rowStride + 1] = Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], - * a[k1*sliceStride + (rows-k2)*rowStride + 1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1*sliceStride + (rows-k2)*rowStride] = - * -Im[(slices-k1)%slices][k2][columns/2] = Im[k1][rows-k2][columns/2], - * 0<=k1<slices, 0<k2<rows/2, a[k1*sliceStride] = Re[k1][0][0] = - * Re[slices-k1][0][0], a[k1*sliceStride + 1] = Im[k1][0][0] = - * -Im[slices-k1][0][0], a[k1*sliceStride + (rows/2)*rowStride] = - * Re[k1][rows/2][0] = Re[slices-k1][rows/2][0], a[k1*sliceStride + - * (rows/2)*rowStride + 1] = Im[k1][rows/2][0] = -Im[slices-k1][rows/2][0], - * a[(slices-k1)*sliceStride + 1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[(slices-k1)*sliceStride] = - * -Im[k1][0][columns/2] = Im[slices-k1][0][columns/2], - * a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[(slices-k1)*sliceStride + (rows/2) * rowStride] = - * -Im[k1][rows/2][columns/2] = Im[slices-k1][rows/2][columns/2], - * 0<k1<slices/2, a[0] = Re[0][0][0], a[1] = Re[0][0][columns/2], - * a[(rows/2)*rowStride] = Re[0][rows/2][0], a[(rows/2)*rowStride + 1] = - * Re[0][rows/2][columns/2], a[(slices/2)*sliceStride] = Re[slices/2][0][0], - * a[(slices/2)*sliceStride + 1] = Re[slices/2][0][columns/2], - * a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2][0], - * a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = - * Re[slices/2][rows/2][columns/2] - *- * - * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(double[] a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth1(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub1(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 3D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. The physical layout of the output
- * data is as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1*sliceStride + - * k2*rowStride + 2*k3+1] = Im[k1][k2][k3] = - * -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], 0<=k1<slices, - * 0<=k2<rows, 0<k3<columns/2, a[k1*sliceStride + k2*rowStride] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1*sliceStride + - * k2*rowStride + 1] = Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], - * a[k1*sliceStride + (rows-k2)*rowStride + 1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1*sliceStride + (rows-k2)*rowStride] = - * -Im[(slices-k1)%slices][k2][columns/2] = Im[k1][rows-k2][columns/2], - * 0<=k1<slices, 0<k2<rows/2, a[k1*sliceStride] = Re[k1][0][0] = - * Re[slices-k1][0][0], a[k1*sliceStride + 1] = Im[k1][0][0] = - * -Im[slices-k1][0][0], a[k1*sliceStride + (rows/2)*rowStride] = - * Re[k1][rows/2][0] = Re[slices-k1][rows/2][0], a[k1*sliceStride + - * (rows/2)*rowStride + 1] = Im[k1][rows/2][0] = -Im[slices-k1][rows/2][0], - * a[(slices-k1)*sliceStride + 1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[(slices-k1)*sliceStride] = - * -Im[k1][0][columns/2] = Im[slices-k1][0][columns/2], - * a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[(slices-k1)*sliceStride + (rows/2) * rowStride] = - * -Im[k1][rows/2][columns/2] = Im[slices-k1][rows/2][columns/2], - * 0<k1<slices/2, a[0] = Re[0][0][0], a[1] = Re[0][0][columns/2], - * a[(rows/2)*rowStride] = Re[0][rows/2][0], a[(rows/2)*rowStride + 1] = - * Re[0][rows/2][columns/2], a[(slices/2)*sliceStride] = Re[slices/2][0][0], - * a[(slices/2)*sliceStride + 1] = Re[slices/2][0][columns/2], - * a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2][0], - * a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = - * Re[slices/2][rows/2][columns/2] - *- * - * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(DoubleLargeArray a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth1(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub1(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 3D forward DFT of real data leaving the result in a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 3D array. The physical
- * layout of the output data is as follows:
- *
- * * - * a[k1][k2][2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1][k2][2*k3+1] = - * Im[k1][k2][k3] = -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], - * 0<=k1<slices, 0<=k2<rows, 0<k3<columns/2, a[k1][k2][0] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1][k2][1] = - * Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], a[k1][rows-k2][1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1][rows-k2][0] = -Im[(slices-k1)%slices][k2][columns/2] = - * Im[k1][rows-k2][columns/2], 0<=k1<slices, 0<k2<rows/2, - * a[k1][0][0] = Re[k1][0][0] = Re[slices-k1][0][0], a[k1][0][1] = - * Im[k1][0][0] = -Im[slices-k1][0][0], a[k1][rows/2][0] = Re[k1][rows/2][0] - * = Re[slices-k1][rows/2][0], a[k1][rows/2][1] = Im[k1][rows/2][0] = - * -Im[slices-k1][rows/2][0], a[slices-k1][0][1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[slices-k1][0][0] = -Im[k1][0][columns/2] = - * Im[slices-k1][0][columns/2], a[slices-k1][rows/2][1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[slices-k1][rows/2][0] = -Im[k1][rows/2][columns/2] = - * Im[slices-k1][rows/2][columns/2], 0<k1<slices/2, a[0][0][0] = - * Re[0][0][0], a[0][0][1] = Re[0][0][columns/2], a[0][rows/2][0] = - * Re[0][rows/2][0], a[0][rows/2][1] = Re[0][rows/2][columns/2], - * a[slices/2][0][0] = Re[slices/2][0][0], a[slices/2][0][1] = - * Re[slices/2][0][columns/2], a[slices/2][rows/2][0] = - * Re[slices/2][rows/2][0], a[slices/2][rows/2][1] = - * Re[slices/2][rows/2][columns/2] - *- * - * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * forward transform, use
realForwardFull. To get back the
- * original data, use realInverse on the output of this method.
- *
- * @param a data to transform
- */
- public void realForward(double[][][] a)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth1(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub1(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- }
- }
-
- /**
- * Computes 3D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices*rows*2*columns, with only the first
- * slices*rows*columns elements filled with real data. To get back the
- * original data, use complexInverse on the output of this
- * method.
- *
- * @param a data to transform
- */
- public void realForwardFull(double[] a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 3D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices*rows*2*columns, with only the first
- * slices*rows*columns elements filled with real data. To get back the
- * original data, use complexInverse on the output of this
- * method.
- *
- * @param a data to transform
- */
- public void realForwardFull(DoubleLargeArray a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 3D forward DFT of real data leaving the result in a
- * . This method computes full real forward transform, i.e. you will get the
- * same result as from complexForward called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices by rows by 2*columns, with only the first
- * slices by rows by columns elements filled with real data. To get back the
- * original data, use complexInverse on the output of this
- * method.
- *
- * @param a data to transform
- */
- public void realForwardFull(double[][][] a)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, -1, a, true);
- cdft3db_subth(-1, a, true);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, -1, a, true);
- cdft3db_sub(-1, a, true);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealForwardFull(a);
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. The physical layout of the input
- * data has to be as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1*sliceStride + - * k2*rowStride + 2*k3+1] = Im[k1][k2][k3] = - * -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], 0<=k1<slices, - * 0<=k2<rows, 0<k3<columns/2, a[k1*sliceStride + k2*rowStride] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1*sliceStride + - * k2*rowStride + 1] = Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], - * a[k1*sliceStride + (rows-k2)*rowStride + 1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1*sliceStride + (rows-k2)*rowStride] = - * -Im[(slices-k1)%slices][k2][columns/2] = Im[k1][rows-k2][columns/2], - * 0<=k1<slices, 0<k2<rows/2, a[k1*sliceStride] = Re[k1][0][0] = - * Re[slices-k1][0][0], a[k1*sliceStride + 1] = Im[k1][0][0] = - * -Im[slices-k1][0][0], a[k1*sliceStride + (rows/2)*rowStride] = - * Re[k1][rows/2][0] = Re[slices-k1][rows/2][0], a[k1*sliceStride + - * (rows/2)*rowStride + 1] = Im[k1][rows/2][0] = -Im[slices-k1][rows/2][0], - * a[(slices-k1)*sliceStride + 1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[(slices-k1)*sliceStride] = - * -Im[k1][0][columns/2] = Im[slices-k1][0][columns/2], - * a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[(slices-k1)*sliceStride + (rows/2) * rowStride] = - * -Im[k1][rows/2][columns/2] = Im[slices-k1][rows/2][columns/2], - * 0<k1<slices/2, a[0] = Re[0][0][0], a[1] = Re[0][0][columns/2], - * a[(rows/2)*rowStride] = Re[0][rows/2][0], a[(rows/2)*rowStride + 1] = - * Re[0][rows/2][columns/2], a[(slices/2)*sliceStride] = Re[slices/2][0][0], - * a[(slices/2)*sliceStride + 1] = Re[slices/2][0][columns/2], - * a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2][0], - * a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = - * Re[slices/2][rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(double[] a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft3d_sub(-1, a);
- cdft3db_subth(1, a, scale);
- xdft3da_subth1(1, 1, a, scale);
- } else {
- rdft3d_sub(-1, a);
- cdft3db_sub(1, a, scale);
- xdft3da_sub1(1, 1, a, scale);
- }
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 1D array addressed in
- * slice-major, then row-major, then column-major, in order of significance,
- * i.e. element (i,j,k) of 3-d array x[slices][rows][2*columns] is stored in
- * a[i*sliceStride + j*rowStride + k], where sliceStride = rows * 2 *
- * columns and rowStride = 2 * columns. The physical layout of the input
- * data has to be as follows:
- *
- * * - * a[k1*sliceStride + k2*rowStride + 2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1*sliceStride + - * k2*rowStride + 2*k3+1] = Im[k1][k2][k3] = - * -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], 0<=k1<slices, - * 0<=k2<rows, 0<k3<columns/2, a[k1*sliceStride + k2*rowStride] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1*sliceStride + - * k2*rowStride + 1] = Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], - * a[k1*sliceStride + (rows-k2)*rowStride + 1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1*sliceStride + (rows-k2)*rowStride] = - * -Im[(slices-k1)%slices][k2][columns/2] = Im[k1][rows-k2][columns/2], - * 0<=k1<slices, 0<k2<rows/2, a[k1*sliceStride] = Re[k1][0][0] = - * Re[slices-k1][0][0], a[k1*sliceStride + 1] = Im[k1][0][0] = - * -Im[slices-k1][0][0], a[k1*sliceStride + (rows/2)*rowStride] = - * Re[k1][rows/2][0] = Re[slices-k1][rows/2][0], a[k1*sliceStride + - * (rows/2)*rowStride + 1] = Im[k1][rows/2][0] = -Im[slices-k1][rows/2][0], - * a[(slices-k1)*sliceStride + 1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[(slices-k1)*sliceStride] = - * -Im[k1][0][columns/2] = Im[slices-k1][0][columns/2], - * a[(slices-k1)*sliceStride + (rows/2)*rowStride + 1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[(slices-k1)*sliceStride + (rows/2) * rowStride] = - * -Im[k1][rows/2][columns/2] = Im[slices-k1][rows/2][columns/2], - * 0<k1<slices/2, a[0] = Re[0][0][0], a[1] = Re[0][0][columns/2], - * a[(rows/2)*rowStride] = Re[0][rows/2][0], a[(rows/2)*rowStride + 1] = - * Re[0][rows/2][columns/2], a[(slices/2)*sliceStride] = Re[slices/2][0][0], - * a[(slices/2)*sliceStride + 1] = Re[slices/2][0][columns/2], - * a[(slices/2)*sliceStride + (rows/2)*rowStride] = Re[slices/2][rows/2][0], - * a[(slices/2)*sliceStride + (rows/2)*rowStride + 1] = - * Re[slices/2][rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(DoubleLargeArray a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft3d_sub(-1, a);
- cdft3db_subth(1, a, scale);
- xdft3da_subth1(1, 1, a, scale);
- } else {
- rdft3d_sub(-1, a);
- cdft3db_sub(1, a, scale);
- xdft3da_sub1(1, 1, a, scale);
- }
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method only works when the sizes of all three dimensions are
- * power-of-two numbers. The data is stored in a 3D array. The physical
- * layout of the input data has to be as follows:
- *
- * * - * a[k1][k2][2*k3] = Re[k1][k2][k3] = - * Re[(slices-k1)%slices][(rows-k2)%rows][columns-k3], a[k1][k2][2*k3+1] = - * Im[k1][k2][k3] = -Im[(slices-k1)%slices][(rows-k2)%rows][columns-k3], - * 0<=k1<slices, 0<=k2<rows, 0<k3<columns/2, a[k1][k2][0] - * = Re[k1][k2][0] = Re[(slices-k1)%slices][rows-k2][0], a[k1][k2][1] = - * Im[k1][k2][0] = -Im[(slices-k1)%slices][rows-k2][0], a[k1][rows-k2][1] = - * Re[(slices-k1)%slices][k2][columns/2] = Re[k1][rows-k2][columns/2], - * a[k1][rows-k2][0] = -Im[(slices-k1)%slices][k2][columns/2] = - * Im[k1][rows-k2][columns/2], 0<=k1<slices, 0<k2<rows/2, - * a[k1][0][0] = Re[k1][0][0] = Re[slices-k1][0][0], a[k1][0][1] = - * Im[k1][0][0] = -Im[slices-k1][0][0], a[k1][rows/2][0] = Re[k1][rows/2][0] - * = Re[slices-k1][rows/2][0], a[k1][rows/2][1] = Im[k1][rows/2][0] = - * -Im[slices-k1][rows/2][0], a[slices-k1][0][1] = Re[k1][0][columns/2] = - * Re[slices-k1][0][columns/2], a[slices-k1][0][0] = -Im[k1][0][columns/2] = - * Im[slices-k1][0][columns/2], a[slices-k1][rows/2][1] = - * Re[k1][rows/2][columns/2] = Re[slices-k1][rows/2][columns/2], - * a[slices-k1][rows/2][0] = -Im[k1][rows/2][columns/2] = - * Im[slices-k1][rows/2][columns/2], 0<k1<slices/2, a[0][0][0] = - * Re[0][0][0], a[0][0][1] = Re[0][0][columns/2], a[0][rows/2][0] = - * Re[0][rows/2][0], a[0][rows/2][1] = Re[0][rows/2][columns/2], - * a[slices/2][0][0] = Re[slices/2][0][0], a[slices/2][0][1] = - * Re[slices/2][0][columns/2], a[slices/2][rows/2][0] = - * Re[slices/2][rows/2][0], a[slices/2][rows/2][1] = - * Re[slices/2][rows/2][columns/2] - *- * - * This method computes only half of the elements of the real transform. The - * other half satisfies the symmetry condition. If you want the full real - * inverse transform, use
realInverseFull.
- *
- * @param a data to transform
- *
- * @param scale if true then scaling is performed
- */
- public void realInverse(double[][][] a, boolean scale)
- {
- if (isPowerOfTwo == false) {
- throw new IllegalArgumentException("slices, rows and columns must be power of two numbers");
- } else {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- rdft3d_sub(-1, a);
- cdft3db_subth(1, a, scale);
- xdft3da_subth1(1, 1, a, scale);
- } else {
- rdft3d_sub(-1, a);
- cdft3db_sub(1, a, scale);
- xdft3da_sub1(1, 1, a, scale);
- }
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices*rows*2*columns, with only the first
- * slices*rows*columns elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(double[] a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, 1, a, scale);
- cdft3db_subth(1, a, scale);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, 1, a, scale);
- cdft3db_sub(1, a, scale);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices*rows*2*columns, with only the first
- * slices*rows*columns elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(DoubleLargeArray a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, 1, a, scale);
- cdft3db_subth(1, a, scale);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, 1, a, scale);
- cdft3db_sub(1, a, scale);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /**
- * Computes 3D inverse DFT of real data leaving the result in a
- * . This method computes full real inverse transform, i.e. you will get the
- * same result as from complexInverse called with all imaginary
- * part equal 0. Because the result is stored in a, the input
- * array must be of size slices by rows by 2*columns, with only the first
- * slices by rows by columns elements filled with real data.
- *
- * @param a data to transform
- * @param scale if true then scaling is performed
- */
- public void realInverseFull(double[][][] a, boolean scale)
- {
- if (isPowerOfTwo) {
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads) {
- xdft3da_subth2(1, 1, a, scale);
- cdft3db_subth(1, a, scale);
- rdft3d_sub(1, a);
- } else {
- xdft3da_sub2(1, 1, a, scale);
- cdft3db_sub(1, a, scale);
- rdft3d_sub(1, a);
- }
- fillSymmetric(a);
- } else {
- mixedRadixRealInverseFull(a, scale);
- }
- }
-
- /* -------- child routines -------- */
- private void mixedRadixRealForwardFull(final double[][][] a)
- {
- double[] temp = new double[2 * rows];
- int ldimn2 = rows / 2 + 1;
- final int newn3 = 2 * columns;
- final int n2d2;
- if (rows % 2 == 0) {
- n2d2 = rows / 2;
- } else {
- n2d2 = (rows + 1) / 2;
- }
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (columns >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForwardFull(a[s][r]);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * rows];
-
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- temp[idx4] = a[s][r][idx2];
- temp[idx4 + 1] = a[s][r][idx2 + 1];
- }
- fftRows.complexForward(temp);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- a[s][r][idx2] = temp[idx4];
- a[s][r][idx2 + 1] = temp[idx4 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * slices];
-
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- temp[idx2] = a[s][r][idx1];
- temp[idx2 + 1] = a[s][r][idx1 + 1];
- }
- fftSlices.complexForward(temp);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- a[s][r][idx1] = temp[idx2];
- a[s][r][idx1 + 1] = temp[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx2 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = newn3 - idx1;
- a[idx2][idx4][idx3 % newn3] = a[s][r][idx1];
- a[idx2][idx4][(idx3 + 1) % newn3] = -a[s][r][idx1 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForwardFull(a[s][r]);
- }
- }
-
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- temp[idx4] = a[s][r][idx2];
- temp[idx4 + 1] = a[s][r][idx2 + 1];
- }
- fftRows.complexForward(temp);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- a[s][r][idx2] = temp[idx4];
- a[s][r][idx2 + 1] = temp[idx4 + 1];
- }
- }
- }
-
- temp = new double[2 * slices];
-
- for (int r = 0; r < ldimn2; r++) {
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- temp[idx2] = a[s][r][idx1];
- temp[idx2 + 1] = a[s][r][idx1 + 1];
- }
- fftSlices.complexForward(temp);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- a[s][r][idx1] = temp[idx2];
- a[s][r][idx1 + 1] = temp[idx2 + 1];
- }
- }
- }
-
- for (int s = 0; s < slices; s++) {
- int idx2 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = newn3 - idx1;
- a[idx2][idx4][idx3 % newn3] = a[s][r][idx1];
- a[idx2][idx4][(idx3 + 1) % newn3] = -a[s][r][idx1 + 1];
- }
- }
- }
-
- }
- }
-
- private void mixedRadixRealInverseFull(final double[][][] a, final boolean scale)
- {
- double[] temp = new double[2 * rows];
- int ldimn2 = rows / 2 + 1;
- final int newn3 = 2 * columns;
- final int n2d2;
- if (rows % 2 == 0) {
- n2d2 = rows / 2;
- } else {
- n2d2 = (rows + 1) / 2;
- }
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (slices >= nthreads) && (columns >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverseFull(a[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * rows];
-
- for (int s = firstSlice; s < lastSlice; s++) {
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- temp[idx4] = a[s][r][idx2];
- temp[idx4 + 1] = a[s][r][idx2 + 1];
- }
- fftRows.complexInverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- a[s][r][idx2] = temp[idx4];
- a[s][r][idx2 + 1] = temp[idx4 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * slices];
-
- for (int r = firstRow; r < lastRow; r++) {
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- temp[idx2] = a[s][r][idx1];
- temp[idx2 + 1] = a[s][r][idx1 + 1];
- }
- fftSlices.complexInverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- a[s][r][idx1] = temp[idx2];
- a[s][r][idx1 + 1] = temp[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
-
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx2 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = newn3 - idx1;
- a[idx2][idx4][idx3 % newn3] = a[s][r][idx1];
- a[idx2][idx4][(idx3 + 1) % newn3] = -a[s][r][idx1 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int s = 0; s < slices; s++) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverseFull(a[s][r], scale);
- }
- }
-
- for (int s = 0; s < slices; s++) {
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- temp[idx4] = a[s][r][idx2];
- temp[idx4 + 1] = a[s][r][idx2 + 1];
- }
- fftRows.complexInverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- a[s][r][idx2] = temp[idx4];
- a[s][r][idx2 + 1] = temp[idx4 + 1];
- }
- }
- }
-
- temp = new double[2 * slices];
-
- for (int r = 0; r < ldimn2; r++) {
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- temp[idx2] = a[s][r][idx1];
- temp[idx2 + 1] = a[s][r][idx1 + 1];
- }
- fftSlices.complexInverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- a[s][r][idx1] = temp[idx2];
- a[s][r][idx1 + 1] = temp[idx2 + 1];
- }
- }
- }
-
- for (int s = 0; s < slices; s++) {
- int idx2 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = newn3 - idx1;
- a[idx2][idx4][idx3 % newn3] = a[s][r][idx1];
- a[idx2][idx4][(idx3 + 1) % newn3] = -a[s][r][idx1 + 1];
- }
- }
- }
-
- }
- }
-
- private void mixedRadixRealForwardFull(final double[] a)
- {
- final int twon3 = 2 * columns;
- double[] temp = new double[twon3];
- int ldimn2 = rows / 2 + 1;
- final int n2d2;
- if (rows % 2 == 0) {
- n2d2 = rows / 2;
- } else {
- n2d2 = (rows + 1) / 2;
- }
-
- final int twoSliceStride = 2 * sliceStride;
- final int twoRowStride = 2 * rowStride;
- int n1d2 = slices / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads) && (columns >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = n1d2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = slices - 1 - l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice - p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[twon3];
- for (int s = firstSlice; s >= lastSlice; s--) {
- int idx1 = s * sliceStride;
- int idx2 = s * twoSliceStride;
- for (int r = rows - 1; r >= 0; r--) {
- System.arraycopy(a, idx1 + r * rowStride, temp, 0, columns);
- fftColumns.realForwardFull(temp);
- System.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- final double[][][] temp2 = new double[n1d2 + 1][rows][twon3];
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- System.arraycopy(a, idx1 + r * rowStride, temp2[s][r], 0, columns);
- fftColumns.realForwardFull(temp2[s][r]);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * twoSliceStride;
- for (int r = 0; r < rows; r++) {
- System.arraycopy(temp2[s][r], 0, a, idx1 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * rows];
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * twoSliceStride;
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * twoRowStride + idx2;
- int idx4 = 2 * r;
- temp[idx4] = a[idx3];
- temp[idx4 + 1] = a[idx3 + 1];
- }
- fftRows.complexForward(temp);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * twoRowStride + idx2;
- int idx4 = 2 * r;
- a[idx3] = temp[idx4];
- a[idx3 + 1] = temp[idx4 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * slices];
-
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = r * twoRowStride;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- temp[idx2] = a[idx4];
- temp[idx2 + 1] = a[idx4 + 1];
- }
- fftSlices.complexForward(temp);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- a[idx4] = temp[idx2];
- a[idx4 + 1] = temp[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx2 = (slices - s) % slices;
- int idx5 = idx2 * twoSliceStride;
- int idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- int idx7 = idx4 * twoRowStride;
- int idx8 = r * twoRowStride;
- int idx9 = idx5 + idx7;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = twon3 - idx1;
- int idx10 = idx6 + idx8 + idx1;
- a[idx9 + idx3 % twon3] = a[idx10];
- a[idx9 + (idx3 + 1) % twon3] = -a[idx10 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int s = slices - 1; s >= 0; s--) {
- int idx1 = s * sliceStride;
- int idx2 = s * twoSliceStride;
- for (int r = rows - 1; r >= 0; r--) {
- System.arraycopy(a, idx1 + r * rowStride, temp, 0, columns);
- fftColumns.realForwardFull(temp);
- System.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
-
- temp = new double[2 * rows];
-
- for (int s = 0; s < slices; s++) {
- int idx1 = s * twoSliceStride;
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- int idx3 = idx1 + r * twoRowStride + idx2;
- temp[idx4] = a[idx3];
- temp[idx4 + 1] = a[idx3 + 1];
- }
- fftRows.complexForward(temp);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- int idx3 = idx1 + r * twoRowStride + idx2;
- a[idx3] = temp[idx4];
- a[idx3 + 1] = temp[idx4 + 1];
- }
- }
- }
-
- temp = new double[2 * slices];
-
- for (int r = 0; r < ldimn2; r++) {
- int idx3 = r * twoRowStride;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- temp[idx2] = a[idx4];
- temp[idx2 + 1] = a[idx4 + 1];
- }
- fftSlices.complexForward(temp);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- a[idx4] = temp[idx2];
- a[idx4 + 1] = temp[idx2 + 1];
- }
- }
- }
-
- for (int s = 0; s < slices; s++) {
- int idx2 = (slices - s) % slices;
- int idx5 = idx2 * twoSliceStride;
- int idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- int idx7 = idx4 * twoRowStride;
- int idx8 = r * twoRowStride;
- int idx9 = idx5 + idx7;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = twon3 - idx1;
- int idx10 = idx6 + idx8 + idx1;
- a[idx9 + idx3 % twon3] = a[idx10];
- a[idx9 + (idx3 + 1) % twon3] = -a[idx10 + 1];
- }
- }
- }
-
- }
- }
-
- private void mixedRadixRealForwardFull(final DoubleLargeArray a)
- {
- final long twon3 = 2 * columnsl;
- DoubleLargeArray temp = new DoubleLargeArray(twon3, false);
- long ldimn2 = rowsl / 2 + 1;
- final long n2d2;
- if (rowsl % 2 == 0) {
- n2d2 = rowsl / 2;
- } else {
- n2d2 = (rowsl + 1) / 2;
- }
-
- final long twoSliceStride = 2 * sliceStridel;
- final long twoRowStride = 2 * rowStridel;
- long n1d2 = slicesl / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads) && (columnsl >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = n1d2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = slicesl - 1 - l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice - p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(twon3, false);
- for (long s = firstSlice; s >= lastSlice; s--) {
- long idx1 = s * sliceStridel;
- long idx2 = s * twoSliceStride;
- for (long r = rowsl - 1; r >= 0; r--) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp, 0, columnsl);
- fftColumns.realForwardFull(temp);
- Utilities.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- final DoubleLargeArray temp2 = new DoubleLargeArray((n1d2 + 1) * rowsl * twon3, false);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp2, s * rowsl * twon3 + r * twon3, columnsl);
- fftColumns.realForwardFull(temp2, s * rowsl * twon3 + r * twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * twoSliceStride;
- for (long r = 0; r < rowsl; r++) {
- Utilities.arraycopy(temp2, s * rowsl * twon3 + r * twon3, a, idx1 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false);
-
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * twoSliceStride;
- for (long c = 0; c < columnsl; c++) {
- long idx2 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * twoRowStride + idx2;
- long idx4 = 2 * r;
- temp.setDouble(idx4, a.getDouble(idx3));
- temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1));
- }
- fftRows.complexForward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * twoRowStride + idx2;
- long idx4 = 2 * r;
- a.setDouble(idx3, temp.getDouble(idx4));
- a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(2 * slicesl, false);
-
- for (long r = firstRow; r < lastRow; r++) {
- long idx3 = r * twoRowStride;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- temp.setDouble(idx2, a.getDouble(idx4));
- temp.setDouble(idx2 + 1, a.getDouble(idx4 + 1));
- }
- fftSlices.complexForward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- a.setDouble(idx4, temp.getDouble(idx2));
- a.setDouble(idx4 + 1, temp.getDouble(idx2 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx2 = (slicesl - s) % slicesl;
- long idx5 = idx2 * twoSliceStride;
- long idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx4 = rowsl - r;
- long idx7 = idx4 * twoRowStride;
- long idx8 = r * twoRowStride;
- long idx9 = idx5 + idx7;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx3 = twon3 - idx1;
- long idx10 = idx6 + idx8 + idx1;
- a.setDouble(idx9 + idx3 % twon3, a.getDouble(idx10));
- a.setDouble(idx9 + (idx3 + 1) % twon3, -a.getDouble(idx10 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (long s = slicesl - 1; s >= 0; s--) {
- long idx1 = s * sliceStridel;
- long idx2 = s * twoSliceStride;
- for (long r = rowsl - 1; r >= 0; r--) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp, 0, columnsl);
- fftColumns.realForwardFull(temp);
- Utilities.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
-
- temp = new DoubleLargeArray(2 * rowsl, false);
-
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * twoSliceStride;
- for (long c = 0; c < columnsl; c++) {
- long idx2 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx4 = 2 * r;
- long idx3 = idx1 + r * twoRowStride + idx2;
- temp.setDouble(idx4, a.getDouble(idx3));
- temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1));
- }
- fftRows.complexForward(temp);
- for (long r = 0; r < rowsl; r++) {
- long idx4 = 2 * r;
- long idx3 = idx1 + r * twoRowStride + idx2;
- a.setDouble(idx3, temp.getDouble(idx4));
- a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1));
- }
- }
- }
-
- temp = new DoubleLargeArray(2 * slicesl, false);
-
- for (long r = 0; r < ldimn2; r++) {
- long idx3 = r * twoRowStride;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- temp.setDouble(idx2, a.getDouble(idx4));
- temp.setDouble(idx2 + 1, a.getDouble(idx4 + 1));
- }
- fftSlices.complexForward(temp);
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- a.setDouble(idx4, temp.getDouble(idx2));
- a.setDouble(idx4 + 1, temp.getDouble(idx2 + 1));
- }
- }
- }
-
- for (long s = 0; s < slicesl; s++) {
- long idx2 = (slicesl - s) % slicesl;
- long idx5 = idx2 * twoSliceStride;
- long idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx4 = rowsl - r;
- long idx7 = idx4 * twoRowStride;
- long idx8 = r * twoRowStride;
- long idx9 = idx5 + idx7;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx3 = twon3 - idx1;
- long idx10 = idx6 + idx8 + idx1;
- a.setDouble(idx9 + idx3 % twon3, a.getDouble(idx10));
- a.setDouble(idx9 + (idx3 + 1) % twon3, -a.getDouble(idx10 + 1));
- }
- }
- }
-
- }
- }
-
- private void mixedRadixRealInverseFull(final double[] a, final boolean scale)
- {
- final int twon3 = 2 * columns;
- double[] temp = new double[twon3];
- int ldimn2 = rows / 2 + 1;
- final int n2d2;
- if (rows % 2 == 0) {
- n2d2 = rows / 2;
- } else {
- n2d2 = (rows + 1) / 2;
- }
-
- final int twoSliceStride = 2 * sliceStride;
- final int twoRowStride = 2 * rowStride;
- int n1d2 = slices / 2;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads) && (columns >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = n1d2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = slices - 1 - l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice - p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[twon3];
- for (int s = firstSlice; s >= lastSlice; s--) {
- int idx1 = s * sliceStride;
- int idx2 = s * twoSliceStride;
- for (int r = rows - 1; r >= 0; r--) {
- System.arraycopy(a, idx1 + r * rowStride, temp, 0, columns);
- fftColumns.realInverseFull(temp, scale);
- System.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- final double[][][] temp2 = new double[n1d2 + 1][rows][twon3];
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * sliceStride;
- for (int r = 0; r < rows; r++) {
- System.arraycopy(a, idx1 + r * rowStride, temp2[s][r], 0, columns);
- fftColumns.realInverseFull(temp2[s][r], scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * twoSliceStride;
- for (int r = 0; r < rows; r++) {
- System.arraycopy(temp2[s][r], 0, a, idx1 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * rows];
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = s * twoSliceStride;
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * twoRowStride + idx2;
- int idx4 = 2 * r;
- temp[idx4] = a[idx3];
- temp[idx4 + 1] = a[idx3 + 1];
- }
- fftRows.complexInverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx3 = idx1 + r * twoRowStride + idx2;
- int idx4 = 2 * r;
- a[idx3] = temp[idx4];
- a[idx3 + 1] = temp[idx4 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstRow = l * p;
- final int lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- double[] temp = new double[2 * slices];
-
- for (int r = firstRow; r < lastRow; r++) {
- int idx3 = r * twoRowStride;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- temp[idx2] = a[idx4];
- temp[idx2 + 1] = a[idx4 + 1];
- }
- fftSlices.complexInverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- a[idx4] = temp[idx2];
- a[idx4 + 1] = temp[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx2 = (slices - s) % slices;
- int idx5 = idx2 * twoSliceStride;
- int idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- int idx7 = idx4 * twoRowStride;
- int idx8 = r * twoRowStride;
- int idx9 = idx5 + idx7;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = twon3 - idx1;
- int idx10 = idx6 + idx8 + idx1;
- a[idx9 + idx3 % twon3] = a[idx10];
- a[idx9 + (idx3 + 1) % twon3] = -a[idx10 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (int s = slices - 1; s >= 0; s--) {
- int idx1 = s * sliceStride;
- int idx2 = s * twoSliceStride;
- for (int r = rows - 1; r >= 0; r--) {
- System.arraycopy(a, idx1 + r * rowStride, temp, 0, columns);
- fftColumns.realInverseFull(temp, scale);
- System.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
-
- temp = new double[2 * rows];
-
- for (int s = 0; s < slices; s++) {
- int idx1 = s * twoSliceStride;
- for (int c = 0; c < columns; c++) {
- int idx2 = 2 * c;
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- int idx3 = idx1 + r * twoRowStride + idx2;
- temp[idx4] = a[idx3];
- temp[idx4 + 1] = a[idx3 + 1];
- }
- fftRows.complexInverse(temp, scale);
- for (int r = 0; r < rows; r++) {
- int idx4 = 2 * r;
- int idx3 = idx1 + r * twoRowStride + idx2;
- a[idx3] = temp[idx4];
- a[idx3 + 1] = temp[idx4 + 1];
- }
- }
- }
-
- temp = new double[2 * slices];
-
- for (int r = 0; r < ldimn2; r++) {
- int idx3 = r * twoRowStride;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- temp[idx2] = a[idx4];
- temp[idx2 + 1] = a[idx4 + 1];
- }
- fftSlices.complexInverse(temp, scale);
- for (int s = 0; s < slices; s++) {
- int idx2 = 2 * s;
- int idx4 = s * twoSliceStride + idx3 + idx1;
- a[idx4] = temp[idx2];
- a[idx4 + 1] = temp[idx2 + 1];
- }
- }
- }
-
- for (int s = 0; s < slices; s++) {
- int idx2 = (slices - s) % slices;
- int idx5 = idx2 * twoSliceStride;
- int idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = rows - r;
- int idx7 = idx4 * twoRowStride;
- int idx8 = r * twoRowStride;
- int idx9 = idx5 + idx7;
- for (int c = 0; c < columns; c++) {
- int idx1 = 2 * c;
- int idx3 = twon3 - idx1;
- int idx10 = idx6 + idx8 + idx1;
- a[idx9 + idx3 % twon3] = a[idx10];
- a[idx9 + (idx3 + 1) % twon3] = -a[idx10 + 1];
- }
- }
- }
-
- }
- }
-
- private void mixedRadixRealInverseFull(final DoubleLargeArray a, final boolean scale)
- {
- final long twon3 = 2 * columnsl;
- DoubleLargeArray temp = new DoubleLargeArray(twon3, false);
- long ldimn2 = rowsl / 2 + 1;
- final long n2d2;
- if (rowsl % 2 == 0) {
- n2d2 = rowsl / 2;
- } else {
- n2d2 = (rowsl + 1) / 2;
- }
-
- final long twoSliceStride = 2 * sliceStridel;
- final long twoRowStride = 2 * rowStridel;
- long n1d2 = slicesl / 2;
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (n1d2 >= nthreads) && (columnsl >= nthreads) && (ldimn2 >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = n1d2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = slicesl - 1 - l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice - p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(twon3, false);
- for (long s = firstSlice; s >= lastSlice; s--) {
- long idx1 = s * sliceStridel;
- long idx2 = s * twoSliceStride;
- for (long r = rowsl - 1; r >= 0; r--) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp, 0, columnsl);
- fftColumns.realInverseFull(temp, scale);
- Utilities.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- final DoubleLargeArray temp2 = new DoubleLargeArray((n1d2 + 1) * rowsl * twon3, false);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * sliceStridel;
- for (long r = 0; r < rowsl; r++) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp2, s * rowsl * twon3 + r * twon3, columnsl);
- fftColumns.realInverseFull(temp2, s * rowsl * twon3 + r * twon3, scale);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? n1d2 + 1 : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * twoSliceStride;
- for (long r = 0; r < rowsl; r++) {
- Utilities.arraycopy(temp2, s * rowsl * twon3 + r * twon3, a, idx1 + r * twoRowStride, twon3);
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(2 * rowsl, false);
-
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx1 = s * twoSliceStride;
- for (long c = 0; c < columnsl; c++) {
- long idx2 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * twoRowStride + idx2;
- long idx4 = 2 * r;
- temp.setDouble(idx4, a.getDouble(idx3));
- temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1));
- }
- fftRows.complexInverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx3 = idx1 + r * twoRowStride + idx2;
- long idx4 = 2 * r;
- a.setDouble(idx3, temp.getDouble(idx4));
- a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = ldimn2 / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstRow = l * p;
- final long lastRow = (l == (nthreads - 1)) ? ldimn2 : firstRow + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- DoubleLargeArray temp = new DoubleLargeArray(2 * slicesl, false);
-
- for (long r = firstRow; r < lastRow; r++) {
- long idx3 = r * twoRowStride;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- temp.setDouble(idx2, a.getDouble(idx4));
- temp.setDouble(idx2 + 1, a.getDouble(idx4 + 1));
- }
- fftSlices.complexInverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- a.setDouble(idx4, temp.getDouble(idx2));
- a.setDouble(idx4 + 1, temp.getDouble(idx2 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
-
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx2 = (slicesl - s) % slicesl;
- long idx5 = idx2 * twoSliceStride;
- long idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx4 = rowsl - r;
- long idx7 = idx4 * twoRowStride;
- long idx8 = r * twoRowStride;
- long idx9 = idx5 + idx7;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx3 = twon3 - idx1;
- long idx10 = idx6 + idx8 + idx1;
- a.setDouble(idx9 + idx3 % twon3, a.getDouble(idx10));
- a.setDouble(idx9 + (idx3 + 1) % twon3, -a.getDouble(idx10 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- for (long s = slicesl - 1; s >= 0; s--) {
- long idx1 = s * sliceStridel;
- long idx2 = s * twoSliceStride;
- for (long r = rowsl - 1; r >= 0; r--) {
- Utilities.arraycopy(a, idx1 + r * rowStridel, temp, 0, columnsl);
- fftColumns.realInverseFull(temp, scale);
- Utilities.arraycopy(temp, 0, a, idx2 + r * twoRowStride, twon3);
- }
- }
-
- temp = new DoubleLargeArray(2 * rowsl, false);
-
- for (long s = 0; s < slicesl; s++) {
- long idx1 = s * twoSliceStride;
- for (long c = 0; c < columnsl; c++) {
- long idx2 = 2 * c;
- for (long r = 0; r < rowsl; r++) {
- long idx4 = 2 * r;
- long idx3 = idx1 + r * twoRowStride + idx2;
- temp.setDouble(idx4, a.getDouble(idx3));
- temp.setDouble(idx4 + 1, a.getDouble(idx3 + 1));
- }
- fftRows.complexInverse(temp, scale);
- for (long r = 0; r < rowsl; r++) {
- long idx4 = 2 * r;
- long idx3 = idx1 + r * twoRowStride + idx2;
- a.setDouble(idx3, temp.getDouble(idx4));
- a.setDouble(idx3 + 1, temp.getDouble(idx4 + 1));
- }
- }
- }
-
- temp = new DoubleLargeArray(2 * slicesl, false);
-
- for (long r = 0; r < ldimn2; r++) {
- long idx3 = r * twoRowStride;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- temp.setDouble(idx2, a.getDouble(idx4));
- temp.setDouble(idx2 + 1, a.getDouble(idx4 + 1));
- }
- fftSlices.complexInverse(temp, scale);
- for (long s = 0; s < slicesl; s++) {
- long idx2 = 2 * s;
- long idx4 = s * twoSliceStride + idx3 + idx1;
- a.setDouble(idx4, temp.getDouble(idx2));
- a.setDouble(idx4 + 1, temp.getDouble(idx2 + 1));
- }
- }
- }
-
- for (long s = 0; s < slicesl; s++) {
- long idx2 = (slicesl - s) % slicesl;
- long idx5 = idx2 * twoSliceStride;
- long idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx4 = rowsl - r;
- long idx7 = idx4 * twoRowStride;
- long idx8 = r * twoRowStride;
- long idx9 = idx5 + idx7;
- for (long c = 0; c < columnsl; c++) {
- long idx1 = 2 * c;
- long idx3 = twon3 - idx1;
- long idx10 = idx6 + idx8 + idx1;
- a.setDouble(idx9 + idx3 % twon3, a.getDouble(idx10));
- a.setDouble(idx9 + (idx3 + 1) % twon3, -a.getDouble(idx10 + 1));
- }
- }
- }
-
- }
- }
-
- private void xdft3da_sub1(int icr, int isgn, double[] a, boolean scale)
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStride);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, idx0 + r * rowStride);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStride, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- if (icr != 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a, idx0 + r * rowStride, scale);
- }
- }
- }
- }
- }
-
- private void xdft3da_sub1(long icr, int isgn, DoubleLargeArray a, boolean scale)
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1l;
- } else if (columnsl < 4) {
- nt >>= 2l;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStridel);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, idx0 + r * rowStridel);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStridel, scale);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- if (icr != 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse(a, idx0 + r * rowStridel, scale);
- }
- }
- }
- }
- }
-
- private void xdft3da_sub2(int icr, int isgn, double[] a, boolean scale)
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStride);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, idx0 + r * rowStride);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStride, scale);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, idx0 + r * rowStride, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- }
-
- private void xdft3da_sub2(long icr, int isgn, DoubleLargeArray a, boolean scale)
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStridel);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, idx0 + r * rowStridel);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- } else {
- for (long s = 0; s < slicesl; s++) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStridel, scale);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, idx0 + r * rowStridel, scale);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
- }
-
- private void xdft3da_sub1(int icr, int isgn, double[][][] a, boolean scale)
- {
- int idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a[s][r]);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[s][r], 0);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a[s][r], scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- if (icr != 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a[s][r], scale);
- }
- }
- }
- }
- }
-
- private void xdft3da_sub2(int icr, int isgn, double[][][] a, boolean scale)
- {
- int idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- for (int s = 0; s < slices; s++) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a[s][r]);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[s][r]);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- } else {
- for (int s = 0; s < slices; s++) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a[s][r], scale);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[s][r], 0, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- }
- }
-
- private void cdft3db_sub(int isgn, double[] a, boolean scale)
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- fftSlices.complexForward(t, 4 * slices);
- fftSlices.complexForward(t, 6 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftSlices.complexForward(t, 0);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- } else {
- if (columns > 4) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- fftSlices.complexInverse(t, 4 * slices, scale);
- fftSlices.complexInverse(t, 6 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftSlices.complexInverse(t, 0, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- }
-
- private void cdft3db_sub(int isgn, DoubleLargeArray a, boolean scale)
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- DoubleLargeArray t = new DoubleLargeArray(nt, false);
- if (isgn == -1) {
- if (columnsl > 4) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 8) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slicesl);
- fftSlices.complexForward(t, 4 * slicesl);
- fftSlices.complexForward(t, 6 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftSlices.complexForward(t, 0);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- } else {
- if (columnsl > 4) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 8) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slicesl, scale);
- fftSlices.complexInverse(t, 4 * slicesl, scale);
- fftSlices.complexInverse(t, 6 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftSlices.complexInverse(t, 0, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
- }
-
- private void cdft3db_sub(int isgn, double[][][] a, boolean scale)
- {
- int idx2, idx3, idx4, idx5;
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- double[] t = new double[nt];
- if (isgn == -1) {
- if (columns > 4) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- fftSlices.complexForward(t, 4 * slices);
- fftSlices.complexForward(t, 6 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftSlices.complexForward(t, 0);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- } else {
- if (columns > 4) {
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- fftSlices.complexInverse(t, 4 * slices, scale);
- fftSlices.complexInverse(t, 6 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftSlices.complexInverse(t, 0, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- }
- }
-
- private void xdft3da_subth1(final int icr, final int isgn, final double[] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), slices);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStride);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, idx0 + r * rowStride);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
-
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStride, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- if (icr != 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a, idx0 + r * rowStride, scale);
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft3da_subth1(final long icr, final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- int i;
- final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), slicesl);
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStridel);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, idx0 + r * rowStridel);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
-
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStridel, scale);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- if (icr != 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse(a, idx0 + r * rowStridel, scale);
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft3da_subth2(final int icr, final int isgn, final double[] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), slices);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStride);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a, idx0 + r * rowStride);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
-
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- idx0 = s * sliceStride;
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStride, scale);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a, idx0 + r * rowStride, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride + c;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx1 = idx0 + r * rowStride;
- idx2 = 2 * r;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft3da_subth2(final long icr, final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- int i;
- final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), slicesl);
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexForward(a, idx0 + r * rowStridel);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realForward(a, idx0 + r * rowStridel);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- fftRows.complexForward(t, 4 * rowsl);
- fftRows.complexForward(t, 6 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rowsl);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexForward(t, 0);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
-
- }
- } else {
- for (long s = n0; s < slicesl; s += nthreads) {
- idx0 = s * sliceStridel;
- if (icr == 0) {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.complexInverse(a, idx0 + r * rowStridel, scale);
- }
- } else {
- for (long r = 0; r < rowsl; r++) {
- fftColumns.realInverse2(a, idx0 + r * rowStridel, scale);
- }
- }
- if (columnsl > 4) {
- for (long c = 0; c < columnsl; c += 8) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- fftRows.complexInverse(t, 4 * rowsl, scale);
- fftRows.complexInverse(t, 6 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel + c;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- idx4 = idx3 + 2 * rowsl;
- idx5 = idx4 + 2 * rowsl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- } else if (columnsl == 4) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rowsl, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- idx3 = 2 * rowsl + 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- } else if (columnsl == 2) {
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftRows.complexInverse(t, 0, scale);
- for (long r = 0; r < rowsl; r++) {
- idx1 = idx0 + r * rowStridel;
- idx2 = 2 * r;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft3da_subth1(final int icr, final int isgn, final double[][][] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), slices);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a[s][r]);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[s][r], 0);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
-
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a[s][r], scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- if (icr != 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse(a[s][r], scale);
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void xdft3da_subth2(final int icr, final int isgn, final double[][][] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), slices);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- int idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- for (int s = n0; s < slices; s += nthreads) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexForward(a[s][r]);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realForward(a[s][r]);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- fftRows.complexForward(t, 4 * rows);
- fftRows.complexForward(t, 6 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexForward(t, 0);
- fftRows.complexForward(t, 2 * rows);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexForward(t, 0);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
-
- }
- } else {
- for (int s = n0; s < slices; s += nthreads) {
- if (icr == 0) {
- for (int r = 0; r < rows; r++) {
- fftColumns.complexInverse(a[s][r], scale);
- }
- } else {
- for (int r = 0; r < rows; r++) {
- fftColumns.realInverse2(a[s][r], 0, scale);
- }
- }
- if (columns > 4) {
- for (int c = 0; c < columns; c += 8) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- fftRows.complexInverse(t, 4 * rows, scale);
- fftRows.complexInverse(t, 6 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- idx4 = idx3 + 2 * rows;
- idx5 = idx4 + 2 * rows;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- } else if (columns == 4) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftRows.complexInverse(t, 0, scale);
- fftRows.complexInverse(t, 2 * rows, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- idx3 = 2 * rows + 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- } else if (columns == 2) {
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftRows.complexInverse(t, 0, scale);
- for (int r = 0; r < rows; r++) {
- idx2 = 2 * r;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft3db_subth(final int isgn, final double[] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), rows);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
-
- public void run()
- {
- int idx0, idx1, idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 4) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- fftSlices.complexForward(t, 4 * slices);
- fftSlices.complexForward(t, 6 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftSlices.complexForward(t, 0);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- } else {
- if (columns > 4) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- t[idx4] = a[idx1 + 4];
- t[idx4 + 1] = a[idx1 + 5];
- t[idx5] = a[idx1 + 6];
- t[idx5 + 1] = a[idx1 + 7];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- fftSlices.complexInverse(t, 4 * slices, scale);
- fftSlices.complexInverse(t, 6 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- a[idx1 + 4] = t[idx4];
- a[idx1 + 5] = t[idx4 + 1];
- a[idx1 + 6] = t[idx5];
- a[idx1 + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- t[idx3] = a[idx1 + 2];
- t[idx3 + 1] = a[idx1 + 3];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- a[idx1 + 2] = t[idx3];
- a[idx1 + 3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- idx0 = r * rowStride;
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- t[idx2] = a[idx1];
- t[idx2 + 1] = a[idx1 + 1];
- }
- fftSlices.complexInverse(t, 0, scale);
- for (int s = 0; s < slices; s++) {
- idx1 = s * sliceStride + idx0;
- idx2 = 2 * s;
- a[idx1] = t[idx2];
- a[idx1 + 1] = t[idx2 + 1];
- }
- }
- }
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft3db_subth(final int isgn, final DoubleLargeArray a, final boolean scale)
- {
- int i;
- final int nthreads = (int) Math.min(ConcurrencyUtils.getNumberOfThreads(), rowsl);
- long nt = slicesl;
- if (nt < rowsl) {
- nt = rowsl;
- }
- nt *= 8;
- if (columnsl == 4) {
- nt >>= 1;
- } else if (columnsl < 4) {
- nt >>= 2;
- }
- final long ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final long n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
-
- public void run()
- {
- long idx0, idx1, idx2, idx3, idx4, idx5;
- DoubleLargeArray t = new DoubleLargeArray(ntf, false);
- if (isgn == -1) {
- if (columnsl > 4) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 8) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slicesl);
- fftSlices.complexForward(t, 4 * slicesl);
- fftSlices.complexForward(t, 6 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- }
- } else if (columnsl == 4) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slicesl);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftSlices.complexForward(t, 0);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- } else {
- if (columnsl > 4) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long c = 0; c < columnsl; c += 8) {
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- t.setDouble(idx4, a.getDouble(idx1 + 4));
- t.setDouble(idx4 + 1, a.getDouble(idx1 + 5));
- t.setDouble(idx5, a.getDouble(idx1 + 6));
- t.setDouble(idx5 + 1, a.getDouble(idx1 + 7));
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slicesl, scale);
- fftSlices.complexInverse(t, 4 * slicesl, scale);
- fftSlices.complexInverse(t, 6 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0 + c;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- idx4 = idx3 + 2 * slicesl;
- idx5 = idx4 + 2 * slicesl;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- a.setDouble(idx1 + 4, t.getDouble(idx4));
- a.setDouble(idx1 + 5, t.getDouble(idx4 + 1));
- a.setDouble(idx1 + 6, t.getDouble(idx5));
- a.setDouble(idx1 + 7, t.getDouble(idx5 + 1));
- }
- }
- }
- } else if (columnsl == 4) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- t.setDouble(idx3, a.getDouble(idx1 + 2));
- t.setDouble(idx3 + 1, a.getDouble(idx1 + 3));
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slicesl, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- idx3 = 2 * slicesl + 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- a.setDouble(idx1 + 2, t.getDouble(idx3));
- a.setDouble(idx1 + 3, t.getDouble(idx3 + 1));
- }
- }
- } else if (columnsl == 2) {
- for (long r = n0; r < rowsl; r += nthreads) {
- idx0 = r * rowStridel;
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- t.setDouble(idx2, a.getDouble(idx1));
- t.setDouble(idx2 + 1, a.getDouble(idx1 + 1));
- }
- fftSlices.complexInverse(t, 0, scale);
- for (long s = 0; s < slicesl; s++) {
- idx1 = s * sliceStridel + idx0;
- idx2 = 2 * s;
- a.setDouble(idx1, t.getDouble(idx2));
- a.setDouble(idx1 + 1, t.getDouble(idx2 + 1));
- }
- }
- }
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void cdft3db_subth(final int isgn, final double[][][] a, final boolean scale)
- {
- int i;
- final int nthreads = Math.min(ConcurrencyUtils.getNumberOfThreads(), rows);
- int nt = slices;
- if (nt < rows) {
- nt = rows;
- }
- nt *= 8;
- if (columns == 4) {
- nt >>= 1;
- } else if (columns < 4) {
- nt >>= 2;
- }
- final int ntf = nt;
- Future>[] futures = new Future[nthreads];
- for (i = 0; i < nthreads; i++) {
- final int n0 = i;
- futures[i] = ConcurrencyUtils.submit(new Runnable()
- {
-
- public void run()
- {
- int idx2, idx3, idx4, idx5;
- double[] t = new double[ntf];
- if (isgn == -1) {
- if (columns > 4) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- fftSlices.complexForward(t, 4 * slices);
- fftSlices.complexForward(t, 6 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftSlices.complexForward(t, 0);
- fftSlices.complexForward(t, 2 * slices);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftSlices.complexForward(t, 0);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- } else {
- if (columns > 4) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int c = 0; c < columns; c += 8) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- t[idx2] = a[s][r][c];
- t[idx2 + 1] = a[s][r][c + 1];
- t[idx3] = a[s][r][c + 2];
- t[idx3 + 1] = a[s][r][c + 3];
- t[idx4] = a[s][r][c + 4];
- t[idx4 + 1] = a[s][r][c + 5];
- t[idx5] = a[s][r][c + 6];
- t[idx5 + 1] = a[s][r][c + 7];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- fftSlices.complexInverse(t, 4 * slices, scale);
- fftSlices.complexInverse(t, 6 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- idx4 = idx3 + 2 * slices;
- idx5 = idx4 + 2 * slices;
- a[s][r][c] = t[idx2];
- a[s][r][c + 1] = t[idx2 + 1];
- a[s][r][c + 2] = t[idx3];
- a[s][r][c + 3] = t[idx3 + 1];
- a[s][r][c + 4] = t[idx4];
- a[s][r][c + 5] = t[idx4 + 1];
- a[s][r][c + 6] = t[idx5];
- a[s][r][c + 7] = t[idx5 + 1];
- }
- }
- }
- } else if (columns == 4) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- t[idx3] = a[s][r][2];
- t[idx3 + 1] = a[s][r][3];
- }
- fftSlices.complexInverse(t, 0, scale);
- fftSlices.complexInverse(t, 2 * slices, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- idx3 = 2 * slices + 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- a[s][r][2] = t[idx3];
- a[s][r][3] = t[idx3 + 1];
- }
- }
- } else if (columns == 2) {
- for (int r = n0; r < rows; r += nthreads) {
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- t[idx2] = a[s][r][0];
- t[idx2 + 1] = a[s][r][1];
- }
- fftSlices.complexInverse(t, 0, scale);
- for (int s = 0; s < slices; s++) {
- idx2 = 2 * s;
- a[s][r][0] = t[idx2];
- a[s][r][1] = t[idx2 + 1];
- }
- }
- }
- }
-
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- }
-
- private void rdft3d_sub(int isgn, double[] a)
- {
- int n1h, n2h, i, j, k, l, idx1, idx2, idx3, idx4;
- double xi;
-
- n1h = slices >> 1;
- n2h = rows >> 1;
- if (isgn < 0) {
- for (i = 1; i < n1h; i++) {
- j = slices - i;
- idx1 = i * sliceStride;
- idx2 = j * sliceStride;
- idx3 = i * sliceStride + n2h * rowStride;
- idx4 = j * sliceStride + n2h * rowStride;
- xi = a[idx1] - a[idx2];
- a[idx1] += a[idx2];
- a[idx2] = xi;
- xi = a[idx2 + 1] - a[idx1 + 1];
- a[idx1 + 1] += a[idx2 + 1];
- a[idx2 + 1] = xi;
- xi = a[idx3] - a[idx4];
- a[idx3] += a[idx4];
- a[idx4] = xi;
- xi = a[idx4 + 1] - a[idx3 + 1];
- a[idx3 + 1] += a[idx4 + 1];
- a[idx4 + 1] = xi;
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- idx1 = i * sliceStride + k * rowStride;
- idx2 = j * sliceStride + l * rowStride;
- xi = a[idx1] - a[idx2];
- a[idx1] += a[idx2];
- a[idx2] = xi;
- xi = a[idx2 + 1] - a[idx1 + 1];
- a[idx1 + 1] += a[idx2 + 1];
- a[idx2 + 1] = xi;
- idx3 = j * sliceStride + k * rowStride;
- idx4 = i * sliceStride + l * rowStride;
- xi = a[idx3] - a[idx4];
- a[idx3] += a[idx4];
- a[idx4] = xi;
- xi = a[idx4 + 1] - a[idx3 + 1];
- a[idx3 + 1] += a[idx4 + 1];
- a[idx4 + 1] = xi;
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- idx1 = k * rowStride;
- idx2 = l * rowStride;
- xi = a[idx1] - a[idx2];
- a[idx1] += a[idx2];
- a[idx2] = xi;
- xi = a[idx2 + 1] - a[idx1 + 1];
- a[idx1 + 1] += a[idx2 + 1];
- a[idx2 + 1] = xi;
- idx3 = n1h * sliceStride + k * rowStride;
- idx4 = n1h * sliceStride + l * rowStride;
- xi = a[idx3] - a[idx4];
- a[idx3] += a[idx4];
- a[idx4] = xi;
- xi = a[idx4 + 1] - a[idx3 + 1];
- a[idx3 + 1] += a[idx4 + 1];
- a[idx4 + 1] = xi;
- }
- } else {
- for (i = 1; i < n1h; i++) {
- j = slices - i;
- idx1 = j * sliceStride;
- idx2 = i * sliceStride;
- a[idx1] = 0.5f * (a[idx2] - a[idx1]);
- a[idx2] -= a[idx1];
- a[idx1 + 1] = 0.5f * (a[idx2 + 1] + a[idx1 + 1]);
- a[idx2 + 1] -= a[idx1 + 1];
- idx3 = j * sliceStride + n2h * rowStride;
- idx4 = i * sliceStride + n2h * rowStride;
- a[idx3] = 0.5f * (a[idx4] - a[idx3]);
- a[idx4] -= a[idx3];
- a[idx3 + 1] = 0.5f * (a[idx4 + 1] + a[idx3 + 1]);
- a[idx4 + 1] -= a[idx3 + 1];
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- idx1 = j * sliceStride + l * rowStride;
- idx2 = i * sliceStride + k * rowStride;
- a[idx1] = 0.5f * (a[idx2] - a[idx1]);
- a[idx2] -= a[idx1];
- a[idx1 + 1] = 0.5f * (a[idx2 + 1] + a[idx1 + 1]);
- a[idx2 + 1] -= a[idx1 + 1];
- idx3 = i * sliceStride + l * rowStride;
- idx4 = j * sliceStride + k * rowStride;
- a[idx3] = 0.5f * (a[idx4] - a[idx3]);
- a[idx4] -= a[idx3];
- a[idx3 + 1] = 0.5f * (a[idx4 + 1] + a[idx3 + 1]);
- a[idx4 + 1] -= a[idx3 + 1];
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- idx1 = l * rowStride;
- idx2 = k * rowStride;
- a[idx1] = 0.5f * (a[idx2] - a[idx1]);
- a[idx2] -= a[idx1];
- a[idx1 + 1] = 0.5f * (a[idx2 + 1] + a[idx1 + 1]);
- a[idx2 + 1] -= a[idx1 + 1];
- idx3 = n1h * sliceStride + l * rowStride;
- idx4 = n1h * sliceStride + k * rowStride;
- a[idx3] = 0.5f * (a[idx4] - a[idx3]);
- a[idx4] -= a[idx3];
- a[idx3 + 1] = 0.5f * (a[idx4 + 1] + a[idx3 + 1]);
- a[idx4 + 1] -= a[idx3 + 1];
- }
- }
- }
-
- private void rdft3d_sub(int isgn, DoubleLargeArray a)
- {
- long n1h, n2h, i, j, k, l, idx1, idx2, idx3, idx4;
- double xi;
-
- n1h = slicesl >> 1l;
- n2h = rowsl >> 1l;
- if (isgn < 0) {
- for (i = 1; i < n1h; i++) {
- j = slicesl - i;
- idx1 = i * sliceStridel;
- idx2 = j * sliceStridel;
- idx3 = i * sliceStridel + n2h * rowStridel;
- idx4 = j * sliceStridel + n2h * rowStridel;
- xi = a.getDouble(idx1) - a.getDouble(idx2);
- a.setDouble(idx1, a.getDouble(idx1) + a.getDouble(idx2));
- a.setDouble(idx2, xi);
- xi = a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1));
- a.setDouble(idx2 + 1, xi);
- xi = a.getDouble(idx3) - a.getDouble(idx4);
- a.setDouble(idx3, a.getDouble(idx3) + a.getDouble(idx4));
- a.setDouble(idx4, xi);
- xi = a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1);
- a.setDouble(idx3 + 1, a.getDouble(idx3 + 1) + a.getDouble(idx4 + 1));
- a.setDouble(idx4 + 1, xi);
- for (k = 1; k < n2h; k++) {
- l = rowsl - k;
- idx1 = i * sliceStridel + k * rowStridel;
- idx2 = j * sliceStridel + l * rowStridel;
- xi = a.getDouble(idx1) - a.getDouble(idx2);
- a.setDouble(idx1, a.getDouble(idx1) + a.getDouble(idx2));
- a.setDouble(idx2, xi);
- xi = a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1));
- a.setDouble(idx2 + 1, xi);
- idx3 = j * sliceStridel + k * rowStridel;
- idx4 = i * sliceStridel + l * rowStridel;
- xi = a.getDouble(idx3) - a.getDouble(idx4);
- a.setDouble(idx3, a.getDouble(idx3) + a.getDouble(idx4));
- a.setDouble(idx4, xi);
- xi = a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1);
- a.setDouble(idx3 + 1, a.getDouble(idx3 + 1) + a.getDouble(idx4 + 1));
- a.setDouble(idx4 + 1, xi);
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rowsl - k;
- idx1 = k * rowStridel;
- idx2 = l * rowStridel;
- xi = a.getDouble(idx1) - a.getDouble(idx2);
- a.setDouble(idx1, a.getDouble(idx1) + a.getDouble(idx2));
- a.setDouble(idx2, xi);
- xi = a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1);
- a.setDouble(idx1 + 1, a.getDouble(idx1 + 1) + a.getDouble(idx2 + 1));
- a.setDouble(idx2 + 1, xi);
- idx3 = n1h * sliceStridel + k * rowStridel;
- idx4 = n1h * sliceStridel + l * rowStridel;
- xi = a.getDouble(idx3) - a.getDouble(idx4);
- a.setDouble(idx3, a.getDouble(idx3) + a.getDouble(idx4));
- a.setDouble(idx4, xi);
- xi = a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1);
- a.setDouble(idx3 + 1, a.getDouble(idx3 + 1) + a.getDouble(idx4 + 1));
- a.setDouble(idx4 + 1, xi);
- }
- } else {
- for (i = 1; i < n1h; i++) {
- j = slicesl - i;
- idx1 = j * sliceStridel;
- idx2 = i * sliceStridel;
- a.setDouble(idx1, 0.5f * (a.getDouble(idx2) - a.getDouble(idx1)));
- a.setDouble(idx2, a.getDouble(idx2) - a.getDouble(idx1));
- a.setDouble(idx1 + 1, 0.5f * (a.getDouble(idx2 + 1) + a.getDouble(idx1 + 1)));
- a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1));
- idx3 = j * sliceStridel + n2h * rowStridel;
- idx4 = i * sliceStridel + n2h * rowStridel;
- a.setDouble(idx3, 0.5f * (a.getDouble(idx4) - a.getDouble(idx3)));
- a.setDouble(idx4, a.getDouble(idx4) - a.getDouble(idx3));
- a.setDouble(idx3 + 1, 0.5f * (a.getDouble(idx4 + 1) + a.getDouble(idx3 + 1)));
- a.setDouble(idx4 + 1, a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1));
- for (k = 1; k < n2h; k++) {
- l = rowsl - k;
- idx1 = j * sliceStridel + l * rowStridel;
- idx2 = i * sliceStridel + k * rowStridel;
- a.setDouble(idx1, 0.5f * (a.getDouble(idx2) - a.getDouble(idx1)));
- a.setDouble(idx2, a.getDouble(idx2) - a.getDouble(idx1));
- a.setDouble(idx1 + 1, 0.5f * (a.getDouble(idx2 + 1) + a.getDouble(idx1 + 1)));
- a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1));
- idx3 = i * sliceStridel + l * rowStridel;
- idx4 = j * sliceStridel + k * rowStridel;
- a.setDouble(idx3, 0.5f * (a.getDouble(idx4) - a.getDouble(idx3)));
- a.setDouble(idx4, a.getDouble(idx4) - a.getDouble(idx3));
- a.setDouble(idx3 + 1, 0.5f * (a.getDouble(idx4 + 1) + a.getDouble(idx3 + 1)));
- a.setDouble(idx4 + 1, a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1));
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rowsl - k;
- idx1 = l * rowStridel;
- idx2 = k * rowStridel;
- a.setDouble(idx1, 0.5f * (a.getDouble(idx2) - a.getDouble(idx1)));
- a.setDouble(idx2, a.getDouble(idx2) - a.getDouble(idx1));
- a.setDouble(idx1 + 1, 0.5f * (a.getDouble(idx2 + 1) + a.getDouble(idx1 + 1)));
- a.setDouble(idx2 + 1, a.getDouble(idx2 + 1) - a.getDouble(idx1 + 1));
- idx3 = n1h * sliceStridel + l * rowStridel;
- idx4 = n1h * sliceStridel + k * rowStridel;
- a.setDouble(idx3, 0.5f * (a.getDouble(idx4) - a.getDouble(idx3)));
- a.setDouble(idx4, a.getDouble(idx4) - a.getDouble(idx3));
- a.setDouble(idx3 + 1, 0.5f * (a.getDouble(idx4 + 1) + a.getDouble(idx3 + 1)));
- a.setDouble(idx4 + 1, a.getDouble(idx4 + 1) - a.getDouble(idx3 + 1));
- }
- }
- }
-
- private void rdft3d_sub(int isgn, double[][][] a)
- {
- int n1h, n2h, i, j, k, l;
- double xi;
-
- n1h = slices >> 1;
- n2h = rows >> 1;
- if (isgn < 0) {
- for (i = 1; i < n1h; i++) {
- j = slices - i;
- xi = a[i][0][0] - a[j][0][0];
- a[i][0][0] += a[j][0][0];
- a[j][0][0] = xi;
- xi = a[j][0][1] - a[i][0][1];
- a[i][0][1] += a[j][0][1];
- a[j][0][1] = xi;
- xi = a[i][n2h][0] - a[j][n2h][0];
- a[i][n2h][0] += a[j][n2h][0];
- a[j][n2h][0] = xi;
- xi = a[j][n2h][1] - a[i][n2h][1];
- a[i][n2h][1] += a[j][n2h][1];
- a[j][n2h][1] = xi;
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- xi = a[i][k][0] - a[j][l][0];
- a[i][k][0] += a[j][l][0];
- a[j][l][0] = xi;
- xi = a[j][l][1] - a[i][k][1];
- a[i][k][1] += a[j][l][1];
- a[j][l][1] = xi;
- xi = a[j][k][0] - a[i][l][0];
- a[j][k][0] += a[i][l][0];
- a[i][l][0] = xi;
- xi = a[i][l][1] - a[j][k][1];
- a[j][k][1] += a[i][l][1];
- a[i][l][1] = xi;
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- xi = a[0][k][0] - a[0][l][0];
- a[0][k][0] += a[0][l][0];
- a[0][l][0] = xi;
- xi = a[0][l][1] - a[0][k][1];
- a[0][k][1] += a[0][l][1];
- a[0][l][1] = xi;
- xi = a[n1h][k][0] - a[n1h][l][0];
- a[n1h][k][0] += a[n1h][l][0];
- a[n1h][l][0] = xi;
- xi = a[n1h][l][1] - a[n1h][k][1];
- a[n1h][k][1] += a[n1h][l][1];
- a[n1h][l][1] = xi;
- }
- } else {
- for (i = 1; i < n1h; i++) {
- j = slices - i;
- a[j][0][0] = 0.5f * (a[i][0][0] - a[j][0][0]);
- a[i][0][0] -= a[j][0][0];
- a[j][0][1] = 0.5f * (a[i][0][1] + a[j][0][1]);
- a[i][0][1] -= a[j][0][1];
- a[j][n2h][0] = 0.5f * (a[i][n2h][0] - a[j][n2h][0]);
- a[i][n2h][0] -= a[j][n2h][0];
- a[j][n2h][1] = 0.5f * (a[i][n2h][1] + a[j][n2h][1]);
- a[i][n2h][1] -= a[j][n2h][1];
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- a[j][l][0] = 0.5f * (a[i][k][0] - a[j][l][0]);
- a[i][k][0] -= a[j][l][0];
- a[j][l][1] = 0.5f * (a[i][k][1] + a[j][l][1]);
- a[i][k][1] -= a[j][l][1];
- a[i][l][0] = 0.5f * (a[j][k][0] - a[i][l][0]);
- a[j][k][0] -= a[i][l][0];
- a[i][l][1] = 0.5f * (a[j][k][1] + a[i][l][1]);
- a[j][k][1] -= a[i][l][1];
- }
- }
- for (k = 1; k < n2h; k++) {
- l = rows - k;
- a[0][l][0] = 0.5f * (a[0][k][0] - a[0][l][0]);
- a[0][k][0] -= a[0][l][0];
- a[0][l][1] = 0.5f * (a[0][k][1] + a[0][l][1]);
- a[0][k][1] -= a[0][l][1];
- a[n1h][l][0] = 0.5f * (a[n1h][k][0] - a[n1h][l][0]);
- a[n1h][k][0] -= a[n1h][l][0];
- a[n1h][l][1] = 0.5f * (a[n1h][k][1] + a[n1h][l][1]);
- a[n1h][k][1] -= a[n1h][l][1];
- }
- }
- }
-
- private void fillSymmetric(final double[][][] a)
- {
- final int twon3 = 2 * columns;
- final int n2d2 = rows / 2;
- int n1d2 = slices / 2;
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (slices >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 0; r < rows; r++) {
- int idx2 = (rows - r) % rows;
- for (int c = 1; c < columns; c += 2) {
- int idx3 = twon3 - c;
- a[idx1][idx2][idx3] = -a[s][r][c + 2];
- a[idx1][idx2][idx3 - 1] = a[s][r][c + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- // ---------------------------------------------
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx2 = rows - r;
- a[idx1][r][columns] = a[s][idx2][1];
- a[s][idx2][columns] = a[s][idx2][1];
- a[idx1][r][columns + 1] = -a[s][idx2][0];
- a[s][idx2][columns + 1] = a[s][idx2][0];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx2 = rows - r;
- a[idx1][idx2][0] = a[s][r][0];
- a[idx1][idx2][1] = -a[s][r][1];
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- } else {
-
- for (int s = 0; s < slices; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 0; r < rows; r++) {
- int idx2 = (rows - r) % rows;
- for (int c = 1; c < columns; c += 2) {
- int idx3 = twon3 - c;
- a[idx1][idx2][idx3] = -a[s][r][c + 2];
- a[idx1][idx2][idx3 - 1] = a[s][r][c + 1];
- }
- }
- }
-
- // ---------------------------------------------
- for (int s = 0; s < slices; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx2 = rows - r;
- a[idx1][r][columns] = a[s][idx2][1];
- a[s][idx2][columns] = a[s][idx2][1];
- a[idx1][r][columns + 1] = -a[s][idx2][0];
- a[s][idx2][columns + 1] = a[s][idx2][0];
- }
- }
-
- for (int s = 0; s < slices; s++) {
- int idx1 = (slices - s) % slices;
- for (int r = 1; r < n2d2; r++) {
- int idx2 = rows - r;
- a[idx1][idx2][0] = a[s][r][0];
- a[idx1][idx2][1] = -a[s][r][1];
- }
- }
- }
-
- // ----------------------------------------------------------
- for (int s = 1; s < n1d2; s++) {
- int idx1 = slices - s;
- a[s][0][columns] = a[idx1][0][1];
- a[idx1][0][columns] = a[idx1][0][1];
- a[s][0][columns + 1] = -a[idx1][0][0];
- a[idx1][0][columns + 1] = a[idx1][0][0];
- a[s][n2d2][columns] = a[idx1][n2d2][1];
- a[idx1][n2d2][columns] = a[idx1][n2d2][1];
- a[s][n2d2][columns + 1] = -a[idx1][n2d2][0];
- a[idx1][n2d2][columns + 1] = a[idx1][n2d2][0];
- a[idx1][0][0] = a[s][0][0];
- a[idx1][0][1] = -a[s][0][1];
- a[idx1][n2d2][0] = a[s][n2d2][0];
- a[idx1][n2d2][1] = -a[s][n2d2][1];
-
- }
- // ----------------------------------------
-
- a[0][0][columns] = a[0][0][1];
- a[0][0][1] = 0;
- a[0][n2d2][columns] = a[0][n2d2][1];
- a[0][n2d2][1] = 0;
- a[n1d2][0][columns] = a[n1d2][0][1];
- a[n1d2][0][1] = 0;
- a[n1d2][n2d2][columns] = a[n1d2][n2d2][1];
- a[n1d2][n2d2][1] = 0;
- a[n1d2][0][columns + 1] = 0;
- a[n1d2][n2d2][columns + 1] = 0;
- }
-
- private void fillSymmetric(final double[] a)
- {
- final int twon3 = 2 * columns;
- final int n2d2 = rows / 2;
- int n1d2 = slices / 2;
-
- final int twoSliceStride = rows * twon3;
- final int twoRowStride = twon3;
-
- int idx1, idx2, idx3, idx4, idx5, idx6;
-
- for (int s = (slices - 1); s >= 1; s--) {
- idx3 = s * sliceStride;
- idx4 = 2 * idx3;
- for (int r = 0; r < rows; r++) {
- idx5 = r * rowStride;
- idx6 = 2 * idx5;
- for (int c = 0; c < columns; c += 2) {
- idx1 = idx3 + idx5 + c;
- idx2 = idx4 + idx6 + c;
- a[idx2] = a[idx1];
- a[idx1] = 0;
- idx1++;
- idx2++;
- a[idx2] = a[idx1];
- a[idx1] = 0;
- }
- }
- }
-
- for (int r = 1; r < rows; r++) {
- idx3 = (rows - r) * rowStride;
- idx4 = (rows - r) * twoRowStride;
- for (int c = 0; c < columns; c += 2) {
- idx1 = idx3 + c;
- idx2 = idx4 + c;
- a[idx2] = a[idx1];
- a[idx1] = 0;
- idx1++;
- idx2++;
- a[idx2] = a[idx1];
- a[idx1] = 0;
- }
- }
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (slices >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- int p = slices / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx3 = ((slices - s) % slices) * twoSliceStride;
- int idx5 = s * twoSliceStride;
- for (int r = 0; r < rows; r++) {
- int idx4 = ((rows - r) % rows) * twoRowStride;
- int idx6 = r * twoRowStride;
- for (int c = 1; c < columns; c += 2) {
- int idx1 = idx3 + idx4 + twon3 - c;
- int idx2 = idx5 + idx6 + c;
- a[idx1] = -a[idx2 + 2];
- a[idx1 - 1] = a[idx2 + 1];
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- // ---------------------------------------------
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx5 = ((slices - s) % slices) * twoSliceStride;
- int idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx4 = idx6 + (rows - r) * twoRowStride;
- int idx1 = idx5 + r * twoRowStride + columns;
- int idx2 = idx4 + columns;
- int idx3 = idx4 + 1;
- a[idx1] = a[idx3];
- a[idx2] = a[idx3];
- a[idx1 + 1] = -a[idx4];
- a[idx2 + 1] = a[idx4];
-
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- for (int l = 0; l < nthreads; l++) {
- final int firstSlice = l * p;
- final int lastSlice = (l == (nthreads - 1)) ? slices : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (int s = firstSlice; s < lastSlice; s++) {
- int idx3 = ((slices - s) % slices) * twoSliceStride;
- int idx4 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- int idx1 = idx3 + (rows - r) * twoRowStride;
- int idx2 = idx4 + r * twoRowStride;
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
-
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- // -----------------------------------------------
- for (int s = 0; s < slices; s++) {
- idx3 = ((slices - s) % slices) * twoSliceStride;
- idx5 = s * twoSliceStride;
- for (int r = 0; r < rows; r++) {
- idx4 = ((rows - r) % rows) * twoRowStride;
- idx6 = r * twoRowStride;
- for (int c = 1; c < columns; c += 2) {
- idx1 = idx3 + idx4 + twon3 - c;
- idx2 = idx5 + idx6 + c;
- a[idx1] = -a[idx2 + 2];
- a[idx1 - 1] = a[idx2 + 1];
- }
- }
- }
-
- // ---------------------------------------------
- for (int s = 0; s < slices; s++) {
- idx5 = ((slices - s) % slices) * twoSliceStride;
- idx6 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- idx4 = idx6 + (rows - r) * twoRowStride;
- idx1 = idx5 + r * twoRowStride + columns;
- idx2 = idx4 + columns;
- idx3 = idx4 + 1;
- a[idx1] = a[idx3];
- a[idx2] = a[idx3];
- a[idx1 + 1] = -a[idx4];
- a[idx2 + 1] = a[idx4];
-
- }
- }
-
- for (int s = 0; s < slices; s++) {
- idx3 = ((slices - s) % slices) * twoSliceStride;
- idx4 = s * twoSliceStride;
- for (int r = 1; r < n2d2; r++) {
- idx1 = idx3 + (rows - r) * twoRowStride;
- idx2 = idx4 + r * twoRowStride;
- a[idx1] = a[idx2];
- a[idx1 + 1] = -a[idx2 + 1];
-
- }
- }
- }
-
- // ----------------------------------------------------------
- for (int s = 1; s < n1d2; s++) {
- idx1 = s * twoSliceStride;
- idx2 = (slices - s) * twoSliceStride;
- idx3 = n2d2 * twoRowStride;
- idx4 = idx1 + idx3;
- idx5 = idx2 + idx3;
- a[idx1 + columns] = a[idx2 + 1];
- a[idx2 + columns] = a[idx2 + 1];
- a[idx1 + columns + 1] = -a[idx2];
- a[idx2 + columns + 1] = a[idx2];
- a[idx4 + columns] = a[idx5 + 1];
- a[idx5 + columns] = a[idx5 + 1];
- a[idx4 + columns + 1] = -a[idx5];
- a[idx5 + columns + 1] = a[idx5];
- a[idx2] = a[idx1];
- a[idx2 + 1] = -a[idx1 + 1];
- a[idx5] = a[idx4];
- a[idx5 + 1] = -a[idx4 + 1];
-
- }
-
- // ----------------------------------------
- a[columns] = a[1];
- a[1] = 0;
- idx1 = n2d2 * twoRowStride;
- idx2 = n1d2 * twoSliceStride;
- idx3 = idx1 + idx2;
- a[idx1 + columns] = a[idx1 + 1];
- a[idx1 + 1] = 0;
- a[idx2 + columns] = a[idx2 + 1];
- a[idx2 + 1] = 0;
- a[idx3 + columns] = a[idx3 + 1];
- a[idx3 + 1] = 0;
- a[idx2 + columns + 1] = 0;
- a[idx3 + columns + 1] = 0;
- }
-
- private void fillSymmetric(final DoubleLargeArray a)
- {
- final long twon3 = 2 * columnsl;
- final long n2d2 = rowsl / 2;
- long n1d2 = slicesl / 2;
-
- final long twoSliceStride = rowsl * twon3;
- final long twoRowStride = twon3;
-
- long idx1, idx2, idx3, idx4, idx5, idx6;
-
- for (long s = (slicesl - 1); s >= 1; s--) {
- idx3 = s * sliceStridel;
- idx4 = 2 * idx3;
- for (long r = 0; r < rowsl; r++) {
- idx5 = r * rowStridel;
- idx6 = 2 * idx5;
- for (long c = 0; c < columnsl; c += 2) {
- idx1 = idx3 + idx5 + c;
- idx2 = idx4 + idx6 + c;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, 0);
- idx1++;
- idx2++;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, 0);
- }
- }
- }
-
- for (long r = 1; r < rowsl; r++) {
- idx3 = (rowsl - r) * rowStridel;
- idx4 = (rowsl - r) * twoRowStride;
- for (long c = 0; c < columnsl; c += 2) {
- idx1 = idx3 + c;
- idx2 = idx4 + c;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, 0);
- idx1++;
- idx2++;
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx1, 0);
- }
- }
-
- int nthreads = ConcurrencyUtils.getNumberOfThreads();
- if ((nthreads > 1) && useThreads && (slicesl >= nthreads)) {
- Future>[] futures = new Future[nthreads];
- long p = slicesl / nthreads;
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx3 = ((slicesl - s) % slicesl) * twoSliceStride;
- long idx5 = s * twoSliceStride;
- for (long r = 0; r < rowsl; r++) {
- long idx4 = ((rowsl - r) % rowsl) * twoRowStride;
- long idx6 = r * twoRowStride;
- for (long c = 1; c < columnsl; c += 2) {
- long idx1 = idx3 + idx4 + twon3 - c;
- long idx2 = idx5 + idx6 + c;
- a.setDouble(idx1, -a.getDouble(idx2 + 2));
- a.setDouble(idx1 - 1, a.getDouble(idx2 + 1));
- }
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
-
- // ---------------------------------------------
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx5 = ((slicesl - s) % slicesl) * twoSliceStride;
- long idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx4 = idx6 + (rowsl - r) * twoRowStride;
- long idx1 = idx5 + r * twoRowStride + columnsl;
- long idx2 = idx4 + columnsl;
- long idx3 = idx4 + 1;
- a.setDouble(idx1, a.getDouble(idx3));
- a.setDouble(idx2, a.getDouble(idx3));
- a.setDouble(idx1 + 1, -a.getDouble(idx4));
- a.setDouble(idx2 + 1, a.getDouble(idx4));
-
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- for (int l = 0; l < nthreads; l++) {
- final long firstSlice = l * p;
- final long lastSlice = (l == (nthreads - 1)) ? slicesl : firstSlice + p;
- futures[l] = ConcurrencyUtils.submit(new Runnable()
- {
- public void run()
- {
- for (long s = firstSlice; s < lastSlice; s++) {
- long idx3 = ((slicesl - s) % slicesl) * twoSliceStride;
- long idx4 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- long idx1 = idx3 + (rowsl - r) * twoRowStride;
- long idx2 = idx4 + r * twoRowStride;
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
-
- }
- }
- }
- });
- }
- ConcurrencyUtils.waitForCompletion(futures);
- } else {
-
- // -----------------------------------------------
- for (long s = 0; s < slicesl; s++) {
- idx3 = ((slicesl - s) % slicesl) * twoSliceStride;
- idx5 = s * twoSliceStride;
- for (long r = 0; r < rowsl; r++) {
- idx4 = ((rowsl - r) % rowsl) * twoRowStride;
- idx6 = r * twoRowStride;
- for (long c = 1; c < columnsl; c += 2) {
- idx1 = idx3 + idx4 + twon3 - c;
- idx2 = idx5 + idx6 + c;
- a.setDouble(idx1, -a.getDouble(idx2 + 2));
- a.setDouble(idx1 - 1, a.getDouble(idx2 + 1));
- }
- }
- }
-
- // ---------------------------------------------
- for (long s = 0; s < slicesl; s++) {
- idx5 = ((slicesl - s) % slicesl) * twoSliceStride;
- idx6 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- idx4 = idx6 + (rowsl - r) * twoRowStride;
- idx1 = idx5 + r * twoRowStride + columnsl;
- idx2 = idx4 + columnsl;
- idx3 = idx4 + 1;
- a.setDouble(idx1, a.getDouble(idx3));
- a.setDouble(idx2, a.getDouble(idx3));
- a.setDouble(idx1 + 1, -a.getDouble(idx4));
- a.setDouble(idx2 + 1, a.getDouble(idx4));
-
- }
- }
-
- for (long s = 0; s < slicesl; s++) {
- idx3 = ((slicesl - s) % slicesl) * twoSliceStride;
- idx4 = s * twoSliceStride;
- for (long r = 1; r < n2d2; r++) {
- idx1 = idx3 + (rowsl - r) * twoRowStride;
- idx2 = idx4 + r * twoRowStride;
- a.setDouble(idx1, a.getDouble(idx2));
- a.setDouble(idx1 + 1, -a.getDouble(idx2 + 1));
-
- }
- }
- }
-
- // ----------------------------------------------------------
- for (long s = 1; s < n1d2; s++) {
- idx1 = s * twoSliceStride;
- idx2 = (slicesl - s) * twoSliceStride;
- idx3 = n2d2 * twoRowStride;
- idx4 = idx1 + idx3;
- idx5 = idx2 + idx3;
- a.setDouble(idx1 + columnsl, a.getDouble(idx2 + 1));
- a.setDouble(idx2 + columnsl, a.getDouble(idx2 + 1));
- a.setDouble(idx1 + columnsl + 1, -a.getDouble(idx2));
- a.setDouble(idx2 + columnsl + 1, a.getDouble(idx2));
- a.setDouble(idx4 + columnsl, a.getDouble(idx5 + 1));
- a.setDouble(idx5 + columnsl, a.getDouble(idx5 + 1));
- a.setDouble(idx4 + columnsl + 1, -a.getDouble(idx5));
- a.setDouble(idx5 + columnsl + 1, a.getDouble(idx5));
- a.setDouble(idx2, a.getDouble(idx1));
- a.setDouble(idx2 + 1, -a.getDouble(idx1 + 1));
- a.setDouble(idx5, a.getDouble(idx4));
- a.setDouble(idx5 + 1, -a.getDouble(idx4 + 1));
-
- }
-
- // ----------------------------------------
- a.setDouble(columnsl, a.getDouble(1));
- a.setDouble(1, 0);
- idx1 = n2d2 * twoRowStride;
- idx2 = n1d2 * twoSliceStride;
- idx3 = idx1 + idx2;
- a.setDouble(idx1 + columnsl, a.getDouble(idx1 + 1));
- a.setDouble(idx1 + 1, 0);
- a.setDouble(idx2 + columnsl, a.getDouble(idx2 + 1));
- a.setDouble(idx2 + 1, 0);
- a.setDouble(idx3 + columnsl, a.getDouble(idx3 + 1));
- a.setDouble(idx3 + 1, 0);
- a.setDouble(idx2 + columnsl + 1, 0);
- a.setDouble(idx3 + columnsl + 1, 0);
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/RealFFTUtils_2D.java b/src/main/java/org/jtransforms/fft/RealFFTUtils_2D.java
deleted file mode 100644
index 61a5aa9..0000000
--- a/src/main/java/org/jtransforms/fft/RealFFTUtils_2D.java
+++ /dev/null
@@ -1,682 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-// @formatter:off
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- *
- * This is a set of utility methods for R/W access to data resulting from a call
- * to the Fourier transform of real data. Memory optimized methods,
- * namely
- * - * DoubleFFT_2D fft = new DoubleFFT_2D(rows, columns); - * double[] data = new double[2 * rows * columns]; - * ... - * fft.realForwardFull(data); - * data[r1 * 2 * columns + c1] = val1; - * val2 = data[r2 * 2 * columns + c2]; - *- * is equivalent to - *
- * DoubleFFT_2D fft = new DoubleFFT_2D(rows, columns); - * RealFFTUtils_2D unpacker = new RealFFTUtils_2D(rows, columns); - * double[] data = new double[rows * columns]; - * ... - * fft.realForward(data); - * unpacker.pack(val1, r1, c1, data); - * val2 = unpacker.unpack(r2, c2, data, 0); - *- * Even (resp. odd) values of
c correspond to the real (resp.
- * imaginary) part of the Fourier mode.
- * - * DoubleFFT_2D fft = new DoubleFFT_2D(rows, columns); - * double[][] data = new double[rows][2 * columns]; - * ... - * fft.realForwardFull(data); - * data[r1][c1] = val1; - * val2 = data[r2][c2]; - *- * is equivalent to - *
- * DoubleFFT_2D fft = new DoubleFFT_2D(rows, columns); - * RealFFTUtils_2D unpacker = new RealFFTUtils_2D(rows, columns); - * double[][] data = new double[rows][columns]; - * ... - * fft.realForward(data); - * unpacker.pack(val1, r1, c1, data); - * val2 = unpacker.unpack(r2, c2, data, 0); - *- * Even (resp. odd) values of
c correspond to the real (resp.
- * imaginary) part of the Fourier mode.
- *
- * @author Sébastien Brisard
- */
-// @formatter:on
-public class RealFFTUtils_2D
-{
-
- /**
- * The constant int value of 1.
- */
- private static final int ONE = 1;
-
- /**
- * The constant int value of 2.
- */
- private static final int TWO = 2;
-
- /**
- * The constant int value of 0.
- */
- private static final int ZERO = 0;
-
- /**
- * The constant int value of 1.
- */
- private static final long ONEL = 1;
-
- /**
- * The constant int value of 2.
- */
- private static final long TWOL = 2;
-
- /**
- * The constant int value of 0.
- */
- private static final long ZEROL = 0;
-
- /**
- * The size of the data in the second direction.
- */
- private final int columns;
-
- /**
- * The size of the data in the first direction.
- */
- private final int rows;
-
- /**
- * The size of the data in the second direction.
- */
- private final long columnsl;
-
- /**
- * The size of the data in the first direction.
- */
- private final long rowsl;
-
- /**
- * Creates a new instance of this class. The size of the underlying
- * {@link DoubleFFT_2D} or {@link FloatFFT_2D} must be specified.
- *
- * @param rows
- * number of rows
- * @param columns
- * number of columns
- */
- public RealFFTUtils_2D(final long rows, final long columns)
- {
- this.columns = (int) columns;
- this.rows = (int) rows;
- this.columnsl = columns;
- this.rowsl = rows;
-
- }
-
- /**
- *
- * Returns the 1d index of the specified 2d Fourier mode. In other words, if
- * packed contains the transformed data following a call to
- * {@link DoubleFFT_2D#realForward(double[])} or
- * {@link FloatFFT_2D#realForward(float[])}, then the returned value
- * index gives access to the [r][c] Fourier mode
- * index == {@link Integer#MIN_VALUE}, then the Fourier
- * mode is zero,index >= 0, then the Fourier mode is
- * packed[index],index < 0, then the Fourier mode is
- * -packed[-index],index
- */
- public int getIndex(final int r, final int c)
- {
- final int cmod2 = c & ONE;
- final int rmul2 = r << ONE;
- if (r != ZERO) {
- if (c <= ONE) {
- if (rmul2 == rows) {
- if (cmod2 == ONE) {
- return Integer.MIN_VALUE;
- }
- return ((rows * columns) >> ONE);
- } else if (rmul2 < rows) {
- return columns * r + cmod2;
- } else {
- if (cmod2 == ZERO) {
- return columns * (rows - r);
- } else {
- return -(columns * (rows - r) + ONE);
- }
- }
- } else if ((c == columns) || (c == columns + ONE)) {
- if (rmul2 == rows) {
- if (cmod2 == ONE) {
- return Integer.MIN_VALUE;
- }
- return ((rows * columns) >> ONE) + ONE;
- } else if (rmul2 < rows) {
- if (cmod2 == ZERO) {
- return columns * (rows - r) + ONE;
- } else {
- return -(columns * (rows - r));
- }
- } else {
- return columns * r + ONE - cmod2;
- }
- } else if (c < columns) {
- return columns * r + c;
- } else {
- if (cmod2 == ZERO) {
- return columns * (rows + TWO - r) - c;
- } else {
- return -(columns * (rows + TWO - r) - c + TWO);
- }
- }
- } else {
- if ((c == ONE) || (c == columns + ONE)) {
- return Integer.MIN_VALUE;
- } else if (c == columns) {
- return ONE;
- } else if (c < columns) {
- return c;
- } else {
- if (cmod2 == ZERO) {
- return (columns << ONE) - c;
- } else {
- return -((columns << ONE) - c + TWO);
- }
- }
- }
- }
-
- /**
- *
- * Returns the 1d index of the specified 2d Fourier mode. In other words, if
- * packed contains the transformed data following a call to
- * {@link DoubleFFT_2D#realForward(DoubleLargeArray)} or
- * {@link FloatFFT_2D#realForward(FloatLargeArray)}, then the returned value
- * index gives access to the [r][c] Fourier mode
- * index == {@link Long#MIN_VALUE}, then the Fourier
- * mode is zero,index >= 0, then the Fourier mode is
- * packed[index],index < 0, then the Fourier mode is
- * -packed[-index],index
- */
- public long getIndex(final long r, final long c)
- {
- final long cmod2 = c & ONEL;
- final long rmul2 = r << ONEL;
- if (r != ZERO) {
- if (c <= ONEL) {
- if (rmul2 == rowsl) {
- if (cmod2 == ONEL) {
- return Long.MIN_VALUE;
- }
- return ((rowsl * columnsl) >> ONEL);
- } else if (rmul2 < rowsl) {
- return columnsl * r + cmod2;
- } else {
- if (cmod2 == ZEROL) {
- return columnsl * (rowsl - r);
- } else {
- return -(columnsl * (rowsl - r) + ONEL);
- }
- }
- } else if ((c == columnsl) || (c == columnsl + ONEL)) {
- if (rmul2 == rowsl) {
- if (cmod2 == ONEL) {
- return Long.MIN_VALUE;
- }
- return ((rowsl * columnsl) >> ONEL) + ONEL;
- } else if (rmul2 < rowsl) {
- if (cmod2 == ZEROL) {
- return columnsl * (rowsl - r) + ONEL;
- } else {
- return -(columnsl * (rowsl - r));
- }
- } else {
- return columnsl * r + ONEL - cmod2;
- }
- } else if (c < columnsl) {
- return columnsl * r + c;
- } else {
- if (cmod2 == ZEROL) {
- return columnsl * (rowsl + TWOL - r) - c;
- } else {
- return -(columnsl * (rowsl + TWOL - r) - c + TWOL);
- }
- }
- } else {
- if ((c == ONEL) || (c == columnsl + ONEL)) {
- return Long.MIN_VALUE;
- } else if (c == columnsl) {
- return ONEL;
- } else if (c < columnsl) {
- return c;
- } else {
- if (cmod2 == ZEROL) {
- return (columnsl << ONEL) - c;
- } else {
- return -((columnsl << ONEL) - c + TWOL);
- }
- }
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_2D#realForward(double[])}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final double val, final int r, final int c,
- final double[] packed, final int pos)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- packed[pos + index] = val;
- } else if (index > Integer.MIN_VALUE) {
- packed[pos - index] = -val;
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_2D#realForward(DoubleLargeArray)}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final double val, final long r, final long c,
- final DoubleLargeArray packed, final long pos)
- {
- final long index = getIndex(r, c);
- if (index >= 0) {
- packed.setDouble(pos + index, val);
- } else if (index > Long.MIN_VALUE) {
- packed.setDouble(pos - index, -val);
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_2D#realForward(double[][])}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- */
- public void pack(final double val, final int r, final int c,
- final double[][] packed)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- packed[index / columns][index % columns] = val;
- } else if (index > Integer.MIN_VALUE) {
- packed[(-index) / columns][(-index) % columns] = -val;
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_2D#realForward(float[])}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final float val, final int r, final int c,
- final float[] packed, final int pos)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- packed[pos + index] = val;
- } else if (index > Integer.MIN_VALUE) {
- packed[pos - index] = -val;
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_2D#realForward(FloatLargeArray)}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final float val, final long r, final long c,
- final FloatLargeArray packed, final long pos)
- {
- final long index = getIndex(r, c);
- if (index >= 0) {
- packed.setFloat(pos + index, val);
- } else if (index > Long.MIN_VALUE) {
- packed.setFloat(pos - index, -val);
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_2D#realForward(float[][])}.
- *
- * @param val
- * the new value of the [r][c] Fourier mode
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- */
- public void pack(final float val, final int r, final int c,
- final float[][] packed)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- packed[index / columns][index % columns] = val;
- } else if (index > Integer.MIN_VALUE) {
- packed[(-index) / columns][(-index) % columns] = -val;
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link DoubleFFT_2D#realForward(double[])}.
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [r][c] Fourier mode
- */
- public double unpack(final int r, final int c, final double[] packed,
- final int pos)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- return packed[pos + index];
- } else if (index > Integer.MIN_VALUE) {
- return -packed[pos - index];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link DoubleFFT_2D#realForward(DoubleLargeArray)}.
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [r][c] Fourier mode
- */
- public double unpack(final long r, final long c, final DoubleLargeArray packed,
- final long pos)
- {
- final long index = getIndex(r, c);
- if (index >= 0) {
- return packed.getDouble(pos + index);
- } else if (index > Long.MIN_VALUE) {
- return -packed.getDouble(pos - index);
- } else {
- return ZEROL;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link DoubleFFT_2D#realForward(double[][])}
- * .
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- *
- * @return the value of the [r][c] Fourier mode
- */
- public double unpack(final int r, final int c, final double[][] packed)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- return packed[index / columns][index % columns];
- } else if (index > Integer.MIN_VALUE) {
- return -packed[(-index) / columns][(-index) % columns];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_2D#realForward(float[])}
- * .
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [r][c] Fourier mode
- */
- public float unpack(final int r, final int c, final float[] packed,
- final int pos)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- return packed[pos + index];
- } else if (index > Integer.MIN_VALUE) {
- return -packed[pos - index];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_2D#realForward(FloatLargeArray)}
- * .
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [r][c] Fourier mode
- */
- public float unpack(final long r, final long c, final FloatLargeArray packed,
- final long pos)
- {
- final long index = getIndex(r, c);
- if (index >= 0) {
- return packed.getFloat(pos + index);
- } else if (index > Long.MIN_VALUE) {
- return -packed.getFloat(pos - index);
- } else {
- return ZEROL;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_2D#realForward(float[][])} .
- *
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- *
- * @return the value of the [r][c] Fourier mode
- */
- public float unpack(final int r, final int c, final float[][] packed)
- {
- final int index = getIndex(r, c);
- if (index >= 0) {
- return packed[index / columns][index % columns];
- } else if (index > Integer.MIN_VALUE) {
- return -packed[(-index) / columns][(-index) % columns];
- } else {
- return ZERO;
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/RealFFTUtils_3D.java b/src/main/java/org/jtransforms/fft/RealFFTUtils_3D.java
deleted file mode 100644
index cd672dc..0000000
--- a/src/main/java/org/jtransforms/fft/RealFFTUtils_3D.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.fft;
-
-// @formatter:off
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- *
- * This is a set of utility methods for R/W access to data resulting from a call
- * to the Fourier transform of real data. Memory optimized methods,
- * namely
- * - * DoubleFFT_3D fft = new DoubleFFT_2D(slices, rows, columns); - * double[] data = new double[2 * slices * rows * columns]; - * ... - * fft.realForwardFull(data); - * data[(s1 * rows + r1) * 2 * columns + c1] = val1; - * val2 = data[(s2 * rows + r2) * 2 * columns + c2]; - *- * is equivalent to - *
- * DoubleFFT_3D fft = new DoubleFFT_3D(slices, rows, columns); - * RealFFTUtils_3D unpacker = new RealFFTUtils_3D(slices, rows, columns); - * double[] data = new double[slices * rows * columns]; - * ... - * fft.realForward(data); - * unpacker.pack(val1, s1, r1, c1, data); - * val2 = unpacker.unpack(s2, r2, c2, data, 0); - *- * Even (resp. odd) values of
c correspond to the real (resp.
- * imaginary) part of the Fourier mode.
- * - * DoubleFFT_3D fft = new DoubleFFT_3D(slices, rows, columns); - * double[][][] data = new double[slices][rows][2 * columns]; - * ... - * fft.realForwardFull(data); - * data[s1][r1][c1] = val1; - * val2 = data[s2][r2][c2]; - *- * is equivalent to - *
- * DoubleFFT_3D fft = new DoubleFFT_3D(slices, rows, columns); - * RealFFTUtils_3D unpacker = new RealFFTUtils_3D(slices, rows, columns); - * double[][][] data = new double[slices][rows][columns]; - * ... - * fft.realForward(data); - * unpacker.pack(val1, s1, r1, c1, data); - * val2 = unpacker.unpack(s2, r2, c2, data, 0); - *- * Even (resp. odd) values of
c correspond to the real (resp.
- * imaginary) part of the Fourier mode.
- *
- * @author Sébastien Brisard
- */
-// @formatter:on
-public class RealFFTUtils_3D
-{
-
- /**
- * The constant int value of 1.
- */
- private static final int ONE = 1;
-
- /**
- * The constant int value of 2.
- */
- private static final int TWO = 2;
-
- /**
- * The constant int value of 0.
- */
- private static final int ZERO = 0;
-
- /**
- * The constant int value of 1.
- */
- private static final long ONEL = 1;
-
- /**
- * The constant int value of 2.
- */
- private static final long TWOL = 2;
-
- /**
- * The constant int value of 0.
- */
- private static final long ZEROL = 0;
-
- /**
- * The size of the data in the third direction.
- */
- private final int columns;
-
- /**
- * The size of the data in the third direction.
- */
- private final long columnsl;
-
- /**
- * The size of the data in the second direction.
- */
- private final int rows;
-
- /**
- * The size of the data in the second direction.
- */
- private final long rowsl;
-
- /**
- * The constant value of 2 * columns.
- */
- private final int rowStride;
-
- /**
- * The constant value of 2 * columns.
- */
- private final long rowStridel;
-
- /**
- * The size of the data in the first direction.
- */
- private final int slices;
-
- /**
- * The size of the data in the first direction.
- */
- private final long slicesl;
-
- /**
- * The constant value of 2 * rows * columns.
- */
- private final int sliceStride;
-
- /**
- * The constant value of 2 * rows * columns.
- */
- private final long sliceStridel;
-
- /**
- * Creates a new instance of this class. The size of the underlying
- * {@link DoubleFFT_3D} or {@link FloatFFT_3D} must be specified.
- *
- * @param slices
- * number of slices
- * @param rows
- * number of rows
- * @param columns
- * number of columns
- */
- public RealFFTUtils_3D(final long slices, final long rows, final long columns)
- {
- this.slices = (int) slices;
- this.rows = (int) rows;
- this.columns = (int) columns;
- this.rowStride = (int) columns;
- this.sliceStride = (int) rows * (int) this.rowStride;
- this.slicesl = slices;
- this.rowsl = rows;
- this.columnsl = columns;
- this.rowStridel = columns;
- this.sliceStridel = rows * this.rowStridel;
- }
-
- /**
- *
- * Returns the 1d index of the specified 3d Fourier mode. In other words, if
- * packed contains the transformed data following a call to
- * {@link DoubleFFT_3D#realForwardFull(double[])} or
- * {@link FloatFFT_3D#realForward(float[])}, then the returned value
- * index gives access to the [s][r][c] Fourier
- * mode
- * index == {@link Integer#MIN_VALUE}, then the Fourier
- * mode is zero,index >= 0, then the Fourier mode is
- * packed[index],index < 0, then the Fourier mode is
- * -packed[-index],index
- */
- public int getIndex(final int s, final int r, final int c)
- {
- final int cmod2 = c & ONE;
- final int rmul2 = r << ONE;
- final int smul2 = s << ONE;
- final int ss = s == ZERO ? ZERO : slices - s;
- final int rr = r == ZERO ? ZERO : rows - r;
- if (c <= ONE) {
- if (r == ZERO) {
- if (s == ZERO) {
- return c == ZERO ? ZERO : Integer.MIN_VALUE;
- } else if (smul2 < slices) {
- return s * sliceStride + c;
- } else if (smul2 > slices) {
- final int index = ss * sliceStride;
- return cmod2 == ZERO ? index : -(index + ONE);
- } else {
- return cmod2 == ZERO ? s * sliceStride : Integer.MIN_VALUE;
- }
- } else if (rmul2 < rows) {
- return s * sliceStride + r * rowStride + c;
- } else if (rmul2 > rows) {
- final int index = ss * sliceStride + rr * rowStride;
- return cmod2 == ZERO ? index : -(index + ONE);
- } else {
- if (s == ZERO) {
- return cmod2 == ZERO ? r * rowStride : Integer.MIN_VALUE;
- } else if (smul2 < slices) {
- return s * sliceStride + r * rowStride + c;
- } else if (smul2 > slices) {
- final int index = ss * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index : -(index + ONE);
- } else {
- final int index = s * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index : Integer.MIN_VALUE;
- }
- }
- } else if (c < columns) {
- return s * sliceStride + r * rowStride + c;
- } else if (c > columns + ONE) {
- final int cc = (columns << ONE) - c;
- final int index = ss * sliceStride + rr * rowStride + cc;
- return cmod2 == ZERO ? index : -(index + TWO);
- } else {
- if (r == ZERO) {
- if (s == ZERO) {
- return cmod2 == ZERO ? ONE : Integer.MIN_VALUE;
- } else if (smul2 < slices) {
- final int index = ss * sliceStride;
- return cmod2 == ZERO ? index + ONE : -index;
- } else if (smul2 > slices) {
- final int index = s * sliceStride;
- return cmod2 == ZERO ? index + ONE : index;
- } else {
- final int index = s * sliceStride;
- return cmod2 == ZERO ? index + ONE : Integer.MIN_VALUE;
- }
- } else if (rmul2 < rows) {
- final int index = ss * sliceStride + rr * rowStride;
- return cmod2 == ZERO ? index + ONE : -index;
- } else if (rmul2 > rows) {
- final int index = s * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index + ONE : index;
- } else {
- if (s == ZERO) {
- final int index = r * rowStride + ONE;
- return cmod2 == ZERO ? index : Integer.MIN_VALUE;
- } else if (smul2 < slices) {
- final int index = ss * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index + ONE : -index;
- } else if (smul2 > slices) {
- final int index = s * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index + ONE : index;
- } else {
- final int index = s * sliceStride + r * rowStride;
- return cmod2 == ZERO ? index + ONE : Integer.MIN_VALUE;
- }
- }
- }
- }
-
- /**
- *
- * Returns the 1d index of the specified 3d Fourier mode. In other words, if
- * packed contains the transformed data following a call to
- * {@link DoubleFFT_3D#realForwardFull(double[])} or
- * {@link FloatFFT_3D#realForward(float[])}, then the returned value
- * index gives access to the [s][r][c] Fourier
- * mode
- * index == {@link Integer#MIN_VALUE}, then the Fourier
- * mode is zero,index >= 0, then the Fourier mode is
- * packed[index],index < 0, then the Fourier mode is
- * -packed[-index],index
- */
- public long getIndex(final long s, final long r, final long c)
- {
- final long cmod2 = c & ONEL;
- final long rmul2 = r << ONEL;
- final long smul2 = s << ONEL;
- final long ss = s == ZEROL ? ZEROL : slicesl - s;
- final long rr = r == ZEROL ? ZEROL : rowsl - r;
- if (c <= ONEL) {
- if (r == ZEROL) {
- if (s == ZEROL) {
- return c == ZEROL ? ZEROL : Long.MIN_VALUE;
- } else if (smul2 < slicesl) {
- return s * sliceStridel + c;
- } else if (smul2 > slicesl) {
- final long index = ss * sliceStridel;
- return cmod2 == ZEROL ? index : -(index + ONEL);
- } else {
- return cmod2 == ZEROL ? s * sliceStridel : Long.MIN_VALUE;
- }
- } else if (rmul2 < rowsl) {
- return s * sliceStridel + r * rowStridel + c;
- } else if (rmul2 > rowsl) {
- final long index = ss * sliceStridel + rr * rowStridel;
- return cmod2 == ZEROL ? index : -(index + ONEL);
- } else {
- if (s == ZEROL) {
- return cmod2 == ZEROL ? r * rowStridel : Long.MIN_VALUE;
- } else if (smul2 < slicesl) {
- return s * sliceStridel + r * rowStridel + c;
- } else if (smul2 > slicesl) {
- final long index = ss * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index : -(index + ONEL);
- } else {
- final long index = s * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index : Long.MIN_VALUE;
- }
- }
- } else if (c < columnsl) {
- return s * sliceStridel + r * rowStridel + c;
- } else if (c > columnsl + ONEL) {
- final long cc = (columnsl << ONEL) - c;
- final long index = ss * sliceStridel + rr * rowStridel + cc;
- return cmod2 == ZEROL ? index : -(index + TWO);
- } else {
- if (r == ZEROL) {
- if (s == ZEROL) {
- return cmod2 == ZEROL ? ONEL : Long.MIN_VALUE;
- } else if (smul2 < slicesl) {
- final long index = ss * sliceStridel;
- return cmod2 == ZEROL ? index + ONEL : -index;
- } else if (smul2 > slicesl) {
- final long index = s * sliceStridel;
- return cmod2 == ZEROL ? index + ONEL : index;
- } else {
- final long index = s * sliceStridel;
- return cmod2 == ZEROL ? index + ONEL : Long.MIN_VALUE;
- }
- } else if (rmul2 < rowsl) {
- final long index = ss * sliceStridel + rr * rowStridel;
- return cmod2 == ZEROL ? index + ONEL : -index;
- } else if (rmul2 > rowsl) {
- final long index = s * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index + ONEL : index;
- } else {
- if (s == ZEROL) {
- final long index = r * rowStridel + ONEL;
- return cmod2 == ZEROL ? index : Long.MIN_VALUE;
- } else if (smul2 < slicesl) {
- final long index = ss * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index + ONEL : -index;
- } else if (smul2 > slicesl) {
- final long index = s * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index + ONEL : index;
- } else {
- final long index = s * sliceStridel + r * rowStridel;
- return cmod2 == ZEROL ? index + ONEL : Long.MIN_VALUE;
- }
- }
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_3D#realForward(double[])}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final double val, final int s, final int r, final int c,
- final double[] packed, final int pos)
- {
- final int i = getIndex(s, r, c);
- if (i >= 0) {
- packed[pos + i] = val;
- } else if (i > Integer.MIN_VALUE) {
- packed[pos - i] = -val;
- } else {
- throw new IllegalArgumentException(String.format(
- "[%d][%d][%d] component cannot be modified (always zero)",
- s, r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_3D#realForward(DoubleLargeArray)}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final double val, final long s, final long r, final long c,
- final DoubleLargeArray packed, final long pos)
- {
- final long i = getIndex(s, r, c);
- if (i >= 0) {
- packed.setDouble(pos + i, val);
- } else if (i > Long.MIN_VALUE) {
- packed.setDouble(pos - i, -val);
- } else {
- throw new IllegalArgumentException(String.format(
- "[%d][%d][%d] component cannot be modified (always zero)",
- s, r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link DoubleFFT_3D#realForward(double[][][])}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- */
- public void pack(final double val, final int s, final int r, final int c,
- final double[][][] packed)
- {
- final int i = getIndex(s, r, c);
- final int ii = Math.abs(i);
- final int ss = ii / sliceStride;
- final int remainder = ii % sliceStride;
- final int rr = remainder / rowStride;
- final int cc = remainder % rowStride;
- if (i >= 0) {
- packed[ss][rr][cc] = val;
- } else if (i > Integer.MIN_VALUE) {
- packed[ss][rr][cc] = -val;
- } else {
- throw new IllegalArgumentException(
- String.format(
- "[%d][%d] component cannot be modified (always zero)",
- r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_3D#realForward(float[])}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final float val, final int s, final int r, final int c,
- final float[] packed, final int pos)
- {
- final int i = getIndex(s, r, c);
- if (i >= 0) {
- packed[pos + i] = val;
- } else if (i > Integer.MIN_VALUE) {
- packed[pos - i] = -val;
- } else {
- throw new IllegalArgumentException(String.format(
- "[%d][%d][%d] component cannot be modified (always zero)",
- s, r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_3D#realForward(FloatLargeArray)}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- */
- public void pack(final float val, final long s, final long r, final long c,
- final FloatLargeArray packed, final long pos)
- {
- final long i = getIndex(s, r, c);
- if (i >= 0) {
- packed.setFloat(pos + i, val);
- } else if (i > Long.MIN_VALUE) {
- packed.setFloat(pos - i, -val);
- } else {
- throw new IllegalArgumentException(String.format(
- "[%d][%d][%d] component cannot be modified (always zero)",
- s, r, c));
- }
- }
-
- /**
- * Sets the specified Fourier mode of the transformed data. The data array
- * results from a call to {@link FloatFFT_3D#realForward(float[][][])}.
- *
- * @param val
- * the new value of the [s][r][c] Fourier mode
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- */
- public void pack(final float val, final int s, final int r, final int c,
- final float[][][] packed)
- {
- final int i = getIndex(s, r, c);
- final int ii = Math.abs(i);
- final int ss = ii / sliceStride;
- final int remainder = ii % sliceStride;
- final int rr = remainder / rowStride;
- final int cc = remainder % rowStride;
- if (i >= 0) {
- packed[ss][rr][cc] = val;
- } else if (i > Integer.MIN_VALUE) {
- packed[ss][rr][cc] = -val;
- } else {
- throw new IllegalArgumentException(String.format(
- "[%d][%d][%d] component cannot be modified (always zero)",
- s, r, c));
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link DoubleFFT_3D#realForward(double[])}.
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public double unpack(final int s, final int r, final int c,
- final double[] packed, final int pos)
- {
- final int i = getIndex(s, r, c);
- if (i >= 0) {
- return packed[pos + i];
- } else if (i > Integer.MIN_VALUE) {
- return -packed[pos - i];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link DoubleFFT_3D#realForward(DoubleLargeArray)}.
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public double unpack(final long s, final long r, final long c,
- final DoubleLargeArray packed, final long pos)
- {
- final long i = getIndex(s, r, c);
- if (i >= 0) {
- return packed.getDouble(pos + i);
- } else if (i > Long.MIN_VALUE) {
- return -packed.getDouble(pos - i);
- } else {
- return ZEROL;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to
- * {@link DoubleFFT_3D#realForward(double[][][])} .
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public double unpack(final int s, final int r, final int c,
- final double[][][] packed)
- {
- final int i = getIndex(s, r, c);
- final int ii = Math.abs(i);
- final int ss = ii / sliceStride;
- final int remainder = ii % sliceStride;
- final int rr = remainder / rowStride;
- final int cc = remainder % rowStride;
- if (i >= 0) {
- return packed[ss][rr][cc];
- } else if (i > Integer.MIN_VALUE) {
- return -packed[ss][rr][cc];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_3D#realForward(float[])} .
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public float unpack(final int s, final int r, final int c,
- final float[] packed, final int pos)
- {
- final int i = getIndex(s, r, c);
- if (i >= 0) {
- return packed[pos + i];
- } else if (i > Integer.MIN_VALUE) {
- return -packed[pos - i];
- } else {
- return ZERO;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_3D#realForward(FloatLargeArray)} .
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- * @param pos
- * index of the first element in array packed
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public float unpack(final long s, final long r, final long c,
- final FloatLargeArray packed, final long pos)
- {
- final long i = getIndex(s, r, c);
- if (i >= 0) {
- return packed.getFloat(pos + i);
- } else if (i > Long.MIN_VALUE) {
- return -packed.getFloat(pos - i);
- } else {
- return ZEROL;
- }
- }
-
- /**
- * Returns the specified Fourier mode of the transformed data. The data
- * array results from a call to {@link FloatFFT_3D#realForward(float[][][])}
- * .
- *
- * @param s
- * the slice index
- * @param r
- * the row index
- * @param c
- * the column index
- * @param packed
- * the transformed data
- *
- * @return the value of the [s][r][c] Fourier mode
- */
- public float unpack(final int s, final int r, final int c,
- final float[][][] packed)
- {
- final int i = getIndex(s, r, c);
- final int ii = Math.abs(i);
- final int ss = ii / sliceStride;
- final int remainder = ii % sliceStride;
- final int rr = remainder / rowStride;
- final int cc = remainder % rowStride;
- if (i >= 0) {
- return packed[ss][rr][cc];
- } else if (i > Integer.MIN_VALUE) {
- return -packed[ss][rr][cc];
- } else {
- return ZERO;
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/fft/package.html b/src/main/java/org/jtransforms/fft/package.html
deleted file mode 100644
index a41a5ae..0000000
--- a/src/main/java/org/jtransforms/fft/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Discrete Fourier Transforms.
-
-
diff --git a/src/main/java/org/jtransforms/utils/IOUtils.java b/src/main/java/org/jtransforms/utils/IOUtils.java
deleted file mode 100644
index 4b15bda..0000000
--- a/src/main/java/org/jtransforms/utils/IOUtils.java
+++ /dev/null
@@ -1,1447 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.utils;
-
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Date;
-import java.util.Random;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-import pl.edu.icm.jlargearrays.FloatLargeArray;
-
-/**
- * I/O utilities.
- *
- * @author Piotr Wendykier (piotr.wendykier@gmail.com)
- */
-public class IOUtils
-{
-
- private static final String FF = "%.4f";
-
- private IOUtils()
- {
-
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(float a, float b)
- {
- double tmp = a - b;
- double rms = tmp * tmp;
- return Math.sqrt(rms);
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(float[] a, float[] b)
- {
- if (a.length != b.length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int i = 0; i < a.length; i++) {
- tmp = (a[i] - b[i]);
- rms += tmp * tmp;
- }
- return Math.sqrt(rms / a.length);
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(FloatLargeArray a, FloatLargeArray b)
- {
- if (a.length() != b.length()) {
- throw new IllegalArgumentException("Arrays are not the same size.");
- }
- double rms = 0;
- double tmp;
- for (long i = 0; i < a.length(); i++) {
- tmp = (a.getFloat(i) - b.getFloat(i));
- rms += tmp * tmp;
- }
- return Math.sqrt(rms / (double) a.length());
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(float[][] a, float[][] b)
- {
- if (a.length != b.length || a[0].length != b[0].length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int r = 0; r < a.length; r++) {
- for (int c = 0; c < a[0].length; c++) {
- tmp = (a[r][c] - b[r][c]);
- rms += tmp * tmp;
- }
- }
- return Math.sqrt(rms / (a.length * a[0].length));
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(float[][][] a, float[][][] b)
- {
- if (a.length != b.length || a[0].length != b[0].length || a[0][0].length != b[0][0].length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int s = 0; s < a.length; s++) {
- for (int r = 0; r < a[0].length; r++) {
- for (int c = 0; c < a[0][0].length; c++) {
- tmp = (a[s][r][c] - b[s][r][c]);
- rms += tmp * tmp;
- }
- }
- }
- return Math.sqrt(rms / (a.length * a[0].length * a[0][0].length));
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(double a, double b)
- {
- double tmp = a - b;
- double rms = tmp * tmp;
- return Math.sqrt(rms);
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(double[] a, double[] b)
- {
- if (a.length != b.length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int i = 0; i < a.length; i++) {
- tmp = (a[i] - b[i]);
- rms += tmp * tmp;
- }
- return Math.sqrt(rms / a.length);
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(DoubleLargeArray a, DoubleLargeArray b)
- {
- if (a.length() != b.length()) {
- throw new IllegalArgumentException("Arrays are not the same size.");
- }
- double rms = 0;
- double tmp;
- for (long i = 0; i < a.length(); i++) {
- tmp = (a.getDouble(i) - b.getDouble(i));
- rms += tmp * tmp;
- }
- return Math.sqrt(rms / (double) a.length());
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(double[][] a, double[][] b)
- {
- if (a.length != b.length || a[0].length != b[0].length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int r = 0; r < a.length; r++) {
- for (int c = 0; c < a[0].length; c++) {
- tmp = (a[r][c] - b[r][c]);
- rms += tmp * tmp;
- }
- }
- return Math.sqrt(rms / (a.length * a[0].length));
- }
-
- /**
- * Computes root mean square error between a and b.
- *
- * @param a input parameter
- * @param b input parameter
- *
- * @return root mean squared error between a and b
- */
- public static double computeRMSE(double[][][] a, double[][][] b)
- {
- if (a.length != b.length || a[0].length != b[0].length || a[0][0].length != b[0][0].length) {
- throw new IllegalArgumentException("Arrays are not the same size");
- }
- double rms = 0;
- double tmp;
- for (int s = 0; s < a.length; s++) {
- for (int r = 0; r < a[0].length; r++) {
- for (int c = 0; c < a[0][0].length; c++) {
- tmp = (a[s][r][c] - b[s][r][c]);
- rms += tmp * tmp;
- }
- }
- }
- return Math.sqrt(rms / (a.length * a[0].length * a[0][0].length));
- }
-
- /**
- * Fills 1D matrix with random numbers.
- *
- * @param N size
- * @param m 1D matrix
- */
- public static void fillMatrix_1D(long N, double[] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < N; i++) {
- m[i] = r.nextDouble();
- }
- }
-
- /**
- * Fills 1D matrix with random numbers.
- *
- * @param N size
- * @param m 1D matrix
- */
- public static void fillMatrix_1D(long N, DoubleLargeArray m)
- {
- Random r = new Random(2);
- for (long i = 0; i < N; i++) {
- m.setDouble(i, r.nextDouble());
- }
- }
-
- /**
- * Fills 1D matrix with random numbers.
- *
- * @param N size
- * @param m 1D matrix
- */
- public static void fillMatrix_1D(long N, FloatLargeArray m)
- {
- Random r = new Random(2);
- for (long i = 0; i < N; i++) {
- m.setDouble(i, r.nextFloat());
- }
- }
-
- /**
- * Fills 1D matrix with random numbers.
- *
- * @param N size
- * @param m 1D matrix
- */
- public static void fillMatrix_1D(long N, float[] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < N; i++) {
- m[i] = r.nextFloat();
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, double[] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- m[(int) (i * n2 + j)] = r.nextDouble();
- }
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, FloatLargeArray m)
- {
- Random r = new Random(2);
- for (long i = 0; i < n1; i++) {
- for (long j = 0; j < n2; j++) {
- m.setFloat(i * n2 + j, r.nextFloat());
- }
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, DoubleLargeArray m)
- {
- Random r = new Random(2);
- for (long i = 0; i < n1; i++) {
- for (long j = 0; j < n2; j++) {
- m.setDouble(i * n2 + j, r.nextDouble());
- }
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, float[] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- m[(int) (i * n2 + j)] = r.nextFloat();
- }
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, double[][] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- m[i][j] = r.nextDouble();
- }
- }
- }
-
- /**
- * Fills 2D matrix with random numbers.
- *
- * @param n1 rows
- * @param n2 columns
- * @param m 2D matrix
- */
- public static void fillMatrix_2D(long n1, long n2, float[][] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- m[i][j] = r.nextFloat();
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, double[] m)
- {
- Random r = new Random(2);
- long sliceStride = n2 * n3;
- long rowStride = n3;
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- for (int k = 0; k < n3; k++) {
- m[(int) (i * sliceStride + j * rowStride + k)] = r.nextDouble();
- }
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, DoubleLargeArray m)
- {
- Random r = new Random(2);
- long sliceStride = n2 * n3;
- long rowStride = n3;
- for (long i = 0; i < n1; i++) {
- for (long j = 0; j < n2; j++) {
- for (long k = 0; k < n3; k++) {
- m.setDouble(i * sliceStride + j * rowStride + k, r.nextDouble());
- }
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, FloatLargeArray m)
- {
- Random r = new Random(2);
- long sliceStride = n2 * n3;
- long rowStride = n3;
- for (long i = 0; i < n1; i++) {
- for (long j = 0; j < n2; j++) {
- for (long k = 0; k < n3; k++) {
- m.setDouble(i * sliceStride + j * rowStride + k, r.nextFloat());
- }
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, float[] m)
- {
- Random r = new Random(2);
- long sliceStride = n2 * n3;
- long rowStride = n3;
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- for (int k = 0; k < n3; k++) {
- m[(int) (i * sliceStride + j * rowStride + k)] = r.nextFloat();
- }
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, double[][][] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- for (int k = 0; k < n3; k++) {
- m[i][j][k] = r.nextDouble();
- }
- }
- }
- }
-
- /**
- * Fills 3D matrix with random numbers.
- *
- * @param n1 slices
- * @param n2 rows
- * @param n3 columns
- * @param m 3D matrix
- */
- public static void fillMatrix_3D(long n1, long n2, long n3, float[][][] m)
- {
- Random r = new Random(2);
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- for (int k = 0; k < n3; k++) {
- m[i][j][k] = r.nextFloat();
- }
- }
- }
- }
-
- /**
- * Displays elements of x, assuming that it is 1D complex
- * array. Complex data is represented by 2 double values in sequence: the
- * real and imaginary parts.
- *
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_1D(double[] x, String title)
- {
- System.out.println(title);
- System.out.println("-------------------");
- for (int i = 0; i < x.length; i = i + 2) {
- if (x[i + 1] == 0) {
- System.out.println(String.format(FF, x[i]));
- continue;
- }
- if (x[i] == 0) {
- System.out.println(String.format(FF, x[i + 1]) + "i");
- continue;
- }
- if (x[i + 1] < 0) {
- System.out.println(String.format(FF, x[i]) + " - " + (String.format(FF, -x[i + 1])) + "i");
- continue;
- }
- System.out.println(String.format(FF, x[i]) + " + " + (String.format(FF, x[i + 1])) + "i");
- }
- System.out.println();
- }
-
- /**
- * Displays elements of x, assuming that it is 2D complex
- * array. Complex data is represented by 2 double values in sequence: the
- * real and imaginary parts.
- *
- * @param rows number of rows in the input array
- * @param columns number of columns in the input array
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_2D(int rows, int columns, double[] x, String title)
- {
- StringBuilder s = new StringBuilder(String.format(title + ": complex array 2D: %d rows, %d columns\n\n", rows, columns));
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < 2 * columns; c = c + 2) {
- if (x[r * 2 * columns + c + 1] == 0) {
- s.append(String.format(FF + "\t", x[r * 2 * columns + c]));
- continue;
- }
- if (x[r * 2 * columns + c] == 0) {
- s.append(String.format(FF + "i\t", x[r * 2 * columns + c + 1]));
- continue;
- }
- if (x[r * 2 * columns + c + 1] < 0) {
- s.append(String.format(FF + " - " + FF + "i\t", x[r * 2 * columns + c], -x[r * 2 * columns + c + 1]));
- continue;
- }
- s.append(String.format(FF + " + " + FF + "i\t", x[r * 2 * columns + c], x[r * 2 * columns + c + 1]));
- }
- s.append("\n");
- }
- System.out.println(s.toString());
- }
-
- /**
- * Displays elements of x, assuming that it is 2D complex
- * array. Complex data is represented by 2 double values in sequence: the
- * real and imaginary parts.
- *
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_2D(double[][] x, String title)
- {
- int rows = x.length;
- int columns = x[0].length;
- StringBuilder s = new StringBuilder(String.format(title + ": complex array 2D: %d rows, %d columns\n\n", rows, columns));
- for (int r = 0; r < rows; r++) {
- for (int c = 0; c < columns; c = c + 2) {
- if (x[r][c + 1] == 0) {
- s.append(String.format(FF + "\t", x[r][c]));
- continue;
- }
- if (x[r][c] == 0) {
- s.append(String.format(FF + "i\t", x[r][c + 1]));
- continue;
- }
- if (x[r][c + 1] < 0) {
- s.append(String.format(FF + " - " + FF + "i\t", x[r][c], -x[r][c + 1]));
- continue;
- }
- s.append(String.format(FF + " + " + FF + "i\t", x[r][c], x[r][c + 1]));
- }
- s.append("\n");
- }
- System.out.println(s.toString());
- }
-
- /**
- * Displays elements of x, assuming that it is 3D complex
- * array. Complex data is represented by 2 double values in sequence: the
- * real and imaginary parts.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param n3 third dimension
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_3D(int n1, int n2, int n3, double[] x, String title)
- {
- int sliceStride = n2 * 2 * n3;
- int rowStride = 2 * n3;
-
- System.out.println(title);
- System.out.println("-------------------");
-
- for (int k = 0; k < 2 * n3; k = k + 2) {
- System.out.println("(:,:," + k / 2 + ")=\n");
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k] == 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- }
- System.out.println("");
- }
- }
- System.out.println("");
- }
-
- /**
- * Displays elements of x. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_3D(double[][][] x, String title)
- {
- System.out.println(title);
- System.out.println("-------------------");
- int slices = x.length;
- int rows = x[0].length;
- int columns = x[0][0].length;
- for (int k = 0; k < columns; k = k + 2) {
- System.out.println("(:,:," + k / 2 + ")=\n");
- for (int i = 0; i < slices; i++) {
- for (int j = 0; j < rows; j++) {
- if (x[i][j][k + 1] == 0) {
- System.out.print(String.format(FF, x[i][j][k]) + "\t");
- continue;
- }
- if (x[i][j][k] == 0) {
- System.out.print(String.format(FF, x[i][j][k + 1]) + "i\t");
- continue;
- }
- if (x[i][j][k + 1] < 0) {
- System.out.print(String.format(FF, x[i][j][k]) + " - " + String.format(FF, -x[i][j][k + 1]) + "i\t");
- continue;
- }
- System.out.print(String.format(FF, x[i][j][k]) + " + " + String.format(FF, x[i][j][k + 1]) + "i\t");
- }
- System.out.println("");
- }
- }
- System.out.println("");
- }
-
- /**
- * Displays elements of x, assuming that it is 3D complex
- * array. Complex data is represented by 2 double values in sequence: the
- * real and imaginary parts.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param n3 third dimension
- * @param x input array
- * @param title title of the array
- */
- public static void showComplex_3D(int n1, int n2, int n3, float[] x, String title)
- {
- int sliceStride = n2 * 2 * n3;
- int rowStride = 2 * n3;
-
- System.out.println(title);
- System.out.println("-------------------");
-
- for (int k = 0; k < 2 * n3; k = k + 2) {
- System.out.println("(:,:," + k / 2 + ")=\n");
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k] == 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- }
- System.out.println("");
- }
- }
- System.out.println("");
- }
-
- /**
- * Displays elements of x, assuming that it is 1D real array.
- *
- * @param x input array
- * @param title title of the array
- */
- public static void showReal_1D(double[] x, String title)
- {
- System.out.println(title);
- System.out.println("-------------------");
- for (int j = 0; j < x.length; j++) {
- System.out.println(String.format(FF, x[j]));
- }
- System.out.println();
- }
-
- /**
- * Displays elements of x, assuming that it is 2D real array.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param x input array
- * @param title title of the array
- *
- */
- public static void showReal_2D(int n1, int n2, double[] x, String title)
- {
- System.out.println(title);
- System.out.println("-------------------");
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (Math.abs(x[i * n2 + j]) < 5e-5) {
- System.out.print("0\t");
- } else {
- System.out.print(String.format(FF, x[i * n2 + j]) + "\t");
- }
- }
- System.out.println();
- }
- System.out.println();
- }
-
- /**
- * Displays elements of x, assuming that it is 3D real array.
- *
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param n3 third dimension
- * @param x input array
- * @param title title of the array
- */
- public static void showReal_3D(int n1, int n2, int n3, double[] x, String title)
- {
- int sliceStride = n2 * n3;
- int rowStride = n3;
-
- System.out.println(title);
- System.out.println("-------------------");
-
- for (int k = 0; k < n3; k++) {
- System.out.println();
- System.out.println("(:,:," + k + ")=\n");
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (Math.abs(x[i * sliceStride + j * rowStride + k]) <= 5e-5) {
- System.out.print("0\t");
- } else {
- System.out.print(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
- }
- }
- System.out.println();
- }
- }
- System.out.println();
- }
-
- /**
- * Displays elements of x.
- *
- * @param x input array
- * @param title title of the array
- */
- public static void showReal_3D(double[][][] x, String title)
- {
-
- System.out.println(title);
- System.out.println("-------------------");
- int slices = x.length;
- int rows = x[0].length;
- int columns = x[0][0].length;
- for (int k = 0; k < columns; k++) {
- System.out.println();
- System.out.println("(:,:," + k + ")=\n");
- for (int i = 0; i < slices; i++) {
- for (int j = 0; j < rows; j++) {
- if (Math.abs(x[i][j][k]) <= 5e-5) {
- System.out.print("0\t");
- } else {
- System.out.print(String.format(FF, x[i][j][k]) + "\t");
- }
- }
- System.out.println();
- }
- }
- System.out.println();
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 1D complex array. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_1D(double[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < x.length; i = i + 2) {
- if (x[i + 1] == 0) {
- out.write(String.format(FF, x[i]));
- out.newLine();
- continue;
- }
- if (x[i] == 0) {
- out.write(String.format(FF, x[i + 1]) + "i");
- out.newLine();
- continue;
- }
- if (x[i + 1] < 0) {
- out.write(String.format(FF, x[i]) + " - " + String.format(FF, -x[i + 1]) + "i");
- out.newLine();
- continue;
- }
- out.write(String.format(FF, x[i]) + " + " + String.format(FF, x[i + 1]) + "i");
- out.newLine();
- }
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 1D complex array. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_1D(float[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < x.length; i = i + 2) {
- if (x[i + 1] == 0) {
- out.write(String.format(FF, x[i]));
- out.newLine();
- continue;
- }
- if (x[i] == 0) {
- out.write(String.format(FF, x[i + 1]) + "i");
- out.newLine();
- continue;
- }
- if (x[i + 1] < 0) {
- out.write(String.format(FF, x[i]) + " - " + String.format(FF, -x[i + 1]) + "i");
- out.newLine();
- continue;
- }
- out.write(String.format(FF, x[i]) + " + " + String.format(FF, x[i + 1]) + "i");
- out.newLine();
- }
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D complex array. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_2D(int n1, int n2, double[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < 2 * n2; j = j + 2) {
- if ((Math.abs(x[i * 2 * n2 + j]) < 5e-5) && (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5)) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write("0 + 0i\t");
- } else {
- out.write("0 - 0i\t");
- }
- continue;
- }
-
- if (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " + 0i\t");
- } else {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " - 0i\t");
- }
- continue;
- }
- if (Math.abs(x[i * 2 * n2 + j]) < 5e-5) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write("0 + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
- } else {
- out.write("0 - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
- }
- continue;
- }
- if (x[i * 2 * n2 + j + 1] < 0) {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
- continue;
- }
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
- }
- out.newLine();
- }
-
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D complex array. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_2D(int n1, int n2, float[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < 2 * n2; j = j + 2) {
- if ((Math.abs(x[i * 2 * n2 + j]) < 5e-5) && (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5)) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write("0 + 0i\t");
- } else {
- out.write("0 - 0i\t");
- }
- continue;
- }
-
- if (Math.abs(x[i * 2 * n2 + j + 1]) < 5e-5) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " + 0i\t");
- } else {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " - 0i\t");
- }
- continue;
- }
- if (Math.abs(x[i * 2 * n2 + j]) < 5e-5) {
- if (x[i * 2 * n2 + j + 1] >= 0.0) {
- out.write("0 + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
- } else {
- out.write("0 - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
- }
- continue;
- }
- if (x[i * 2 * n2 + j + 1] < 0) {
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " - " + String.format(FF, -x[i * 2 * n2 + j + 1]) + "i\t");
- continue;
- }
- out.write(String.format(FF, x[i * 2 * n2 + j]) + " + " + String.format(FF, x[i * 2 * n2 + j + 1]) + "i\t");
- }
- out.newLine();
- }
-
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename. Complex
- * data is represented by 2 double values in sequence: the real and
- * imaginary parts.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_2D(double[][] x, String filename)
- {
- int n1 = x.length;
- int n2 = x[0].length;
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < 2 * n2; j = j + 2) {
- if ((Math.abs(x[i][j]) < 5e-5) && (Math.abs(x[i][j + 1]) < 5e-5)) {
- if (x[i][j + 1] >= 0.0) {
- out.write("0 + 0i\t");
- } else {
- out.write("0 - 0i\t");
- }
- continue;
- }
-
- if (Math.abs(x[i][j + 1]) < 5e-5) {
- if (x[i][j + 1] >= 0.0) {
- out.write(String.format(FF, x[i][j]) + " + 0i\t");
- } else {
- out.write(String.format(FF, x[i][j]) + " - 0i\t");
- }
- continue;
- }
- if (Math.abs(x[i][j]) < 5e-5) {
- if (x[i][j + 1] >= 0.0) {
- out.write("0 + " + String.format(FF, x[i][j + 1]) + "i\t");
- } else {
- out.write("0 - " + String.format(FF, -x[i][j + 1]) + "i\t");
- }
- continue;
- }
- if (x[i][j + 1] < 0) {
- out.write(String.format(FF, x[i][j]) + " - " + String.format(FF, -x[i][j + 1]) + "i\t");
- continue;
- }
- out.write(String.format(FF, x[i][j]) + " + " + String.format(FF, x[i][j + 1]) + "i\t");
- }
- out.newLine();
- }
-
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 3D complex array. Complex data is represented by 2
- * double values in sequence: the real and imaginary parts.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param n3 third dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_3D(int n1, int n2, int n3, double[] x, String filename)
- {
- int sliceStride = n2 * n3 * 2;
- int rowStride = n3 * 2;
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int k = 0; k < 2 * n3; k = k + 2) {
- out.newLine();
- out.write("(:,:," + k / 2 + ")=");
- out.newLine();
- out.newLine();
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (x[i * sliceStride + j * rowStride + k + 1] == 0) {
- out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k] == 0) {
- out.write(String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- if (x[i * sliceStride + j * rowStride + k + 1] < 0) {
- out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " - " + String.format(FF, -x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- continue;
- }
- out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + " + " + String.format(FF, x[i * sliceStride + j * rowStride + k + 1]) + "i\t");
- }
- out.newLine();
- }
- }
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename. Complex
- * data is represented by 2 double values in sequence: the real and
- * imaginary parts.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileComplex_3D(double[][][] x, String filename)
- {
- int n1 = x.length;
- int n2 = x[0].length;
- int n3 = x[0][0].length;
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int k = 0; k < 2 * n3; k = k + 2) {
- out.newLine();
- out.write("(:,:," + k / 2 + ")=");
- out.newLine();
- out.newLine();
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (x[i][j][k + 1] == 0) {
- out.write(String.format(FF, x[i][j][k]) + "\t");
- continue;
- }
- if (x[i][j][k] == 0) {
- out.write(String.format(FF, x[i][j][k + 1]) + "i\t");
- continue;
- }
- if (x[i][j][k + 1] < 0) {
- out.write(String.format(FF, x[i][j][k]) + " - " + String.format(FF, -x[i][j][k + 1]) + "i\t");
- continue;
- }
- out.write(String.format(FF, x[i][j][k]) + " + " + String.format(FF, x[i][j][k + 1]) + "i\t");
- }
- out.newLine();
- }
- }
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D real array.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileReal_1D(double[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int j = 0; j < x.length; j++) {
- out.write(String.format(FF, x[j]));
- out.newLine();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D real array.
- *
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileReal_1D(float[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int j = 0; j < x.length; j++) {
- out.write(String.format(FF, x[j]));
- out.newLine();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D real array.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileReal_2D(int n1, int n2, double[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (Math.abs(x[i * n2 + j]) < 5e-5) {
- out.write("0\t");
- } else {
- out.write(String.format(FF, x[i * n2 + j]) + "\t");
- }
- }
- out.newLine();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 2D real array.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileReal_2D(int n1, int n2, float[] x, String filename)
- {
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- if (Math.abs(x[i * n2 + j]) < 5e-5) {
- out.write("0\t");
- } else {
- out.write(String.format(FF, x[i * n2 + j]) + "\t");
- }
- }
- out.newLine();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves elements of x in a file filename,
- * assuming that it is 3D real array.
- *
- * @param n1 first dimension
- * @param n2 second dimension
- * @param n3 third dimension
- * @param x input array
- * @param filename finename
- */
- public static void writeToFileReal_3D(int n1, int n2, int n3, double[] x, String filename)
- {
- int sliceStride = n2 * n3;
- int rowStride = n3;
-
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename));
- for (int k = 0; k < n3; k++) {
- out.newLine();
- out.write("(:,:," + k + ")=");
- out.newLine();
- out.newLine();
- for (int i = 0; i < n1; i++) {
- for (int j = 0; j < n2; j++) {
- out.write(String.format(FF, x[i * sliceStride + j * rowStride + k]) + "\t");
- }
- out.newLine();
- }
- out.newLine();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Saves benchmark results in a file.
- *
- * @param filename filename
- * @param nthread number of threads
- * @param niter number of iterations
- * @param doWarmup if warmup was performed
- * @param doScaling if scaling was performed
- * @param sizes benchmarked sizes
- * @param times_without_constructor timings excluding constructor
- * @param times_with_constructor timings including constructor
- */
- public static void writeFFTBenchmarkResultsToFile(String filename, int nthread, int niter, boolean doWarmup, boolean doScaling, long[] sizes, double[] times_without_constructor, double[] times_with_constructor)
- {
- String[] properties = {"os.name", "os.version", "os.arch", "java.vendor", "java.version"};
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(filename, false));
- out.write(new Date().toString());
- out.newLine();
- out.write("System properties:");
- out.newLine();
- out.write("\tos.name = " + System.getProperty(properties[0]));
- out.newLine();
- out.write("\tos.version = " + System.getProperty(properties[1]));
- out.newLine();
- out.write("\tos.arch = " + System.getProperty(properties[2]));
- out.newLine();
- out.write("\tjava.vendor = " + System.getProperty(properties[3]));
- out.newLine();
- out.write("\tjava.version = " + System.getProperty(properties[4]));
- out.newLine();
- out.write("\tavailable processors = " + Runtime.getRuntime().availableProcessors());
- out.newLine();
- out.write("Settings:");
- out.newLine();
- out.write("\tused processors = " + nthread);
- out.newLine();
- out.write("\tTHREADS_BEGIN_N_2D = " + ConcurrencyUtils.getThreadsBeginN_2D());
- out.newLine();
- out.write("\tTHREADS_BEGIN_N_3D = " + ConcurrencyUtils.getThreadsBeginN_3D());
- out.newLine();
- out.write("\tnumber of iterations = " + niter);
- out.newLine();
- out.write("\twarm-up performed = " + doWarmup);
- out.newLine();
- out.write("\tscaling performed = " + doScaling);
- out.newLine();
- out.write("--------------------------------------------------------------------------------------------------");
- out.newLine();
- out.write("sizes=[");
- for (int i = 0; i < sizes.length; i++) {
- out.write(Long.toString(sizes[i]));
- if (i < sizes.length - 1) {
- out.write(", ");
- } else {
- out.write("]");
- }
- }
- out.newLine();
- out.write("times without constructor(in msec)=[");
- for (int i = 0; i < times_without_constructor.length; i++) {
- out.write(String.format("%.2f", times_without_constructor[i]));
- if (i < times_without_constructor.length - 1) {
- out.write(", ");
- } else {
- out.write("]");
- }
- }
- out.newLine();
- out.write("times with constructor(in msec)=[");
- for (int i = 0; i < times_without_constructor.length; i++) {
- out.write(String.format("%.2f", times_with_constructor[i]));
- if (i < times_with_constructor.length - 1) {
- out.write(", ");
- } else {
- out.write("]");
- }
- }
- out.newLine();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-}
diff --git a/src/main/java/org/jtransforms/utils/package.html b/src/main/java/org/jtransforms/utils/package.html
deleted file mode 100644
index 4ee8eaa..0000000
--- a/src/main/java/org/jtransforms/utils/package.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Utility classes.
-
-
diff --git a/src/test/java/org/jtransforms/dct/DoubleDCT_1DTest.java b/src/test/java/org/jtransforms/dct/DoubleDCT_1DTest.java
deleted file mode 100644
index 786e9df..0000000
--- a/src/test/java/org/jtransforms/dct/DoubleDCT_1DTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * JTransforms
- * Copyright (c) 2007 onward, Piotr Wendykier
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * ***** END LICENSE BLOCK ***** */
-package org.jtransforms.dct;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Random;
-import org.jtransforms.utils.ConcurrencyUtils;
-import org.jtransforms.utils.IOUtils;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import pl.edu.icm.jlargearrays.DoubleLargeArray;
-
-/**
- * This is a series of JUnit tests for the {@link DoubleDCT_1D}.
- *
- * @author Piotr Wendykier
- */
-@RunWith(value = Parameterized.class)
-public class DoubleDCT_1DTest {
-
- /**
- * Base message of all exceptions.
- */
- public static final String DEFAULT_MESSAGE = "%d-threaded DCT of size %d: ";
-
- /**
- * The constant value of the seed of the random generator.
- */
- public static final int SEED = 20110602;
-
- private static final double EPS = Math.pow(10, -12);
-
- @Parameters
- public static Collection