All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apfloat.internal.DoubleTableFNT Maven / Gradle / Ivy

There is a newer version: 1.14.0
Show newest version
package org.apfloat.internal;

import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;

/**
 * Fast Number Theoretic Transform that uses lookup tables
 * for powers of n:th root of unity and permutation indexes.

* * All access to this class must be externally synchronized. * * @since 1.7.0 * @version 1.7.0 * @author Mikko Tommila */ public class DoubleTableFNT extends DoubleModMath { /** * Default constructor. */ public DoubleTableFNT() { } /** * Forward (Sande-Tukey) fast Number Theoretic Transform. * Data length must be a power of two. * * @param arrayAccess The data array to transform. * @param wTable Table of powers of n:th root of unity w modulo the current modulus. * @param permutationTable Table of permutation indexes, or null if the data should not be permuted. */ public void tableFNT(ArrayAccess arrayAccess, double[] wTable, int[] permutationTable) throws ApfloatRuntimeException { int nn, offset, istep, mmax, r; double[] data; data = arrayAccess.getDoubleData(); offset = arrayAccess.getOffset(); nn = arrayAccess.getLength(); assert (nn == (nn & -nn)); if (nn < 2) { return; } r = 1; mmax = nn >> 1; while (mmax > 0) { istep = mmax << 1; // Optimize first step when wr = 1 for (int i = offset; i < offset + nn; i += istep) { int j = i + mmax; double a = data[i]; double b = data[j]; data[i] = modAdd(a, b); data[j] = modSubtract(a, b); } int t = r; for (int m = 1; m < mmax; m++) { for (int i = offset + m; i < offset + nn; i += istep) { int j = i + mmax; double a = data[i]; double b = data[j]; data[i] = modAdd(a, b); data[j] = modMultiply(wTable[t], modSubtract(a, b)); } t += r; } r <<= 1; mmax >>= 1; } if (permutationTable != null) { DoubleScramble.scramble(data, offset, permutationTable); } } /** * Inverse (Cooley-Tukey) fast Number Theoretic Transform. * Data length must be a power of two. * * @param arrayAccess The data array to transform. * @param wTable Table of powers of n:th root of unity w modulo the current modulus. * @param permutationTable Table of permutation indexes, or null if the data should not be permuted. */ public void inverseTableFNT(ArrayAccess arrayAccess, double[] wTable, int[] permutationTable) throws ApfloatRuntimeException { int nn, offset, istep, mmax, r; double[] data; data = arrayAccess.getDoubleData(); offset = arrayAccess.getOffset(); nn = arrayAccess.getLength(); assert (nn == (nn & -nn)); if (nn < 2) { return; } if (permutationTable != null) { DoubleScramble.scramble(data, offset, permutationTable); } r = nn; mmax = 1; while (nn > mmax) { istep = mmax << 1; r >>= 1; // Optimize first step when w = 1 for (int i = offset; i < offset + nn; i += istep) { int j = i + mmax; double wTemp = data[j]; data[j] = modSubtract(data[i], wTemp); data[i] = modAdd(data[i], wTemp); } int t = r; for (int m = 1; m < mmax; m++) { for (int i = offset + m; i < offset + nn; i += istep) { int j = i + mmax; double wTemp = modMultiply(wTable[t], data[j]); data[j] = modSubtract(data[i], wTemp); data[i] = modAdd(data[i], wTemp); } t += r; } mmax = istep; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy