pax_global_header 0000666 0000000 0000000 00000000064 15113064030 0014503 g ustar 00root root 0000000 0000000 52 comment=4047e2ecdf6bd7f9df13e4700703dd46437edc2e
apfloat-1.15.0/ 0000775 0000000 0000000 00000000000 15113064030 0013215 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/.github/ 0000775 0000000 0000000 00000000000 15113064030 0014555 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/.github/workflows/ 0000775 0000000 0000000 00000000000 15113064030 0016612 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/.github/workflows/maven.yml 0000664 0000000 0000000 00000002267 15113064030 0020452 0 ustar 00root root 0000000 0000000 # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Java CI with Maven
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: write
security-events: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'corretto'
check-latest: true
cache: maven
- name: Build with Maven
run: mvn -B clean package -Dgpg.skip -Djarsigner.skip
# Optional: Uploads the full dependency graph to GitHub to improve the quality of Dependabot alerts this repository can receive
- name: Update dependency graph
uses: advanced-security/maven-dependency-submission-action@v4
apfloat-1.15.0/.gitignore 0000664 0000000 0000000 00000000213 15113064030 0015201 0 ustar 00root root 0000000 0000000 # Eclipse
.classpath
.metadata/
.project
.settings/
# Intellij
.idea/
*.iml
*.iws
# Mac
.DS_Store
# Maven
log/
target/
apfloat-1.15.0/LICENSE.txt 0000664 0000000 0000000 00000002101 15113064030 0015032 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2025 Mikko Tommila
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. apfloat-1.15.0/README.md 0000664 0000000 0000000 00000002151 15113064030 0014473 0 ustar 00root root 0000000 0000000 # Apfloat
Copyright © 2025 Mikko Tommila
This work is licensed under the terms of the MIT license. See the [MIT License](LICENSE.txt) for more details.
If you have any questions or need a different type of license, please [contact the author](mailto:Mikko.Tommila@apfloat.org).
## Building the Library
To build the library quickly, without running unit tests (takes about 20 minutes) and without signing with GPG run:
`mvn clean install -Dgpg.skip -Djarsigner.skip -DskipTests`
To build the signed applet files, you need to first generate a signing key, e.g. with:
`keytool -genkeypair -validity 21915 -dname "cn=Your Name, o=example.com" -storepass password -keypass password -alias mykey`
and then build without -Djarsigner.skip.
## Running the Sample Applications
To run the arbitrary precision calculator, run:
`mvn -pl :apfloat-calc exec:java -Dexec.mainClass=org.apfloat.calc.CalculatorGUI`
To run the pi calculator, run:
`mvn -pl :apfloat-samples exec:java -Dexec.mainClass=org.apfloat.samples.PiParallelGUI`
## Apfloat website
Go to the [apfloat for Java website](https://www.apfloat.org/apfloat_java/).
apfloat-1.15.0/apfloat-aparapi/ 0000775 0000000 0000000 00000000000 15113064030 0016256 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/pom.xml 0000664 0000000 0000000 00000005074 15113064030 0017601 0 ustar 00root root 0000000 0000000
* * This transform only works together with an {@link NTTStepStrategy} implementation * that processes the data in columns instead of rows and a {@link MatrixStrategy} * implementation that can transpose the data.
* * The data size should be sufficiently large to meet the parallelization needs of the GPU. * The GPU global size i.e. the number of columns in the data matrix should be at least 1024. * * @since 1.8.3 * @version 1.8.3 * @author Mikko Tommila */ public class ColumnSixStepFNTStrategy extends SixStepFNTStrategy { /** * Basic constructor. * * @param stepStrategy A step strategy that can process data in columns. * @param matrixStrategy A matrix strategy that can process the data. */ public ColumnSixStepFNTStrategy(NTTStepStrategy stepStrategy, MatrixStrategy matrixStrategy) { super.stepStrategy = stepStrategy; super.matrixStrategy = matrixStrategy; } @Override protected void transposeInitial(ArrayAccess arrayAccess, int n1, int n2, boolean isInverse) { // Omitted as we want to process the columns, not rows } @Override protected void transposeMiddle(ArrayAccess arrayAccess, int n1, int n2, boolean isInverse) { // Matrix is in transposed form compared to the normal six-step algorithm, so swap n1 and n2 super.transposeMiddle(arrayAccess, n2, n1, isInverse); } @Override protected void multiplyElements(ArrayAccess arrayAccess, int rows, int columns, long length, long totalTransformLength, boolean isInverse, int modulus) { // Matrix is in transposed form compared to the normal six-step algorithm, so swap rows and columns super.multiplyElements(arrayAccess, columns, rows, length, totalTransformLength, isInverse, modulus); } } apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/ColumnTwoPassFNTStrategy.java 0000664 0000000 0000000 00000007106 15113064030 0032264 0 ustar 00root root 0000000 0000000 /* * MIT License * * Copyright (c) 2002-2023 Mikko Tommila * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.apfloat.aparapi; import org.apfloat.internal.TwoPassFNTStrategy; import org.apfloat.spi.ArrayAccess; import org.apfloat.spi.DataStorage; import org.apfloat.spi.NTTStepStrategy; /** * Two-pass NTT implementation that processes the data in the columns of the matrix.
* * This transform only works together with an {@link NTTStepStrategy} implementation * that processes the data in columns instead of rows.
* * Note that if the data size is too big compared to the maximum available memory then the * data is read from disk in too thin slices and the level of parallelism may become too * small for the GPU, ruining the performance. The GPU global size i.e. the number of columns * read from the data matrix to memory at one time should be at least 1024. * * @since 1.8.3 * @version 1.8.3 * @author Mikko Tommila */ public class ColumnTwoPassFNTStrategy extends TwoPassFNTStrategy { /** * Basic constructor. * * @param stepStrategy A step strategy that can process data in columns. */ public ColumnTwoPassFNTStrategy(NTTStepStrategy stepStrategy) { // Note that there is no defaultStrategy here; if we get to the two-pass algorithm then we // assume that the data size is always "big enough" for a sufficient level of parallelism on the GPU super.stepStrategy = stepStrategy; } @Override protected ArrayAccess getColumns(DataStorage dataStorage, int startColumn, int columns, int rows) { // Get columns un-transposed return dataStorage.getArray(DataStorage.READ_WRITE, startColumn, columns, rows); } @Override protected ArrayAccess getRows(DataStorage dataStorage, int startRow, int rows, int columns) { // Get rows transposed as we want to organize the data in columns return dataStorage.subsequence(startRow * columns, rows * columns).getTransposedArray(DataStorage.READ_WRITE, 0, columns, rows); } @Override protected void multiplyElements(ArrayAccess arrayAccess, int startRow, int startColumn, int rows, int columns, long length, long totalTransformLength, boolean isInverse, int modulus) { // Data is processed in transposed form compared to the normal two-pass algorithm, so swap rows and columns super.multiplyElements(arrayAccess, startColumn, startRow, columns, rows, length, totalTransformLength, isInverse, modulus); } } apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/DecorableFactor3NTTStrategy.java 0000664 0000000 0000000 00000007774 15113064030 0032641 0 ustar 00root root 0000000 0000000 /* * MIT License * * Copyright (c) 2002-2025 Mikko Tommila * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.apfloat.aparapi; import org.apfloat.ApfloatRuntimeException; import org.apfloat.internal.ApfloatInternalException; import org.apfloat.internal.DecorableNTTStrategy; import org.apfloat.internal.Factor3NTTStrategy; import org.apfloat.spi.ArrayAccess; import org.apfloat.spi.DataStorage; import org.apfloat.spi.Factor3NTTStepStrategy; import org.apfloat.spi.NTTStrategy; /** * Factor-3 NTT strategy that can be decorated.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class DecorableFactor3NTTStrategy
extends Factor3NTTStrategy
implements DecorableNTTStrategy
{
/**
* Creates a new factor-3 transform strategy on top of an existing transform.
* The underlying transform needs to be capable of only doing transforms of
* length 2n.
*
* @param factor2Strategy The underlying transformation strategy, that can be capable of only doing radix-2 transforms.
*/
public DecorableFactor3NTTStrategy(NTTStrategy factor2Strategy)
{
super(factor2Strategy);
}
/**
* Creates a new factor-3 transform strategy on top of an existing factor-2 transform and a factor-3 step strategy.
*
* @param factor2Strategy The underlying transformation strategy, that can be capable of only doing radix-2 transforms.
* @param stepStrategy The factor-3 step strategy.
*/
public DecorableFactor3NTTStrategy(NTTStrategy factor2Strategy, Factor3NTTStepStrategy stepStrategy)
{
super(factor2Strategy, stepStrategy);
}
@Override
public void transform(DataStorage dataStorage, int modulus)
throws ApfloatRuntimeException
{
preTransform(dataStorage);
super.transform(dataStorage, modulus);
postTransform(dataStorage);
}
@Override
public void inverseTransform(DataStorage dataStorage, int modulus, long totalTransformLength)
throws ApfloatRuntimeException
{
preTransform(dataStorage);
super.inverseTransform(dataStorage, modulus, totalTransformLength);
postTransform(dataStorage);
}
private void preTransform(DataStorage dataStorage)
{
long length = dataStorage.getSize();
if (length > Integer.MAX_VALUE)
{
throw new ApfloatInternalException("Maximum array length exceeded: " + length);
}
ArrayAccess arrayAccess = dataStorage.getArray(DataStorage.READ_WRITE, 0, (int) length);
preTransform(arrayAccess);
}
private void postTransform(DataStorage dataStorage)
{
long length = dataStorage.getSize();
assert (length <= Integer.MAX_VALUE);
ArrayAccess arrayAccess = dataStorage.getArray(DataStorage.READ_WRITE, 0, (int) length);
postTransform(arrayAccess);
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiBuilderFactory.java 0000664 0000000 0000000 00000003715 15113064030 0032304 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatContext;
import org.apfloat.spi.NTTBuilder;
import org.apfloat.internal.IntBuilderFactory;
/**
* Builder factory for aparapi transform implementations for the int element type.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiBuilderFactory
extends IntBuilderFactory
{
/**
* Default constructor.
*/
public IntAparapiBuilderFactory()
{
boolean rowOrientation = Boolean.parseBoolean(ApfloatContext.getContext().getProperty("rowOrientation"));
this.nttBuilder = new IntAparapiNTTBuilder(rowOrientation);
}
@Override
public NTTBuilder getNTTBuilder()
{
return this.nttBuilder;
}
private NTTBuilder nttBuilder;
}
IntAparapiColumnSixStepFNTStrategy.java 0000664 0000000 0000000 00000003250 15113064030 0034151 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
/**
* Six-step NTT implementation for the int element type using column orientation.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiColumnSixStepFNTStrategy
extends ColumnSixStepFNTStrategy
implements IntAparapiNTTStrategy
{
/**
* Default constructor.
*/
public IntAparapiColumnSixStepFNTStrategy()
{
super(new IntAparapiNTTStepStrategy(false), new IntAparapiMatrixStrategy());
}
}
IntAparapiColumnTwoPassFNTStrategy.java 0000664 0000000 0000000 00000003210 15113064030 0034146 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
/**
* Two-pass NTT implementation for the int element type using column orientation.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiColumnTwoPassFNTStrategy
extends ColumnTwoPassFNTStrategy
implements IntAparapiNTTStrategy
{
/**
* Default constructor.
*/
public IntAparapiColumnTwoPassFNTStrategy()
{
super(new IntAparapiNTTStepStrategy(false));
}
}
IntAparapiFactor3NTTStepStrategy.java 0000664 0000000 0000000 00000010354 15113064030 0033552 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.DataStorage;
import com.aparapi.Range;
import org.apfloat.internal.ApfloatInternalException;
import org.apfloat.internal.IntFactor3NTTStepStrategy;
import static org.apfloat.internal.IntModConstants.*;
/**
* Steps for the factor-3 NTT using the GPU, for the int element type.
*
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class IntAparapiFactor3NTTStepStrategy
extends IntFactor3NTTStepStrategy
{
@Override
public void transformColumns(DataStorage dataStorage0, DataStorage dataStorage1, DataStorage dataStorage2, long startColumn, long columns, long power2length, long length, boolean isInverse, int modulus)
throws ApfloatRuntimeException
{
// Transform length is three times a power of two
assert (length == 3 * power2length);
// Check that the data storages use consecutive sections of the same memory array
if (!dataStorage0.isCached() || !dataStorage1.isCached() || !dataStorage2.isCached() ||
startColumn > Integer.MAX_VALUE || columns > Integer.MAX_VALUE)
{
throw new ApfloatInternalException("Data must be stored in memory");
}
ArrayAccess arrayAccess0 = dataStorage0.getArray(DataStorage.READ_WRITE, startColumn, (int) columns),
arrayAccess1 = dataStorage1.getArray(DataStorage.READ_WRITE, startColumn, (int) columns),
arrayAccess2 = dataStorage2.getArray(DataStorage.READ_WRITE, startColumn, (int) columns);
if (arrayAccess0.getIntData() != arrayAccess1.getIntData() || arrayAccess1.getIntData() != arrayAccess2.getIntData() ||
arrayAccess1.getOffset() != arrayAccess0.getOffset() + columns || arrayAccess2.getOffset() != arrayAccess1.getOffset() + columns)
{
throw new ApfloatInternalException("Data must be stored consecutively in memory");
}
setModulus(MODULUS[modulus]); // Modulus
int w = (isInverse ?
getInverseNthRoot(PRIMITIVE_ROOT[modulus], length) :
getForwardNthRoot(PRIMITIVE_ROOT[modulus], length)), // Forward/inverse n:th root
w3 = modPow(w, (int) power2length), // Forward/inverse 3rd root
ww = modMultiply(w, w),
w1 = negate(modDivide((int) 3, (int) 2)),
w2 = modAdd(w3, modDivide((int) 1, (int) 2));
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(isInverse ? IntKernel.INVERSE_TRANSFORM_COLUMNS : IntKernel.TRANSFORM_COLUMNS);
kernel.setArrayAccess(arrayAccess0);
kernel.setStartColumn((int) startColumn);
kernel.setColumns((int) columns);
kernel.setW(w);
kernel.setWw(ww);
kernel.setW1(w1);
kernel.setW2(w2);
kernel.setModulus(MODULUS[modulus]);
Range range = RangeHelper.create((int) columns);
kernel.execute(range);
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiFactor3NTTStrategy.java 0000664 0000000 0000000 00000003744 15113064030 0033002 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.spi.NTTStrategy;
/**
* Factor-3 NTT implementation for the int element type.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiFactor3NTTStrategy
extends DecorableFactor3NTTStrategy
implements IntAparapiNTTStrategy
{
/**
* Creates a new factor-3 transform strategy on top of an existing transform.
* The underlying transform needs to be capable of only doing transforms of
* length 2n.
*
* @param factor2Strategy The underlying transformation strategy, that can be capable of only doing radix-2 transforms.
*/
public IntAparapiFactor3NTTStrategy(NTTStrategy factor2Strategy)
{
super(factor2Strategy, new IntAparapiFactor3NTTStepStrategy());
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiMatrixStrategy.java 0000664 0000000 0000000 00000015414 15113064030 0032354 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.MatrixStrategy;
import org.apfloat.internal.ApfloatInternalException;
import com.aparapi.Range;
/**
* Matrix transposition in the GPU for the
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiSixStepFNTStrategy
extends SixStepFNTStrategy
implements IntAparapiNTTStrategy
{
/**
* Default constructor.
*/
public IntAparapiSixStepFNTStrategy()
{
super(new IntAparapiNTTStepStrategy(true), new IntAparapiMatrixStrategy());
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiTwoPassFNTStrategy.java 0000664 0000000 0000000 00000003245 15113064030 0033057 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.internal.TwoPassFNTStrategy;
/**
* Two-pass NTT implementation for the
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiTwoPassFNTStrategy
extends TwoPassFNTStrategy
implements IntAparapiNTTStrategy
{
/**
* Default constructor.
*/
public IntAparapiTwoPassFNTStrategy()
{
super(new IntAparapiNTTStepStrategy(true));
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntKernel.java 0000664 0000000 0000000 00000050647 15113064030 0027316 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import com.aparapi.Kernel;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
/**
* Kernel for the
*
* There are two ways the data can be organized:
*
*
* When the data is organized in rows, and the GPU cache is sufficiently large, the algorithm
* makes a fixed number of passes through the main memory of the GPU (and O(log n) passes
* through the GPU cache.)
*
* Due to the extreme parallelization requirements (global size should be at lest 1024)
* this algorithm works efficiently only with 4 million decimal digit calculations or bigger.
* However with 4 million digits, it's only approximately as fast as the pure-Java
* version (depending on the GPU and CPU hardware). On the other hand, the algorithm
* mathematically only works up to about 226 million digits. So the useful range is only
* somewhere around 10-200 million digits.
*
* Some notes about the aparapi specific requirements for code that must be converted to OpenCL:
*
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiColumnSixStepFNTStrategy
extends ColumnSixStepFNTStrategy
implements LongAparapiNTTStrategy
{
/**
* Default constructor.
*/
public LongAparapiColumnSixStepFNTStrategy()
{
super(new LongAparapiNTTStepStrategy(false), new LongAparapiMatrixStrategy());
}
}
LongAparapiColumnTwoPassFNTStrategy.java 0000664 0000000 0000000 00000003215 15113064030 0034320 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
/**
* Two-pass NTT implementation for the
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiColumnTwoPassFNTStrategy
extends ColumnTwoPassFNTStrategy
implements LongAparapiNTTStrategy
{
/**
* Default constructor.
*/
public LongAparapiColumnTwoPassFNTStrategy()
{
super(new LongAparapiNTTStepStrategy(false));
}
}
LongAparapiFactor3NTTStepStrategy.java 0000664 0000000 0000000 00000010405 15113064030 0033714 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.DataStorage;
import com.aparapi.Range;
import org.apfloat.internal.ApfloatInternalException;
import org.apfloat.internal.LongFactor3NTTStepStrategy;
import static org.apfloat.internal.LongModConstants.*;
/**
* Steps for the factor-3 NTT using the GPU, for the
*
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class LongAparapiFactor3NTTStepStrategy
extends LongFactor3NTTStepStrategy
{
@Override
public void transformColumns(DataStorage dataStorage0, DataStorage dataStorage1, DataStorage dataStorage2, long startColumn, long columns, long power2length, long length, boolean isInverse, int modulus)
throws ApfloatRuntimeException
{
// Transform length is three times a power of two
assert (length == 3 * power2length);
// Check that the data storages use consecutive sections of the same memory array
if (!dataStorage0.isCached() || !dataStorage1.isCached() || !dataStorage2.isCached() ||
startColumn > Integer.MAX_VALUE || columns > Integer.MAX_VALUE)
{
throw new ApfloatInternalException("Data must be stored in memory");
}
ArrayAccess arrayAccess0 = dataStorage0.getArray(DataStorage.READ_WRITE, startColumn, (int) columns),
arrayAccess1 = dataStorage1.getArray(DataStorage.READ_WRITE, startColumn, (int) columns),
arrayAccess2 = dataStorage2.getArray(DataStorage.READ_WRITE, startColumn, (int) columns);
if (arrayAccess0.getLongData() != arrayAccess1.getLongData() || arrayAccess1.getLongData() != arrayAccess2.getLongData() ||
arrayAccess1.getOffset() != arrayAccess0.getOffset() + columns || arrayAccess2.getOffset() != arrayAccess1.getOffset() + columns)
{
throw new ApfloatInternalException("Data must be stored consecutively in memory");
}
setModulus(MODULUS[modulus]); // Modulus
long w = (isInverse ?
getInverseNthRoot(PRIMITIVE_ROOT[modulus], length) :
getForwardNthRoot(PRIMITIVE_ROOT[modulus], length)), // Forward/inverse n:th root
w3 = modPow(w, (long) power2length), // Forward/inverse 3rd root
ww = modMultiply(w, w),
w1 = negate(modDivide((long) 3, (long) 2)),
w2 = modAdd(w3, modDivide((long) 1, (long) 2));
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(isInverse ? LongKernel.INVERSE_TRANSFORM_COLUMNS : LongKernel.TRANSFORM_COLUMNS);
kernel.setArrayAccess(arrayAccess0);
kernel.setStartColumn((int) startColumn);
kernel.setColumns((int) columns);
kernel.setW(w);
kernel.setWw(ww);
kernel.setW1(w1);
kernel.setW2(w2);
kernel.setModulus(MODULUS[modulus]);
Range range = RangeHelper.create((int) columns);
kernel.execute(range);
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiFactor3NTTStrategy.java 0000664 0000000 0000000 00000003751 15113064030 0033145 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.spi.NTTStrategy;
/**
* Factor-3 NTT implementation for the
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiFactor3NTTStrategy
extends DecorableFactor3NTTStrategy
implements LongAparapiNTTStrategy
{
/**
* Creates a new factor-3 transform strategy on top of an existing transform.
* The underlying transform needs to be capable of only doing transforms of
* length 2n.
*
* @param factor2Strategy The underlying transformation strategy, that can be capable of only doing radix-2 transforms.
*/
public LongAparapiFactor3NTTStrategy(NTTStrategy factor2Strategy)
{
super(factor2Strategy, new LongAparapiFactor3NTTStepStrategy());
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiMatrixStrategy.java 0000664 0000000 0000000 00000015430 15113064030 0032517 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.MatrixStrategy;
import org.apfloat.internal.ApfloatInternalException;
import com.aparapi.Range;
/**
* Matrix transposition in the GPU for the
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiSixStepFNTStrategy
extends SixStepFNTStrategy
implements LongAparapiNTTStrategy
{
/**
* Default constructor.
*/
public LongAparapiSixStepFNTStrategy()
{
super(new LongAparapiNTTStepStrategy(true), new LongAparapiMatrixStrategy());
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiTwoPassFNTStrategy.java 0000664 0000000 0000000 00000003252 15113064030 0033222 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.internal.TwoPassFNTStrategy;
/**
* Two-pass NTT implementation for the
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiTwoPassFNTStrategy
extends TwoPassFNTStrategy
implements LongAparapiNTTStrategy
{
/**
* Default constructor.
*/
public LongAparapiTwoPassFNTStrategy()
{
super(new LongAparapiNTTStepStrategy(true));
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongKernel.java 0000664 0000000 0000000 00000051074 15113064030 0027456 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import com.aparapi.Kernel;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
/**
* Kernel for the
*
* There are two ways the data can be organized:
*
*
* When the data is organized in rows, and the GPU cache is sufficiently large, the algorithm
* makes a fixed number of passes through the main memory of the GPU (and O(log n) passes
* through the GPU cache.)
*
* Due to the extreme parallelization requirements (global size should be at least 1024)
* this algorithm works efficiently only with 8 million decimal digit calculations or bigger.
* However with 8 million digits, it's only approximately as fast as the pure-Java
* version (depending on the GPU and CPU hardware). Depending on the total amount of memory
* available for the GPU this algorithm will fail (or revert to the very slow software emulation)
* e.g. at one-billion-digit calculations if your GPU has 1 GB of memory. The maximum power-of-two
* size for a Java array is one billion (230) so if your GPU has more than 8 GB of
* memory then the algorithm can never fail (as any Java long[] will always fit to the GPU memory).
*
* Some notes about the aparapi specific requirements for code that must be converted to OpenCL:
*
This package contains Number-Theoretic Transform implementations that can use
the GPU (Graphics Processing Unit) for executing the transforms. There is significant
overhead in invoking the GPU, e.g. in transferring the data between the main memory
and the GPU memory, so for small data sets there is usually no performance improvement,
and in many cases performance can be even significantly slower. However for very large
calculations, e.g. one billion digits, using the GPU can improve the performance noticeably,
depending on the hardware used.
*/
package org.apfloat.aparapi;
apfloat-1.15.0/apfloat-aparapi/src/main/resources/ 0000775 0000000 0000000 00000000000 15113064030 0022003 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/resources/META-INF/ 0000775 0000000 0000000 00000000000 15113064030 0023143 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/resources/META-INF/services/ 0000775 0000000 0000000 00000000000 15113064030 0024766 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/resources/META-INF/services/org.apfloat.spi.BuilderFactory 0000664 0000000 0000000 00000000135 15113064030 0032633 0 ustar 00root root 0000000 0000000 org.apfloat.aparapi.IntAparapiBuilderFactory
org.apfloat.aparapi.LongAparapiBuilderFactory
apfloat-1.15.0/apfloat-aparapi/src/test/ 0000775 0000000 0000000 00000000000 15113064030 0020024 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/ 0000775 0000000 0000000 00000000000 15113064030 0020745 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/ 0000775 0000000 0000000 00000000000 15113064030 0021534 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/ 0000775 0000000 0000000 00000000000 15113064030 0023162 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi/ 0000775 0000000 0000000 00000000000 15113064030 0024577 5 ustar 00root root 0000000 0000000 IntAparapiColumnSixStepFNTStrategyTest.java 0000664 0000000 0000000 00000005645 15113064030 0035056 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiColumnSixStepFNTStrategyTest
extends IntAparapiSixStepFNTStrategyTest
{
public IntAparapiColumnSixStepFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiColumnSixStepFNTStrategyTest("testForward"));
suite.addTest(new IntAparapiColumnSixStepFNTStrategyTest("testForwardBig"));
suite.addTest(new IntAparapiColumnSixStepFNTStrategyTest("testRoundTrip"));
suite.addTest(new IntAparapiColumnSixStepFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testForward()
{
runTestForward(1024);
}
public static void testForwardBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(8192);
runTestForward(4096);
}
private static void runTestForward(int size)
{
runTestForward(new IntAparapiColumnSixStepFNTStrategy(), size);
}
public static void testRoundTrip()
{
runRoundTrip(1024);
}
public static void testRoundTripBig()
{
int size = (int) Math.min(1 << 21, IntModConstants.MAX_TRANSFORM_LENGTH & -IntModConstants.MAX_TRANSFORM_LENGTH);
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new IntAparapiColumnSixStepFNTStrategy(), size);
}
}
IntAparapiColumnTwoPassFNTStrategyTest.java 0000664 0000000 0000000 00000005272 15113064030 0035053 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiColumnTwoPassFNTStrategyTest
extends IntNTTStrategyTestCase
{
public IntAparapiColumnTwoPassFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiColumnTwoPassFNTStrategyTest("testRoundTrip"));
suite.addTest(new IntAparapiColumnTwoPassFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
runRoundTrip(131072);
}
public static void testRoundTripBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
int size = (int) Math.min(1 << 21, Util.round2down(IntModConstants.MAX_TRANSFORM_LENGTH));
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new IntAparapiColumnTwoPassFNTStrategy(), size);
}
}
IntAparapiFactor3NTTStrategyTest.java 0000664 0000000 0000000 00000014642 15113064030 0033615 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.util.Arrays;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiFactor3NTTStrategyTest
extends IntNTTStrategyTestCase
{
public IntAparapiFactor3NTTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiFactor3NTTStrategyTest("testForward"));
suite.addTest(new IntAparapiFactor3NTTStrategyTest("testRoundTrip"));
suite.addTest(new IntAparapiFactor3NTTStrategyTest("testRoundTrip2"));
return suite;
}
public static void testForward()
{
runForward();
}
private static void runForward()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(Long.MAX_VALUE);
for (int modulus = 0; modulus < 3; modulus++)
{
int size = 3 * 2048;
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
int[] data = getPlainArray(dataStorage),
expectedTransform = ntt(data, modulus);
Arrays.sort(expectedTransform);
NTTStrategy nttStrategy = new IntAparapiFactor3NTTStrategy(new IntAparapiColumnSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
int[] actualTransform = getPlainArray(dataStorage);
Arrays.sort(actualTransform);
assertEquals("expected length", size, expectedTransform.length);
assertEquals("actual length", size, actualTransform.length);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], [" + i + "]", (long) expectedTransform[i], (long) actualTransform[i]);
}
}
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
int numberOfProcessors = ctx.getNumberOfProcessors();
ctx.setNumberOfProcessors(1);
ctx.setMemoryThreshold(Long.MAX_VALUE);
runRoundTrip();
ctx.setNumberOfProcessors(numberOfProcessors);
}
private static void runRoundTrip()
{
int size = (int) Math.min(3 * 1048576, IntModConstants.MAX_TRANSFORM_LENGTH); // Will use six-step transform
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
for (int modulus = 0; modulus < 3; modulus++)
{
Factor3NTTStrategy nttStrategy = new IntAparapiFactor3NTTStrategy(new IntAparapiColumnSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
assertEquals("transformed size", size, dataStorage.getSize());
DataStorage.Iterator iterator = dataStorage.iterator(DataStorage.READ, 0, 1);
assertTrue("transformed [0]", 6 != (long) iterator.getInt());
iterator.close();
nttStrategy.inverseTransform(dataStorage, modulus, size);
assertEquals("inverse transformed size", size, dataStorage.getSize());
iterator = dataStorage.iterator(DataStorage.READ, 0, size);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], round-tripped [" + i + "]", i + 6, (long) iterator.getInt());
iterator.next();
}
}
}
public static void testRoundTrip2()
{
ApfloatContext ctx = ApfloatContext.getContext();
int numberOfProcessors = ctx.getNumberOfProcessors();
ctx.setNumberOfProcessors(1);
ctx.setMemoryThreshold(Long.MAX_VALUE);
runRoundTrip2();
ctx.setNumberOfProcessors(numberOfProcessors);
}
private static void runRoundTrip2()
{
int size = 2048; // Will fall back to the power-of-two length transform
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
for (int modulus = 0; modulus < 3; modulus++)
{
Factor3NTTStrategy nttStrategy = new IntAparapiFactor3NTTStrategy(new IntAparapiSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
assertEquals("transformed size", size, dataStorage.getSize());
DataStorage.Iterator iterator = dataStorage.iterator(DataStorage.READ, 0, 1);
assertTrue("transformed [0]", 6 != (long) iterator.getInt());
iterator.close();
nttStrategy.inverseTransform(dataStorage, modulus, size);
assertEquals("inverse transformed size", size, dataStorage.getSize());
iterator = dataStorage.iterator(DataStorage.READ, 0, size);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], round-tripped [" + i + "]", i + 6, (long) iterator.getInt());
iterator.next();
}
}
}
}
apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi/IntAparapiMatrixStrategyTest.java 0000664 0000000 0000000 00000024645 15113064030 0033255 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class IntAparapiMatrixStrategyTest
extends IntTestCase
{
public IntAparapiMatrixStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiMatrixStrategyTest("testTransposeSquare"));
suite.addTest(new IntAparapiMatrixStrategyTest("testTransposeSquarePart"));
suite.addTest(new IntAparapiMatrixStrategyTest("testTransposeWide"));
suite.addTest(new IntAparapiMatrixStrategyTest("testTransposeTall"));
suite.addTest(new IntAparapiMatrixStrategyTest("testPermuteToDoubleWidth"));
suite.addTest(new IntAparapiMatrixStrategyTest("testPermuteToHalfWidth"));
return suite;
}
private static ArrayAccess getArray(int count)
{
int[] data = new int[count + 5];
ArrayAccess arrayAccess = new IntMemoryArrayAccess(data, 5, count);
for (int i = 0; i < count; i++)
{
data[i + 5] = (int) (i + 1);
}
return arrayAccess;
}
public static void testTransposeSquare()
{
ArrayAccess arrayAccess = getArray(16);
new IntAparapiMatrixStrategy().transpose(arrayAccess, 4, 4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("16 elem [" + i + "][" + j + "]", 4 * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 4 * i + j]);
}
}
arrayAccess = getArray(18).subsequence(1, 16);
new IntAparapiMatrixStrategy().transpose(arrayAccess, 4, 4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("16 elem sub [" + i + "][" + j + "]", 4 * j + i + 2, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 4 * i + j]);
}
}
ApfloatContext ctx = ApfloatContext.getContext();
int cacheBurstBlockSize = Util.round2down(ctx.getCacheBurst() / 4), // Cache burst in ints
cacheL1Size = Util.sqrt4down(ctx.getCacheL1Size() / 4), // To fit in processor L1 cache
cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 4), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
arrayAccess = getArray(cacheBurstBlockSize * cacheBurstBlockSize);
new IntAparapiMatrixStrategy().transpose(arrayAccess, cacheBurstBlockSize, cacheBurstBlockSize);
for (int i = 0; i < cacheBurstBlockSize; i++)
{
for (int j = 0; j < cacheBurstBlockSize; j++)
{
assertEquals("cacheBurstBlockSize [" + i + "][" + j + "]", cacheBurstBlockSize * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + cacheBurstBlockSize * i + j]);
}
}
arrayAccess = getArray(cacheL1Size * cacheL1Size);
new IntAparapiMatrixStrategy().transpose(arrayAccess, cacheL1Size, cacheL1Size);
for (int i = 0; i < cacheL1Size; i++)
{
for (int j = 0; j < cacheL1Size; j++)
{
assertEquals("cacheL1Size [" + i + "][" + j + "]", cacheL1Size * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + cacheL1Size * i + j]);
}
}
arrayAccess = getArray(cacheL2Size * cacheL2Size);
new IntAparapiMatrixStrategy().transpose(arrayAccess, cacheL2Size, cacheL2Size);
for (int i = 0; i < cacheL2Size; i++)
{
for (int j = 0; j < cacheL2Size; j++)
{
assertEquals("cacheL2Size [" + i + "][" + j + "]", cacheL2Size * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + cacheL2Size * i + j]);
}
}
arrayAccess = getArray(bigSize * bigSize);
new IntAparapiMatrixStrategy().transpose(arrayAccess, bigSize, bigSize);
for (int i = 0; i < bigSize; i++)
{
for (int j = 0; j < bigSize; j++)
{
assertEquals("bigSize [" + i + "][" + j + "]", bigSize * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + bigSize * i + j]);
}
}
}
public static void testTransposeSquarePart()
{
ArrayAccess arrayAccess = getArray(32);
new IntAparapiMatrixStrategy().transposeSquare(arrayAccess, 4, 8);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("1st transposed [" + i + "][" + j + "]", 8 * j + i + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 8 * i + j]);
}
for (int j = 4; j < 8; j++)
{
assertEquals("1st untransposed [" + i + "][" + j + "]", 8 * i + j + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 8 * i + j]);
}
}
arrayAccess = getArray(32);
new IntAparapiMatrixStrategy().transposeSquare(arrayAccess.subsequence(4, 28), 4, 8);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("2nd untransposed [" + i + "][" + j + "]", 8 * i + j + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 8 * i + j]);
}
for (int j = 4; j < 8; j++)
{
assertEquals("2nd transposed [" + i + "][" + j + "]", 8 * (j - 4) + (i + 4) + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 8 * i + j]);
}
}
}
public static void testTransposeWide()
{
ApfloatContext ctx = ApfloatContext.getContext();
int cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 4), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
ArrayAccess arrayAccess = getArray(2 * bigSize * bigSize + 5).subsequence(5, 2 * bigSize * bigSize);
new IntAparapiMatrixStrategy().transpose(arrayAccess, bigSize, 2 * bigSize);
for (int i = 0; i < 2 * bigSize; i++)
{
for (int j = 0; j < bigSize; j++)
{
assertEquals("transposed [" + i + "][" + j + "]", 2 * bigSize * j + i + 6, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + bigSize * i + j]);
}
}
}
public static void testTransposeTall()
{
ApfloatContext ctx = ApfloatContext.getContext();
int cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 4), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
ArrayAccess arrayAccess = getArray(2 * bigSize * bigSize + 5).subsequence(5, 2 * bigSize * bigSize);
new IntAparapiMatrixStrategy().transpose(arrayAccess, 2 * bigSize, bigSize);
for (int i = 0; i < bigSize; i++)
{
for (int j = 0; j < 2 * bigSize; j++)
{
assertEquals("transposed [" + i + "][" + j + "]", bigSize * j + i + 6, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 2 * bigSize * i + j]);
}
}
}
public static void testPermuteToDoubleWidth()
{
ArrayAccess arrayAccess = getArray(256);
new IntAparapiMatrixStrategy().permuteToDoubleWidth(arrayAccess, 8, 32);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to double width [" + i + "][" + j + "]", 32 * i + j + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 64 * i + j]);
}
for (int j = 32; j < 64; j++)
{
assertEquals("permuted to double width [" + i + "][" + j + "]", 32 * i + j - 32 + 128 + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 64 * i + j]);
}
}
}
public static void testPermuteToHalfWidth()
{
ArrayAccess arrayAccess = getArray(256);
new IntAparapiMatrixStrategy().permuteToHalfWidth(arrayAccess, 4, 64);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to half width [" + i + "][" + j + "]", 64 * i + j + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 32 * i + j]);
}
}
for (int i = 4; i < 8; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to half width [" + i + "][" + j + "]", 64 * (i - 4) + j + 32 + 1, (long) arrayAccess.getIntData()[arrayAccess.getOffset() + 32 * i + j]);
}
}
}
}
IntAparapiSixStepFNTStrategyTest.java 0000664 0000000 0000000 00000007702 15113064030 0033674 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.util.Arrays;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiSixStepFNTStrategyTest
extends IntNTTStrategyTestCase
{
public IntAparapiSixStepFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiSixStepFNTStrategyTest("testForward"));
suite.addTest(new IntAparapiSixStepFNTStrategyTest("testForwardBig"));
suite.addTest(new IntAparapiSixStepFNTStrategyTest("testRoundTrip"));
suite.addTest(new IntAparapiSixStepFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testForward()
{
runTestForward(1024);
}
public static void testForwardBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(8192);
runTestForward(4096);
}
private static void runTestForward(int size)
{
runTestForward(new IntAparapiSixStepFNTStrategy(), size);
}
protected static void runTestForward(AbstractStepFNTStrategy nttStrategy, int size)
{
for (int modulus = 0; modulus < 3; modulus++)
{
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
int[] data = getPlainArray(dataStorage),
expectedTransform = ntt(data, modulus);
IntScramble.scramble(expectedTransform, 0, Scramble.createScrambleTable(size));
Arrays.sort(expectedTransform);
nttStrategy.transform(dataStorage, modulus);
int[] actualTransform = getPlainArray(dataStorage);
Arrays.sort(actualTransform);
assertEquals("expected length", size, expectedTransform.length);
assertEquals("actual length", size, actualTransform.length);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], [" + i + "]", (long) expectedTransform[i], (long) actualTransform[i]);
}
}
}
public static void testRoundTrip()
{
runRoundTrip(1024);
}
public static void testRoundTripBig()
{
int size = (int) Math.min(1 << 21, IntModConstants.MAX_TRANSFORM_LENGTH & -IntModConstants.MAX_TRANSFORM_LENGTH);
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new IntAparapiSixStepFNTStrategy(), size);
}
}
IntAparapiTwoPassFNTStrategyTest.java 0000664 0000000 0000000 00000005234 15113064030 0033673 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiTwoPassFNTStrategyTest
extends IntNTTStrategyTestCase
{
public IntAparapiTwoPassFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new IntAparapiTwoPassFNTStrategyTest("testRoundTrip"));
suite.addTest(new IntAparapiTwoPassFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
runRoundTrip(131072);
}
public static void testRoundTripBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
int size = (int) Math.min(1 << 21, Util.round2down(IntModConstants.MAX_TRANSFORM_LENGTH));
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new IntAparapiTwoPassFNTStrategy(), size);
}
}
LongAparapiColumnSixStepFNTStrategyTest.java 0000664 0000000 0000000 00000005660 15113064030 0035220 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiColumnSixStepFNTStrategyTest
extends LongAparapiSixStepFNTStrategyTest
{
public LongAparapiColumnSixStepFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiColumnSixStepFNTStrategyTest("testForward"));
suite.addTest(new LongAparapiColumnSixStepFNTStrategyTest("testForwardBig"));
suite.addTest(new LongAparapiColumnSixStepFNTStrategyTest("testRoundTrip"));
suite.addTest(new LongAparapiColumnSixStepFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testForward()
{
runTestForward(1024);
}
public static void testForwardBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(8192);
runTestForward(4096);
}
private static void runTestForward(int size)
{
runTestForward(new LongAparapiColumnSixStepFNTStrategy(), size);
}
public static void testRoundTrip()
{
runRoundTrip(1024);
}
public static void testRoundTripBig()
{
int size = (int) Math.min(1 << 21, LongModConstants.MAX_TRANSFORM_LENGTH & -LongModConstants.MAX_TRANSFORM_LENGTH);
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new LongAparapiColumnSixStepFNTStrategy(), size);
}
}
LongAparapiColumnTwoPassFNTStrategyTest.java 0000664 0000000 0000000 00000005301 15113064030 0035211 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiColumnTwoPassFNTStrategyTest
extends LongNTTStrategyTestCase
{
public LongAparapiColumnTwoPassFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiColumnTwoPassFNTStrategyTest("testRoundTrip"));
suite.addTest(new LongAparapiColumnTwoPassFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
runRoundTrip(131072);
}
public static void testRoundTripBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
int size = (int) Math.min(1 << 21, Util.round2down(LongModConstants.MAX_TRANSFORM_LENGTH));
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new LongAparapiColumnTwoPassFNTStrategy(), size);
}
}
LongAparapiFactor3NTTStrategyTest.java 0000664 0000000 0000000 00000014665 15113064030 0033767 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.util.Arrays;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiFactor3NTTStrategyTest
extends LongNTTStrategyTestCase
{
public LongAparapiFactor3NTTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiFactor3NTTStrategyTest("testForward"));
suite.addTest(new LongAparapiFactor3NTTStrategyTest("testRoundTrip"));
suite.addTest(new LongAparapiFactor3NTTStrategyTest("testRoundTrip2"));
return suite;
}
public static void testForward()
{
runForward();
}
private static void runForward()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(Long.MAX_VALUE);
for (int modulus = 0; modulus < 3; modulus++)
{
int size = 3 * 2048;
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
long[] data = getPlainArray(dataStorage),
expectedTransform = ntt(data, modulus);
Arrays.sort(expectedTransform);
NTTStrategy nttStrategy = new LongAparapiFactor3NTTStrategy(new LongAparapiColumnSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
long[] actualTransform = getPlainArray(dataStorage);
Arrays.sort(actualTransform);
assertEquals("expected length", size, expectedTransform.length);
assertEquals("actual length", size, actualTransform.length);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], [" + i + "]", (long) expectedTransform[i], (long) actualTransform[i]);
}
}
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
int numberOfProcessors = ctx.getNumberOfProcessors();
ctx.setNumberOfProcessors(1);
ctx.setMemoryThreshold(Long.MAX_VALUE);
runRoundTrip();
ctx.setNumberOfProcessors(numberOfProcessors);
}
private static void runRoundTrip()
{
int size = (int) Math.min(3 * 1048576, LongModConstants.MAX_TRANSFORM_LENGTH); // Will use six-step transform
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
for (int modulus = 0; modulus < 3; modulus++)
{
Factor3NTTStrategy nttStrategy = new LongAparapiFactor3NTTStrategy(new LongAparapiColumnSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
assertEquals("transformed size", size, dataStorage.getSize());
DataStorage.Iterator iterator = dataStorage.iterator(DataStorage.READ, 0, 1);
assertTrue("transformed [0]", 6 != (long) iterator.getLong());
iterator.close();
nttStrategy.inverseTransform(dataStorage, modulus, size);
assertEquals("inverse transformed size", size, dataStorage.getSize());
iterator = dataStorage.iterator(DataStorage.READ, 0, size);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], round-tripped [" + i + "]", i + 6, (long) iterator.getLong());
iterator.next();
}
}
}
public static void testRoundTrip2()
{
ApfloatContext ctx = ApfloatContext.getContext();
int numberOfProcessors = ctx.getNumberOfProcessors();
ctx.setNumberOfProcessors(1);
ctx.setMemoryThreshold(Long.MAX_VALUE);
runRoundTrip2();
ctx.setNumberOfProcessors(numberOfProcessors);
}
private static void runRoundTrip2()
{
int size = 2048; // Will fall back to the power-of-two length transform
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
for (int modulus = 0; modulus < 3; modulus++)
{
Factor3NTTStrategy nttStrategy = new LongAparapiFactor3NTTStrategy(new LongAparapiSixStepFNTStrategy());
nttStrategy.transform(dataStorage, modulus);
assertEquals("transformed size", size, dataStorage.getSize());
DataStorage.Iterator iterator = dataStorage.iterator(DataStorage.READ, 0, 1);
assertTrue("transformed [0]", 6 != (long) iterator.getLong());
iterator.close();
nttStrategy.inverseTransform(dataStorage, modulus, size);
assertEquals("inverse transformed size", size, dataStorage.getSize());
iterator = dataStorage.iterator(DataStorage.READ, 0, size);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], round-tripped [" + i + "]", i + 6, (long) iterator.getLong());
iterator.next();
}
}
}
}
apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi/LongAparapiMatrixStrategyTest.java 0000664 0000000 0000000 00000024717 15113064030 0033422 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2023 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class LongAparapiMatrixStrategyTest
extends LongTestCase
{
public LongAparapiMatrixStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiMatrixStrategyTest("testTransposeSquare"));
suite.addTest(new LongAparapiMatrixStrategyTest("testTransposeSquarePart"));
suite.addTest(new LongAparapiMatrixStrategyTest("testTransposeWide"));
suite.addTest(new LongAparapiMatrixStrategyTest("testTransposeTall"));
suite.addTest(new LongAparapiMatrixStrategyTest("testPermuteToDoubleWidth"));
suite.addTest(new LongAparapiMatrixStrategyTest("testPermuteToHalfWidth"));
return suite;
}
private static ArrayAccess getArray(int count)
{
long[] data = new long[count + 5];
ArrayAccess arrayAccess = new LongMemoryArrayAccess(data, 5, count);
for (int i = 0; i < count; i++)
{
data[i + 5] = (long) (i + 1);
}
return arrayAccess;
}
public static void testTransposeSquare()
{
ArrayAccess arrayAccess = getArray(16);
new LongAparapiMatrixStrategy().transpose(arrayAccess, 4, 4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("16 elem [" + i + "][" + j + "]", 4 * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 4 * i + j]);
}
}
arrayAccess = getArray(18).subsequence(1, 16);
new LongAparapiMatrixStrategy().transpose(arrayAccess, 4, 4);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("16 elem sub [" + i + "][" + j + "]", 4 * j + i + 2, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 4 * i + j]);
}
}
ApfloatContext ctx = ApfloatContext.getContext();
int cacheBurstBlockSize = Util.round2down(ctx.getCacheBurst() / 8), // Cache burst in longs
cacheL1Size = Util.sqrt4down(ctx.getCacheL1Size() / 8), // To fit in processor L1 cache
cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 8), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
arrayAccess = getArray(cacheBurstBlockSize * cacheBurstBlockSize);
new LongAparapiMatrixStrategy().transpose(arrayAccess, cacheBurstBlockSize, cacheBurstBlockSize);
for (int i = 0; i < cacheBurstBlockSize; i++)
{
for (int j = 0; j < cacheBurstBlockSize; j++)
{
assertEquals("cacheBurstBlockSize [" + i + "][" + j + "]", cacheBurstBlockSize * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + cacheBurstBlockSize * i + j]);
}
}
arrayAccess = getArray(cacheL1Size * cacheL1Size);
new LongAparapiMatrixStrategy().transpose(arrayAccess, cacheL1Size, cacheL1Size);
for (int i = 0; i < cacheL1Size; i++)
{
for (int j = 0; j < cacheL1Size; j++)
{
assertEquals("cacheL1Size [" + i + "][" + j + "]", cacheL1Size * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + cacheL1Size * i + j]);
}
}
arrayAccess = getArray(cacheL2Size * cacheL2Size);
new LongAparapiMatrixStrategy().transpose(arrayAccess, cacheL2Size, cacheL2Size);
for (int i = 0; i < cacheL2Size; i++)
{
for (int j = 0; j < cacheL2Size; j++)
{
assertEquals("cacheL2Size [" + i + "][" + j + "]", cacheL2Size * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + cacheL2Size * i + j]);
}
}
arrayAccess = getArray(bigSize * bigSize);
new LongAparapiMatrixStrategy().transpose(arrayAccess, bigSize, bigSize);
for (int i = 0; i < bigSize; i++)
{
for (int j = 0; j < bigSize; j++)
{
assertEquals("bigSize [" + i + "][" + j + "]", bigSize * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + bigSize * i + j]);
}
}
}
public static void testTransposeSquarePart()
{
ArrayAccess arrayAccess = getArray(32);
new LongAparapiMatrixStrategy().transposeSquare(arrayAccess, 4, 8);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("1st transposed [" + i + "][" + j + "]", 8 * j + i + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 8 * i + j]);
}
for (int j = 4; j < 8; j++)
{
assertEquals("1st untransposed [" + i + "][" + j + "]", 8 * i + j + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 8 * i + j]);
}
}
arrayAccess = getArray(32);
new LongAparapiMatrixStrategy().transposeSquare(arrayAccess.subsequence(4, 28), 4, 8);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
assertEquals("2nd untransposed [" + i + "][" + j + "]", 8 * i + j + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 8 * i + j]);
}
for (int j = 4; j < 8; j++)
{
assertEquals("2nd transposed [" + i + "][" + j + "]", 8 * (j - 4) + (i + 4) + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 8 * i + j]);
}
}
}
public static void testTransposeWide()
{
ApfloatContext ctx = ApfloatContext.getContext();
int cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 8), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
ArrayAccess arrayAccess = getArray(2 * bigSize * bigSize + 5).subsequence(5, 2 * bigSize * bigSize);
new LongAparapiMatrixStrategy().transpose(arrayAccess, bigSize, 2 * bigSize);
for (int i = 0; i < 2 * bigSize; i++)
{
for (int j = 0; j < bigSize; j++)
{
assertEquals("transposed [" + i + "][" + j + "]", 2 * bigSize * j + i + 6, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + bigSize * i + j]);
}
}
}
public static void testTransposeTall()
{
ApfloatContext ctx = ApfloatContext.getContext();
int cacheL2Size = Util.sqrt4down(ctx.getCacheL2Size() / 8), // To fit in processor L2 cache
bigSize = cacheL2Size * 2; // To not fit in processor L2 cache
ArrayAccess arrayAccess = getArray(2 * bigSize * bigSize + 5).subsequence(5, 2 * bigSize * bigSize);
new LongAparapiMatrixStrategy().transpose(arrayAccess, 2 * bigSize, bigSize);
for (int i = 0; i < bigSize; i++)
{
for (int j = 0; j < 2 * bigSize; j++)
{
assertEquals("transposed [" + i + "][" + j + "]", bigSize * j + i + 6, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 2 * bigSize * i + j]);
}
}
}
public static void testPermuteToDoubleWidth()
{
ArrayAccess arrayAccess = getArray(256);
new LongAparapiMatrixStrategy().permuteToDoubleWidth(arrayAccess, 8, 32);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to double width [" + i + "][" + j + "]", 32 * i + j + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 64 * i + j]);
}
for (int j = 32; j < 64; j++)
{
assertEquals("permuted to double width [" + i + "][" + j + "]", 32 * i + j - 32 + 128 + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 64 * i + j]);
}
}
}
public static void testPermuteToHalfWidth()
{
ArrayAccess arrayAccess = getArray(256);
new LongAparapiMatrixStrategy().permuteToHalfWidth(arrayAccess, 4, 64);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to half width [" + i + "][" + j + "]", 64 * i + j + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 32 * i + j]);
}
}
for (int i = 4; i < 8; i++)
{
for (int j = 0; j < 32; j++)
{
assertEquals("permuted to half width [" + i + "][" + j + "]", 64 * (i - 4) + j + 32 + 1, (long) arrayAccess.getLongData()[arrayAccess.getOffset() + 32 * i + j]);
}
}
}
}
LongAparapiSixStepFNTStrategyTest.java 0000664 0000000 0000000 00000007720 15113064030 0034041 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.util.Arrays;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiSixStepFNTStrategyTest
extends LongNTTStrategyTestCase
{
public LongAparapiSixStepFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiSixStepFNTStrategyTest("testForward"));
suite.addTest(new LongAparapiSixStepFNTStrategyTest("testForwardBig"));
suite.addTest(new LongAparapiSixStepFNTStrategyTest("testRoundTrip"));
suite.addTest(new LongAparapiSixStepFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testForward()
{
runTestForward(1024);
}
public static void testForwardBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMemoryThreshold(8192);
runTestForward(4096);
}
private static void runTestForward(int size)
{
runTestForward(new LongAparapiSixStepFNTStrategy(), size);
}
protected static void runTestForward(AbstractStepFNTStrategy nttStrategy, int size)
{
for (int modulus = 0; modulus < 3; modulus++)
{
DataStorage dataStorage = createDataStorage(size + 5).subsequence(5, size);
long[] data = getPlainArray(dataStorage),
expectedTransform = ntt(data, modulus);
LongScramble.scramble(expectedTransform, 0, Scramble.createScrambleTable(size));
Arrays.sort(expectedTransform);
nttStrategy.transform(dataStorage, modulus);
long[] actualTransform = getPlainArray(dataStorage);
Arrays.sort(actualTransform);
assertEquals("expected length", size, expectedTransform.length);
assertEquals("actual length", size, actualTransform.length);
for (int i = 0; i < size; i++)
{
assertEquals("MODULUS[" + modulus + "], [" + i + "]", (long) expectedTransform[i], (long) actualTransform[i]);
}
}
}
public static void testRoundTrip()
{
runRoundTrip(1024);
}
public static void testRoundTripBig()
{
int size = (int) Math.min(1 << 21, LongModConstants.MAX_TRANSFORM_LENGTH & -LongModConstants.MAX_TRANSFORM_LENGTH);
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new LongAparapiSixStepFNTStrategy(), size);
}
}
LongAparapiTwoPassFNTStrategyTest.java 0000664 0000000 0000000 00000005243 15113064030 0034040 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/test/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.*;
import org.apfloat.spi.*;
import org.apfloat.internal.*;
import junit.framework.TestSuite;
/**
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiTwoPassFNTStrategyTest
extends LongNTTStrategyTestCase
{
public LongAparapiTwoPassFNTStrategyTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new LongAparapiTwoPassFNTStrategyTest("testRoundTrip"));
suite.addTest(new LongAparapiTwoPassFNTStrategyTest("testRoundTripBig"));
return suite;
}
public static void testRoundTrip()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
runRoundTrip(131072);
}
public static void testRoundTripBig()
{
ApfloatContext ctx = ApfloatContext.getContext();
ctx.setMaxMemoryBlockSize(65536);
ctx.setMemoryThreshold(1024);
ctx.setBlockSize(256);
int size = (int) Math.min(1 << 21, Util.round2down(LongModConstants.MAX_TRANSFORM_LENGTH));
runRoundTrip(size);
}
private static void runRoundTrip(int size)
{
runRoundTrip(new LongAparapiTwoPassFNTStrategy(), size);
}
}
apfloat-1.15.0/apfloat-applet/ 0000775 0000000 0000000 00000000000 15113064030 0016126 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-applet/pom.xml 0000664 0000000 0000000 00000003616 15113064030 0017451 0 ustar 00root root 0000000 0000000
*
* The precision of each calculation is determined separately, which means
* that loss of precision can easily accumulate in complicated calculations
* (e.g. matrix inversion). If this should be avoided, and a fixed precision is
* required, then it may be better to use {@link FixedPrecisionApcomplexField}
* instead.
*
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class ApcomplexField
extends AbstractField
*
* The precision of each calculation is determined separately, which means
* that loss of precision can easily accumulate in complicated calculations
* (e.g. matrix inversion). If this should be avoided, and a fixed precision is
* required, then it may be better to use {@link FixedPrecisionApfloatField}
* instead.
*
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class ApfloatField
extends AbstractField
*
* This class sets the modulus using {@link ModuloApintField#setModulus(Apint)}.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class EllipticCurveGroup
implements GroupAdditive
*
* For example, Curve25519 can be set with
*
*
*
*
* For the modulo integers to actually for a field, the modulus must
* be prime. Otherwise it's just a {@link Ring} and the {@link #inverse()}
* method may fail.
*
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class ModuloApintField
extends AbstractField
*
* For the polynomials to actually form a field, the modulus must be irreducible
* over the coefficient field. Otherwise it's just a {@link Ring} and the
* multiplicative {@link #inverse()} method may fail.
*
* @param
This package contains classes that allow using the apfloat library
classes with the JScience library. For example, it's possible
to perform arbitrary-precision matrix or polynomial operations.
*/
package org.apfloat.jscience;
apfloat-1.15.0/apfloat-jscience/src/test/ 0000775 0000000 0000000 00000000000 15113064030 0020172 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-jscience/src/test/java/ 0000775 0000000 0000000 00000000000 15113064030 0021113 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-jscience/src/test/java/org/ 0000775 0000000 0000000 00000000000 15113064030 0021702 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-jscience/src/test/java/org/apfloat/ 0000775 0000000 0000000 00000000000 15113064030 0023330 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-jscience/src/test/java/org/apfloat/jscience/ 0000775 0000000 0000000 00000000000 15113064030 0025113 5 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-jscience/src/test/java/org/apfloat/jscience/ApcomplexFieldTest.java 0000664 0000000 0000000 00000015125 15113064030 0031516 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.jscience;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashSet;
import org.apfloat.*;
import org.jscience.mathematics.function.*;
import org.jscience.mathematics.vector.*;
import javolution.text.*;
import javolution.xml.*;
import javolution.xml.stream.*;
import junit.framework.TestSuite;
/**
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class ApcomplexFieldTest
extends ApfloatTestCase
{
public ApcomplexFieldTest(String methodName)
{
super(methodName);
}
public static void main(String[] args)
{
junit.textui.TestRunner.run(suite());
}
public static TestSuite suite()
{
TestSuite suite = new TestSuite();
suite.addTest(new ApcomplexFieldTest("testBasic"));
suite.addTest(new ApcomplexFieldTest("testXmlSerialization"));
suite.addTest(new ApcomplexFieldTest("testMatrixInverse"));
suite.addTest(new ApcomplexFieldTest("testRationalFunction"));
return suite;
}
public static void testBasic()
{
ApcomplexField a = valueOf("(0,100)");
ApcomplexField b = valueOf("(0,200)");
ApcomplexField c = valueOf("(0,200)");
ApcomplexField zero = valueOf("0");
assertEquals("100 + 200", valueOf("(0,300)"), a.plus(b));
assertEquals("-100", valueOf("(0,-100)"), a.opposite());
assertEquals("100 - 200", valueOf("(0,-100)"), a.minus(b));
assertEquals("100 * 200", valueOf("-20000"), a.times(b));
assertEquals("1 / 100", valueOf("(0,-0.01)"), a.inverse());
assertEquals("copy", a, a.copy());
assertEquals("doubleValue", 0.0, a.doubleValue());
assertEquals("longValue", 0L, a.longValue());
assertEquals("String", "(0, 1e2)", a.toString());
assertEquals("Text", new Text("(0, 1e2)"), a.toText());
assertTrue("isLargerThan", b.isLargerThan(a));
assertEquals("compareTo", -1, a.compareTo(b));
HashSetint type.
*
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class IntAparapiMatrixStrategy
implements MatrixStrategy
{
/**
* Default constructor.
*/
public IntAparapiMatrixStrategy()
{
}
@Override
public void transpose(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
if (n1 == n2)
{
// Simply transpose
transposeSquare(arrayAccess, n1, n1);
}
else if (n2 == 2 * n1)
{
// First transpose two n1 x n1 blocks
transposeSquare(arrayAccess, n1, n2);
transposeSquare(arrayAccess.subsequence(n1, arrayAccess.getLength() - n1), n1, n2);
// Then permute the rows to correct order
permuteToHalfWidth(arrayAccess, n1, n2);
}
else if (n1 == 2 * n2)
{
// First permute the rows to correct order
permuteToDoubleWidth(arrayAccess, n1, n2);
// Then transpose two n2 x n2 blocks
transposeSquare(arrayAccess, n2, n1);
transposeSquare(arrayAccess.subsequence(n2, arrayAccess.getLength() - n2), n2, n1);
}
else
{
throw new ApfloatInternalException("Must be n1 = n2, n1 = 2*n2 or n2 = 2*n1; matrix is " + n1 + " x " + n2);
}
}
@Override
public void transposeSquare(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(IntKernel.TRANSPOSE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2);
Range range = RangeHelper.create2D(n1, n1);
kernel.execute(range);
}
@Override
public void permuteToHalfWidth(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
// Permute the rows of matrix to correct order, to make the n1 x n2 matrix half as wide (2*n1 x n2/2)
if (n1 < 2)
{
return;
}
int twicen1 = 2 * n1;
boolean[] isRowDone = new boolean[twicen1];
int[] index = new int[twicen1 * 2]; // Overly big but twicen1 just isn't enough
int j = 1,
p = 0;
do
{
int m = j;
index[p++] = m;
isRowDone[m] = true;
m = (m < n1 ? 2 * m : 2 * (m - n1) + 1);
while (m != j)
{
isRowDone[m] = true;
index[p++] = m;
m = (m < n1 ? 2 * m : 2 * (m - n1) + 1);
}
index[p++] = 0;
while (isRowDone[j])
{
j++;
}
} while (j < twicen1 - 1);
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(IntKernel.PERMUTE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2 / 2);
kernel.setIndex(index);
kernel.setIndexCount(p);
kernel.put(index);
Range range = RangeHelper.create(n2 / 2);
kernel.execute(range);
}
@Override
public void permuteToDoubleWidth(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
if (n1 < 2)
{
throw new ApfloatInternalException("Matrix height must be at least 2.");
}
// Permute the rows of matrix to correct order, to make the n1 x n2 matrix twice as wide (n1/2 x 2*n2)
if (n1 < 4)
{
return;
}
int halfn1 = n1 / 2;
boolean[] isRowDone = new boolean[n1];
int[] index = new int[n1 * 2]; // Overly big but n1 just isn't enough
int j = 1,
p = 0;
do
{
int m = j;
index[p++] = m;
isRowDone[m] = true;
m = ((m & 1) != 0 ? m / 2 + halfn1 : m / 2);
while (m != j)
{
isRowDone[m] = true;
index[p++] = m;
m = ((m & 1) != 0 ? m / 2 + halfn1 : m / 2);
}
index[p++] = 0;
while (isRowDone[j])
{
j++;
}
} while (j < n1 - 1);
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(IntKernel.PERMUTE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2);
kernel.setIndex(index);
kernel.setIndexCount(p);
kernel.put(index);
Range range = RangeHelper.create(n2);
kernel.execute(range);
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiNTTBuilder.java 0000664 0000000 0000000 00000006403 15113064030 0031337 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.spi.BuilderFactory;
import org.apfloat.spi.NTTStrategy;
import org.apfloat.ApfloatContext;
import org.apfloat.internal.IntNTTBuilder;
/**
* NTT Builder for aparapi transform implementations for the int element type.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiNTTBuilder
extends IntNTTBuilder
{
private static final int MIN_GPU_LENGTH = 1048576;
/**
* Basic constructor.
*
* @param rowOrientation If the data is using row orientation.
*/
public IntAparapiNTTBuilder(boolean rowOrientation)
{
this.rowOrientation = rowOrientation;
}
@Override
protected NTTStrategy createSixStepFNTStrategy(long size)
{
long length = size;
if (length < MIN_GPU_LENGTH)
{
return super.createSixStepFNTStrategy(size);
}
return this.rowOrientation ? new IntAparapiSixStepFNTStrategy() : new IntAparapiColumnSixStepFNTStrategy();
}
@Override
protected NTTStrategy createTwoPassFNTStrategy(long size)
{
long length = size;
if (length < MIN_GPU_LENGTH)
{
return super.createTwoPassFNTStrategy(size);
}
return (this.rowOrientation ? new IntAparapiTwoPassFNTStrategy() : new IntAparapiColumnTwoPassFNTStrategy());
}
@Override
protected NTTStrategy createFactor3NTTStrategy(long size, NTTStrategy nttStrategy)
{
if (nttStrategy instanceof IntAparapiNTTStrategy)
{
ApfloatContext ctx = ApfloatContext.getContext();
BuilderFactory builderFactory = ctx.getBuilderFactory();
long maxMemoryBlockSize = ctx.getMaxMemoryBlockSize() / builderFactory.getElementSize();
if (size <= maxMemoryBlockSize && size <= Integer.MAX_VALUE)
{
return new IntAparapiFactor3NTTStrategy(nttStrategy);
}
}
return super.createFactor3NTTStrategy(size, nttStrategy);
}
private boolean rowOrientation;
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiNTTStepStrategy.java 0000664 0000000 0000000 00000012524 15113064030 0032410 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import com.aparapi.Range;
import org.apfloat.internal.IntNTTStepStrategy;
import org.apfloat.internal.IntWTables;
import org.apfloat.internal.Scramble;
import static org.apfloat.internal.IntModConstants.*;
import org.apfloat.ApfloatContext;
/**
* NTT steps for the int element type aparapi transforms.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class IntAparapiNTTStepStrategy
extends IntNTTStepStrategy
{
/**
* Basic constructor.
*
* @param rowOrientation If the data is using row orientation.
*/
public IntAparapiNTTStepStrategy(boolean rowOrientation)
{
this.rowOrientation = rowOrientation;
}
@Override
public void multiplyElements(ArrayAccess arrayAccess, int startRow, int startColumn, int rows, int columns, long length, long totalTransformLength, boolean isInverse, int modulus)
throws ApfloatRuntimeException
{
setModulus(MODULUS[modulus]);
int w = (isInverse ?
getInverseNthRoot(PRIMITIVE_ROOT[modulus], length) :
getForwardNthRoot(PRIMITIVE_ROOT[modulus], length));
int scaleFactor = (isInverse ?
modDivide((int) 1, (int) totalTransformLength) :
(int) 1);
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(IntKernel.MULTIPLY_ELEMENTS);
kernel.setArrayAccess(arrayAccess);
kernel.setStartRow(startRow);
kernel.setStartColumn(startColumn);
kernel.setRows(rows);
kernel.setColumns(columns);
kernel.setW(w);
kernel.setScaleFactor(scaleFactor);
kernel.setModulus(MODULUS[modulus]);
Range range = RangeHelper.create(columns);
kernel.execute(range);
}
/**
* Transform the rows or columns of the data matrix.
* If the data is oriented in rows, transforms physically the rows.
* If the data is oriented in columns, transforms physically columns.
*
* @param arrayAccess The memory array to split and transform.
* @param length Length of one transform.
* @param count Number of transforms to be done.
* @param isInverse true if an inverse transform is performed, false if a forward transform is performed.
* @param permute If permutation should be done.
* @param modulus Index of the modulus.
*/
@Override
public void transformRows(ArrayAccess arrayAccess, int length, int count, boolean isInverse, boolean permute, int modulus)
throws ApfloatRuntimeException
{
int[] wTable = (isInverse ?
IntWTables.getInverseWTable(modulus, length) :
IntWTables.getWTable(modulus, length));
int[] permutationTable = (permute ? Scramble.createScrambleTable(length) : null);
IntKernel kernel = IntKernel.getInstance();
kernel.setOp(this.rowOrientation ? (isInverse ? IntKernel.INVERSE_TRANSFORM_ROWS_ROWORIENTATION : IntKernel.TRANSFORM_ROWS_ROWORIENTATION) :
(isInverse ? IntKernel.INVERSE_TRANSFORM_ROWS_COLUMNORIENTATION : IntKernel.TRANSFORM_ROWS_COLUMNORIENTATION));
kernel.setLength(length);
kernel.setArrayAccess(arrayAccess);
kernel.setWTable(wTable);
kernel.setPermutationTable(permutationTable);
kernel.setModulus(MODULUS[modulus]);
kernel.put(wTable);
if (permutationTable != null)
{
kernel.put(permutationTable);
}
Range range;
if (this.rowOrientation)
{
int workGroupSize = Integer.parseInt(ApfloatContext.getContext().getProperty("workGroupSize", String.valueOf(RangeHelper.MAX_LOCAL_SIZE)));
int width = Math.min(length, workGroupSize);
range = Range.create2D(width, count, width, 1);
}
else
{
range = RangeHelper.create(count);
}
kernel.execute(range);
}
private boolean rowOrientation;
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/IntAparapiNTTStrategy.java 0000664 0000000 0000000 00000006524 15113064030 0031557 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import org.apfloat.internal.NTTStrategyDecorator;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.NTTStrategy;
/**
* NTT strategy with decorator to set up the data for the GPU, for the int element type.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public interface IntAparapiNTTStrategy
extends NTTStrategy, NTTStrategyDecorator
{
/**
* @hidden
*/
static final ThreadLocalint element type using row orientation.int element type using row orientation.int element type. Contains everything needed for the NTT.
*
*
* When the data is organized in columns, the NTT algorithm makes O(log n) passes through
* the main memory of the GPU.
*
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
class IntKernel
extends Kernel
{
private IntKernel()
{
}
public static IntKernel getInstance()
{
return IntKernel.kernel.get();
}
private static ThreadLocalassert() does not work-glong element type.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiBuilderFactory
extends LongBuilderFactory
{
/**
* Default constructor.
*/
public LongAparapiBuilderFactory()
{
boolean rowOrientation = Boolean.parseBoolean(ApfloatContext.getContext().getProperty("rowOrientation"));
this.nttBuilder = new LongAparapiNTTBuilder(rowOrientation);
}
@Override
public NTTBuilder getNTTBuilder()
{
return this.nttBuilder;
}
private NTTBuilder nttBuilder;
}
LongAparapiColumnSixStepFNTStrategy.java 0000664 0000000 0000000 00000003256 15113064030 0034324 0 ustar 00root root 0000000 0000000 apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
/**
* Six-step NTT implementation for the long element type using column orientation.long element type using column orientation.long element type.long element type.long type.
*
* @since 1.8.3
* @version 1.8.3
* @author Mikko Tommila
*/
public class LongAparapiMatrixStrategy
implements MatrixStrategy
{
/**
* Default constructor.
*/
public LongAparapiMatrixStrategy()
{
}
@Override
public void transpose(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
if (n1 == n2)
{
// Simply transpose
transposeSquare(arrayAccess, n1, n1);
}
else if (n2 == 2 * n1)
{
// First transpose two n1 x n1 blocks
transposeSquare(arrayAccess, n1, n2);
transposeSquare(arrayAccess.subsequence(n1, arrayAccess.getLength() - n1), n1, n2);
// Then permute the rows to correct order
permuteToHalfWidth(arrayAccess, n1, n2);
}
else if (n1 == 2 * n2)
{
// First permute the rows to correct order
permuteToDoubleWidth(arrayAccess, n1, n2);
// Then transpose two n2 x n2 blocks
transposeSquare(arrayAccess, n2, n1);
transposeSquare(arrayAccess.subsequence(n2, arrayAccess.getLength() - n2), n2, n1);
}
else
{
throw new ApfloatInternalException("Must be n1 = n2, n1 = 2*n2 or n2 = 2*n1; matrix is " + n1 + " x " + n2);
}
}
@Override
public void transposeSquare(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(LongKernel.TRANSPOSE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2);
Range range = RangeHelper.create2D(n1, n1);
kernel.execute(range);
}
@Override
public void permuteToHalfWidth(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
// Permute the rows of matrix to correct order, to make the n1 x n2 matrix half as wide (2*n1 x n2/2)
if (n1 < 2)
{
return;
}
int twicen1 = 2 * n1;
boolean[] isRowDone = new boolean[twicen1];
int[] index = new int[twicen1 * 2]; // Overly big but twicen1 just isn't enough
int j = 1,
p = 0;
do
{
int m = j;
index[p++] = m;
isRowDone[m] = true;
m = (m < n1 ? 2 * m : 2 * (m - n1) + 1);
while (m != j)
{
isRowDone[m] = true;
index[p++] = m;
m = (m < n1 ? 2 * m : 2 * (m - n1) + 1);
}
index[p++] = 0;
while (isRowDone[j])
{
j++;
}
} while (j < twicen1 - 1);
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(LongKernel.PERMUTE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2 / 2);
kernel.setIndex(index);
kernel.setIndexCount(p);
kernel.put(index);
Range range = RangeHelper.create(n2 / 2);
kernel.execute(range);
}
@Override
public void permuteToDoubleWidth(ArrayAccess arrayAccess, int n1, int n2)
throws ApfloatRuntimeException
{
if (n1 != (n1 & -n1) ||
n2 != (n2 & -n2) ||
n1 <= 0 || n2 <= 0)
{
throw new ApfloatInternalException("Matrix size must be a power of two, not " + n1 + " x " + n2);
}
if (n1 < 2)
{
throw new ApfloatInternalException("Matrix height must be at least 2.");
}
// Permute the rows of matrix to correct order, to make the n1 x n2 matrix twice as wide (n1/2 x 2*n2)
if (n1 < 4)
{
return;
}
int halfn1 = n1 / 2;
boolean[] isRowDone = new boolean[n1];
int[] index = new int[n1 * 2]; // Overly big but n1 just isn't enough
int j = 1,
p = 0;
do
{
int m = j;
index[p++] = m;
isRowDone[m] = true;
m = ((m & 1) != 0 ? m / 2 + halfn1 : m / 2);
while (m != j)
{
isRowDone[m] = true;
index[p++] = m;
m = ((m & 1) != 0 ? m / 2 + halfn1 : m / 2);
}
index[p++] = 0;
while (isRowDone[j])
{
j++;
}
} while (j < n1 - 1);
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(LongKernel.PERMUTE);
kernel.setArrayAccess(arrayAccess);
kernel.setN2(n2);
kernel.setIndex(index);
kernel.setIndexCount(p);
kernel.put(index);
Range range = RangeHelper.create(n2);
kernel.execute(range);
}
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiNTTBuilder.java 0000664 0000000 0000000 00000006416 15113064030 0031510 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.spi.BuilderFactory;
import org.apfloat.spi.NTTStrategy;
import org.apfloat.ApfloatContext;
import org.apfloat.internal.LongNTTBuilder;
/**
* NTT Builder for aparapi transform implementations for the long element type.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiNTTBuilder
extends LongNTTBuilder
{
private static final int MIN_GPU_LENGTH = 1048576;
/**
* Basic constructor.
*
* @param rowOrientation If the data is using row orientation.
*/
public LongAparapiNTTBuilder(boolean rowOrientation)
{
this.rowOrientation = rowOrientation;
}
@Override
protected NTTStrategy createSixStepFNTStrategy(long size)
{
long length = size;
if (length < MIN_GPU_LENGTH)
{
return super.createSixStepFNTStrategy(size);
}
return this.rowOrientation ? new LongAparapiSixStepFNTStrategy() : new LongAparapiColumnSixStepFNTStrategy();
}
@Override
protected NTTStrategy createTwoPassFNTStrategy(long size)
{
long length = size;
if (length < MIN_GPU_LENGTH)
{
return super.createTwoPassFNTStrategy(size);
}
return (this.rowOrientation ? new LongAparapiTwoPassFNTStrategy() : new LongAparapiColumnTwoPassFNTStrategy());
}
@Override
protected NTTStrategy createFactor3NTTStrategy(long size, NTTStrategy nttStrategy)
{
if (nttStrategy instanceof LongAparapiNTTStrategy)
{
ApfloatContext ctx = ApfloatContext.getContext();
BuilderFactory builderFactory = ctx.getBuilderFactory();
long maxMemoryBlockSize = ctx.getMaxMemoryBlockSize() / builderFactory.getElementSize();
if (size <= maxMemoryBlockSize && size <= Integer.MAX_VALUE)
{
return new LongAparapiFactor3NTTStrategy(nttStrategy);
}
}
return super.createFactor3NTTStrategy(size, nttStrategy);
}
private boolean rowOrientation;
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiNTTStepStrategy.java 0000664 0000000 0000000 00000012562 15113064030 0032557 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import org.apfloat.ApfloatRuntimeException;
import org.apfloat.spi.ArrayAccess;
import com.aparapi.Range;
import org.apfloat.internal.LongNTTStepStrategy;
import org.apfloat.internal.LongWTables;
import org.apfloat.internal.Scramble;
import static org.apfloat.internal.LongModConstants.*;
import org.apfloat.ApfloatContext;
/**
* NTT steps for the long element type aparapi transforms.
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
public class LongAparapiNTTStepStrategy
extends LongNTTStepStrategy
{
/**
* Basic constructor.
*
* @param rowOrientation If the data is using row orientation.
*/
public LongAparapiNTTStepStrategy(boolean rowOrientation)
{
this.rowOrientation = rowOrientation;
}
@Override
public void multiplyElements(ArrayAccess arrayAccess, int startRow, int startColumn, int rows, int columns, long length, long totalTransformLength, boolean isInverse, int modulus)
throws ApfloatRuntimeException
{
setModulus(MODULUS[modulus]);
long w = (isInverse ?
getInverseNthRoot(PRIMITIVE_ROOT[modulus], length) :
getForwardNthRoot(PRIMITIVE_ROOT[modulus], length));
long scaleFactor = (isInverse ?
modDivide((long) 1, (long) totalTransformLength) :
(long) 1);
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(LongKernel.MULTIPLY_ELEMENTS);
kernel.setArrayAccess(arrayAccess);
kernel.setStartRow(startRow);
kernel.setStartColumn(startColumn);
kernel.setRows(rows);
kernel.setColumns(columns);
kernel.setW(w);
kernel.setScaleFactor(scaleFactor);
kernel.setModulus(MODULUS[modulus]);
Range range = RangeHelper.create(columns);
kernel.execute(range);
}
/**
* Transform the rows or columns of the data matrix.
* If the data is oriented in rows, transforms physically the rows.
* If the data is oriented in columns, transforms physically columns.
*
* @param arrayAccess The memory array to split and transform.
* @param length Length of one transform.
* @param count Number of transforms to be done.
* @param isInverse true if an inverse transform is performed, false if a forward transform is performed.
* @param permute If permutation should be done.
* @param modulus Index of the modulus.
*/
@Override
public void transformRows(ArrayAccess arrayAccess, int length, int count, boolean isInverse, boolean permute, int modulus)
throws ApfloatRuntimeException
{
long[] wTable = (isInverse ?
LongWTables.getInverseWTable(modulus, length) :
LongWTables.getWTable(modulus, length));
int[] permutationTable = (permute ? Scramble.createScrambleTable(length) : null);
LongKernel kernel = LongKernel.getInstance();
kernel.setOp(this.rowOrientation ? (isInverse ? LongKernel.INVERSE_TRANSFORM_ROWS_ROWORIENTATION : LongKernel.TRANSFORM_ROWS_ROWORIENTATION) :
(isInverse ? LongKernel.INVERSE_TRANSFORM_ROWS_COLUMNORIENTATION : LongKernel.TRANSFORM_ROWS_COLUMNORIENTATION));
kernel.setLength(length);
kernel.setArrayAccess(arrayAccess);
kernel.setWTable(wTable);
kernel.setPermutationTable(permutationTable);
kernel.setModulus(MODULUS[modulus]);
kernel.put(wTable);
if (permutationTable != null)
{
kernel.put(permutationTable);
}
Range range;
if (this.rowOrientation)
{
int workGroupSize = Integer.parseInt(ApfloatContext.getContext().getProperty("workGroupSize", String.valueOf(RangeHelper.MAX_LOCAL_SIZE)));
int width = Math.min(length, workGroupSize);
range = Range.create2D(width, count, width, 1);
}
else
{
range = RangeHelper.create(count);
}
kernel.execute(range);
}
private boolean rowOrientation;
}
apfloat-1.15.0/apfloat-aparapi/src/main/java/org/apfloat/aparapi/LongAparapiNTTStrategy.java 0000664 0000000 0000000 00000006537 15113064030 0031730 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.aparapi;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import org.apfloat.internal.NTTStrategyDecorator;
import org.apfloat.spi.ArrayAccess;
import org.apfloat.spi.NTTStrategy;
/**
* NTT strategy with decorator to set up the data for the GPU, for the long element type.
*
* @since 1.15.0
* @version 1.15.0
* @author Mikko Tommila
*/
public interface LongAparapiNTTStrategy
extends NTTStrategy, NTTStrategyDecorator
{
/**
* @hidden
*/
static final ThreadLocallong element type using row orientation.long element type using row orientation.long element type. Contains everything needed for the NTT.
*
*
* When the data is organized in columns, the NTT algorithm makes O(log n) passes through
* the main memory of the GPU.
*
*
* @since 1.8.3
* @version 1.15.0
* @author Mikko Tommila
*/
class LongKernel
extends Kernel
{
private LongKernel()
{
}
public static LongKernel getInstance()
{
return LongKernel.kernel.get();
}
private static ThreadLocalassert() does not work-gnull for arbitrary precision.
*/
protected Long getInputPrecision()
{
return this.inputPrecision;
}
private static List-x
*
* @exception ParseException In case of invalid argument.
*/
public Number negate(Number x)
throws ParseException;
/**
* Addition.
*
* @param x First argument.
* @param y Second argument.
*
* @return x + y
*
* @exception ParseException In case of invalid arguments.
*/
public Number add(Number x, Number y)
throws ParseException;
/**
* Subtraction.
*
* @param x First argument.
* @param y Second argument.
*
* @return x - y
*
* @exception ParseException In case of invalid arguments.
*/
public Number subtract(Number x, Number y)
throws ParseException;
/**
* Multiplication.
*
* @param x First argument.
* @param y Second argument.
*
* @return x * y
*
* @exception ParseException In case of invalid arguments.
*/
public Number multiply(Number x, Number y)
throws ParseException;
/**
* Division.
*
* @param x First argument.
* @param y Second argument.
*
* @return x / y
*
* @exception ParseException In case of invalid arguments.
*/
public Number divide(Number x, Number y)
throws ParseException;
/**
* Remainder.
*
* @param x First argument.
* @param y Second argument.
*
* @return x % y
*
* @exception ParseException In case of invalid arguments.
*/
public Number mod(Number x, Number y)
throws ParseException;
/**
* Power.
*
* @param x First argument.
* @param y Second argument.
*
* @return xy
*
* @exception ParseException In case of invalid arguments.
*/
public Number pow(Number x, Number y)
throws ParseException;
/**
* Factorial.
*
* @param x The argument.
*
* @return x!
*
* @exception ParseException In case of invalid arguments.
*/
public Number factorial(Number x)
throws ParseException;
/**
* Double factorial.
*
* @param x The argument.
*
* @return x!!
*
* @exception ParseException In case of invalid arguments.
*/
public Number doubleFactorial(Number x)
throws ParseException;
/**
* Arbitrary function.
*
* @param name Name of the function.
* @param arguments Function arguments.
*
* @return Function value.
*
* @exception ParseException In case of invalid arguments.
*/
public Number function(String name, Listnull if the variable is not defined.
*
* @exception ParseException In case of invalid argument.
*/
public Number getVariable(String name)
throws ParseException;
/**
* Set a variable.
*
* @param name Name of the variable.
* @param value Value of the variable.
*
* @exception ParseException In case of invalid arguments.
*/
public void setVariable(String name, Number value)
throws ParseException;
/**
* Set the formatting option.
*
* @param pretty If a fixed-point or a floating-point notation should be used.
*/
public void setFormat(boolean pretty);
/**
* Set a fixed input precision.
*
* @param inputPrecision The precision if a fixed precision is used or null for arbitrary precision.
*/
public void setInputPrecision(Long inputPrecision);
/**
* Convert a number to a String. The current formatting option is used.
*
* @param x The number.
*
* @return The String.
*/
public String format(Number x);
}
apfloat-1.15.0/apfloat-calc/src/main/java/org/apfloat/calc/CalculatorParser.jj 0000664 0000000 0000000 00000015343 15113064030 0027117 0 ustar 00root root 0000000 0000000 options
{
LOOKAHEAD = 2;
STATIC = false;
UNICODE_INPUT = true;
ERROR_REPORTING = false;
}
PARSER_BEGIN(CalculatorParser)
package org.apfloat.calc;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.List;
import java.util.ArrayList;
public class CalculatorParser
{
public CalculatorParser(InputStream in, OutputStream out, CalculatorImpl calculatorImpl)
{
this(in);
this.out = new PrintWriter(new OutputStreamWriter(out), true);
this.calculatorImpl = calculatorImpl;
}
public CalculatorParser(Reader in, Writer out, CalculatorImpl calculatorImpl)
{
this(in);
this.out = new PrintWriter(out, true);
this.calculatorImpl = calculatorImpl;
}
public CalculatorParser(Reader in, PrintWriter out, CalculatorImpl calculatorImpl)
{
this(in);
this.out = out;
this.calculatorImpl = calculatorImpl;
}
private PrintWriter out;
private CalculatorImpl calculatorImpl;
}
PARSER_END(CalculatorParser)
SKIP:
{
" "
| "\t"
}
TOKEN:
{
< INTEGER: ((this + that
*/
@Override
public abstract T plus(T that);
/**
* Returns the additive inverse of this object.
*
* @return -this
*/
@Override
public abstract T opposite();
/**
* Returns the product of this object with the one specified.
*
* @param that The multiplicand.
*
* @return this * that
*/
@Override
public abstract T times(T that);
/**
* Returns the multiplicative inverse of this object.
*
* @return 1 / this
*
* @exception ArithmeticException If the divisor is zero.
*/
@Override
public abstract T inverse()
throws ArithmeticException;
/**
* Returns a copy of this object.
*
* @return A copy of this object.
*/
@Override
public abstract T copy();
/**
* Compares the absolute value of this number
* with the absolute value of the number specified.
*
* @param that The number to be compared with.
*
* @return |this| > |that|
*/
@Override
public boolean isLargerThan(T that)
{
return ApcomplexMath.norm(value()).compareTo(ApcomplexMath.norm(that.value())) > 0;
}
/**
* Returns the value of this number as the underlying type.
*
* @return The value.
*/
public V value()
{
return this.value;
}
/**
* Returns the value of this number as a double.
*
* @return The value.
*/
@Override
public double doubleValue()
{
return value().doubleValue();
}
/**
* Returns the value of this number as a long.
*
* @return The value.
*/
@Override
public long longValue()
{
return value().longValue();
}
/**
* Returns the text representation of this number.
*
* @return The string representation of this number as a Text.
*/
@Override
public Text toText()
{
return Text.valueOf(value().toString());
}
/**
* Compares this number to another number.
*
* @param that The number to be compared with.
*
* @return -1, 0, or 1 depending on the ordering.
*/
@Override
public int compareTo(T that)
{
int result = value().real().compareTo(that.value().real());
if (result == 0)
{
result = value().imag().compareTo(that.value().imag());
}
return result;
}
/**
* Returns the hash code for this number.
*
* @return The hash code value.
*/
@Override
public int hashCode()
{
return value().hashCode();
}
/**
* Compares for equality.
*
* @return If the objects are equal.
*/
@Override
public boolean equals(Object obj)
{
if (obj instanceof AbstractField)
{
AbstractField, ?> that = (AbstractField, ?>) obj;
return value().equals(that.value());
}
return false;
}
static Apfloat parse(String prefix, InputElement xml)
throws XMLStreamException
{
String mantissa = xml.getAttribute(prefix + "mantissa", "0");
long exponent = Long.parseLong(xml.getAttribute(prefix + "exponent", "0")),
precision = Long.parseLong(xml.getAttribute(prefix + "precision", String.valueOf(mantissa.length())));
int radix = Integer.parseInt(xml.getAttribute(prefix + "radix", String.valueOf(ApfloatContext.getContext().getDefaultRadix())));
return ApfloatMath.scale(new Apint(mantissa, radix).precision(precision), exponent);
}
static void format(Apfloat value, String prefix, OutputElement xml)
throws XMLStreamException
{
format(value, prefix, xml, value.precision());
}
static void format(Apfloat value, String prefix, OutputElement xml, Long precision)
throws XMLStreamException
{
Apint mantissa = ApfloatMath.scale(value, Math.subtractExact(value.size(), value.scale())).truncate();
long exponent = (value.signum() == 0 ? 0 : Math.subtractExact(value.scale(), value.size()));
xml.setAttribute(prefix + "mantissa", mantissa.toString());
xml.setAttribute(prefix + "exponent", exponent);
if (precision != null)
{
xml.setAttribute(prefix + "precision", precision.longValue());
}
xml.setAttribute(prefix + "radix", value.radix());
}
private static final long serialVersionUID = -7725271295007354895L;
private V value;
}
apfloat-1.15.0/apfloat-jscience/src/main/java/org/apfloat/jscience/ApcomplexField.java 0000664 0000000 0000000 00000007430 15113064030 0030623 0 ustar 00root root 0000000 0000000 /*
* MIT License
*
* Copyright (c) 2002-2025 Mikko Tommila
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.apfloat.jscience;
import javolution.xml.XMLFormat;
import javolution.xml.stream.XMLStreamException;
import org.apfloat.Apcomplex;
import org.apfloat.ApcomplexMath;
/**
* This class represents an arbitrary precision complex number.
* y2 = x3 + a x + bsetWeierstrassParameters(new Apint(486662), new Apint(1), ApintMath.pow(new Apint(2), 255).subtract(new Apint(19)))
*
* @param a The curve parameter a.
* @param b The curve parameter b.
* @param p The modulus.
*/
public static void setWeierstrassParameters(Apint a, Apint b, Apint p)
{
ModuloApintField.setModulus(p);
int radix = a.radix();
ModuloApintField α = new ModuloApintField(a),
β = new ModuloApintField(b),
four = new ModuloApintField(new Apint(4, radix)),
twentyseven = new ModuloApintField(new Apint(3, radix));
if (four.times(α).times(α).times(α).plus(twentyseven.times(β).times(β)).value().signum() == 0)
{
throw new IllegalArgumentException("Curve is not valid");
}
weierstrassA.set(α);
weierstrassB.set(β);
montgomeryA.set(null);
montgomeryB.set(null);
}
/**
* Set the curve parameters in Montgomery form.
* The elliptic curve specified in the Montgomery form is
* B y2 = x3 + A x2 + x
*
* For example, Curve25519 can be set withsetMontgomeryParameters(new Apint(1), new Apint(486662), ApintMath.pow(new Apint(2), 255).subtract(new Apint(19)))
*
* @param b The curve parameter B.
* @param a The curve parameter A.
* @param p The modulus.
*/
public static void setMontgomeryParameters(Apint b, Apint a, Apint p)
{
int radix = p.radix();
ModuloApintField.setModulus(p);
ModuloApintField A = new ModuloApintField(a),
B = new ModuloApintField(b),
two = new ModuloApintField(new Apint(2, radix)),
three = new ModuloApintField(new Apint(3, radix)),
nine = new ModuloApintField(new Apint(9, radix)),
twentyseven = new ModuloApintField(new Apint(27, radix));
setWeierstrassParameters(three.minus(A.times(A)).times(three.times(B).times(B).inverse()).value(),
two.times(A).times(A).minus(nine).times(A).times(twentyseven.times(B).times(B).times(B).inverse()).value(),
p);
montgomeryA.set(A);
montgomeryB.set(B);
}
/**
* Set the curve parameters in twisted Edwards form.
* The elliptic curve specified in the twisted Edwards form is
* a x2 + y2 = 1 + d x2 y2
*
* For example, Curve448 can be set withsetEdwardsParameters(new Apint(1), new Apint(-39081), ApintMath.pow(new Apint(2), 448).subtract(ApintMath.pow(new Apint(2), 224).subtract(new Apint(1))))
*
* @param a The curve parameter a.
* @param d The curve parameter d.
* @param p The modulus.
*/
public static void setEdwardsParameters(Apint a, Apint d, Apint p)
{
int radix = p.radix();
ModuloApintField.setModulus(p);
ModuloApintField x = new ModuloApintField(a.subtract(d)).inverse(),
ad = new ModuloApintField(a.add(d)),
two = new ModuloApintField(new Apint(2, radix)),
four = new ModuloApintField(new Apint(4, radix));
setMontgomeryParameters(four.times(x).value(),
two.times(ad).times(x).value(),
p);
}
/**
* Returns the curve parameter a in Weierstrass form.
*
* @return The curve parameter a.
*
* @see #setWeierstrassParameters(Apint, Apint, Apint)
*/
public static Apint getA()
{
return weierstrassA.get().value();
}
/**
* Returns the curve parameter b in Weierstrass form.
*
* @return The curve parameter b.
*
* @see #setWeierstrassParameters(Apint, Apint, Apint)
*/
public static Apint getB()
{
return weierstrassB.get().value();
}
/**
* Returns the j-invariant of the curve.
*
* @return The j-invariant of the curve.
*/
public static Apint getJInvariant()
{
ModuloApintField a = weierstrassA.get(),
b = weierstrassB.get();
int radix = a.value().radix();
ModuloApintField foura3 = new ModuloApintField(new Apint(4, radix)).times(a).times(a).times(a),
twentyseven = new ModuloApintField(new Apint(27, radix)),
twelve3 = new ModuloApintField(new Apint(1728, radix));
return twelve3.times(foura3).times(foura3.plus(twentyseven.times(b).times(b)).inverse()).value();
}
/**
* Returns the x-coordinate of this point.
*
* @return The x-coordinate.
*/
public Apint getX()
{
return this.x.value();
}
/**
* Returns the y-coordinate of this point.
*
* @return The y-coordinate.
*/
public Apint getY()
{
return this.y.value();
}
@Override
public EllipticCurveGroup plus(EllipticCurveGroup that)
{
if (this.equals(O))
{
return that;
}
if (that.equals(O))
{
return this;
}
ModuloApintField a = weierstrassA.get(),
b = weierstrassB.get(),
x,
y;
if (a == null || b == null)
{
throw new IllegalStateException("Curve parameters have not been set");
}
if (!this.x.equals(that.x))
{
// P != Q
ModuloApintField λ = that.y.minus(this.y).times(that.x.minus(this.x).inverse());
x = λ.times(λ).minus(this.x).minus(that.x);
y = λ.times(this.x.minus(x)).minus(this.y);
}
else if (this.y.equals(that.y))
{
// P == Q
int radix = this.y.value().radix();
ModuloApintField two = new ModuloApintField(new Apint(2, radix)),
three = new ModuloApintField(new Apint(3, radix)),
λ = three.times(this.x).times(this.x).plus(a).times(two.times(this.y).inverse());
x = λ.times(λ).minus(two.times(this.x));
y = λ.times(this.x.minus(x)).minus(this.y);
}
else
{
// P == -Q
assert (this.x.equals(that.x) && this.y.equals(that.y.opposite()));
// Result is O, the "point at infinity"
return O;
}
assert (y.times(y).equals(x.times(x).plus(a).times(x).plus(b)));
return new EllipticCurveGroup(x, y);
}
/**
* Returns this elliptic curve point multiplied by a scalar.
*
* @param that The multiplier.
*
* @return The resulting elliptic curve point.
*/
public EllipticCurveGroup times(Apint that)
{
if (this.equals(O))
{
return this;
}
if (that.signum() < 0)
{
return opposite().times(that.negate());
}
Apint two = new Apint(2, that.radix());
EllipticCurveGroup a = this,
result = O;
while (that.signum() != 0)
{
Apint[] qr = ApintMath.div(that, two);
if (qr[1].signum() != 0)
{
result = result.plus(a);
}
if (qr[0].signum() != 0)
{
a = a.plus(a);
}
that = qr[0];
}
return result;
}
@Override
public EllipticCurveGroup opposite()
{
if (this.equals(O))
{
return this;
}
return new EllipticCurveGroup(this.x, this.y.opposite());
}
@Override
public EllipticCurveGroup copy()
{
if (this.equals(O))
{
return new EllipticCurveGroup((ModuloApintField) null, (ModuloApintField) null);
}
return new EllipticCurveGroup(this.x.value(), this.y.value());
}
@Override
public Text toText()
{
if (this.equals(O))
{
return Text.valueOf("(∞, ∞)");
}
return Text.valueOf("(" + this.x + ", " + this.y + ')');
}
@Override
public String toString() {
return toText().toString();
}
@Override
public int hashCode()
{
return Objects.hashCode(this.x) + 3 * Objects.hashCode(this.y);
}
@Override
public boolean equals(Object obj)
{
if (obj instanceof EllipticCurveGroup)
{
EllipticCurveGroup that = (EllipticCurveGroup) obj;
return Objects.equals(this.x, that.x) && Objects.equals(this.y, that.y);
}
return false;
}
private static final long serialVersionUID = 4239380063596030297L;
private final ModuloApintField x,
y;
private static final LocalContext.ReferenceFixedPrecisionApcomplexHelper.
* This can help avoid accumulating round-off errors and loss of precision
* in complicated computations such as matrix inversion.
*
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class FixedPrecisionApcomplexField
extends AbstractFieldFixedPrecisionApfloatHelper.
* This can help avoid accumulating round-off errors and loss of precision
* in complicated computations such as matrix inversion.
*
* @since 1.8.0
* @version 1.15.0
* @author Mikko Tommila
*/
public class FixedPrecisionApfloatField
extends AbstractFieldnull if modulo reduction is not done.
* The modulus can be set in a thread-specific way using
* {@link javolution.context.LocalContext}.
*
* @return The local modulus or null if modulo reduction is not done.
*
* @see #setModulus
*/
public static Apint getModulus()
{
return MODULUS.get();
}
/**
* Sets the modulus.
* The modulus can be set in a thread-specific way using
* {@link javolution.context.LocalContext}.
*
* @param modulus The modulus or null if modulo reduction is not done.
*
* @throws IllegalArgumentException If modulus is not positive.
*/
public static void setModulus(Apint modulus)
{
if (modulus != null && modulus.signum() <= 0)
{
throw new IllegalArgumentException("Modulus has to be greater than zero");
}
MODULUS.set(modulus);
}
/**
* Reduce the value with the current modulus.
*
* @param value The value.
*
* @return The value mod the current modulus.
*/
public static Apint reduce(Apint value)
{
Apint modulus = MODULUS.get();
if (modulus != null)
{
value = value.mod(modulus);
if (value.signum() < 0) // The modulus is always positive, so reduce values to positive
{
value = value.add(modulus);
}
}
return value;
}
@Override
public ModuloApintField plus(ModuloApintField that)
{
return new ModuloApintField(value().add(that.value()));
}
@Override
public ModuloApintField opposite()
{
return new ModuloApintField(value().negate());
}
@Override
public ModuloApintField times(ModuloApintField that)
{
return new ModuloApintField(value().multiply(that.value()));
}
@Override
public ModuloApintField inverse()
throws ArithmeticException
{
Apint modulus = MODULUS.get();
if (modulus == null)
{
throw new ApfloatArithmeticException("Modulus is not set");
}
return new ModuloApintField(ApintMath.modPow(value(), new Apint(-1), modulus));
}
/**
* Modular power.
*
* @param exp The exponent
*
* @return thisexp
*
* @since 1.15.0
*/
public ModuloApintField pow(Apint exp)
{
Apint modulus = MODULUS.get();
if (modulus == null)
{
throw new ApfloatArithmeticException("Modulus is not set");
}
return new ModuloApintField(ApintMath.modPow(value(), exp, modulus));
}
@Override
public ModuloApintField copy()
{
return new ModuloApintField(value());
}
private static final long serialVersionUID = 5308452222350777004L;
private static final LocalContext.Referencenull if modulo reduction is not done.
* The modulus can be set in a thread-specific way using
* {@link javolution.context.LocalContext}.
*
* @param null if modulo reduction is not done.
*
* @see #setModulus
*/
public static null if modulo reduction is not done.
*/
public static this - that
*/
public ModuloPolynomialField