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

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

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

import org.apfloat.ApfloatContext;
import org.apfloat.spi.ConvolutionBuilder;
import org.apfloat.spi.ConvolutionStrategy;
import org.apfloat.spi.NTTBuilder;
import org.apfloat.spi.NTTStrategy;
import org.apfloat.spi.Util;

/**
 * Abstract base class for creating convolutions of suitable type for the specified length.

* * Based on a work estimate, depending on the operand sizes and implementation-dependent * factors, the O(n2) long multiplication, Karatsuba multiplication and * the NTT algorithms are chosen e.g. as follows:

* *

* * * * * * * * * * * * * * * *
size1size2Algorithm
1616Long
16256Long
3232Long
32256Long
6464Karatsuba
64256NTT
6465536Karatsuba
128128NTT
12865536NTT
1284294967296Karatsuba
256256NTT
2564294967296Karatsuba
512512NTT
5124294967296NTT
* * @since 1.7.0 * @version 1.7.0 * @author Mikko Tommila */ public abstract class AbstractConvolutionBuilder implements ConvolutionBuilder { /** * Subclass constructor. */ protected AbstractConvolutionBuilder() { } public ConvolutionStrategy createConvolution(int radix, long size1, long size2, long resultSize) { long minSize = Math.min(size1, size2), maxSize = Math.max(size1, size2), totalSize = size1 + size2; if (minSize == 1) { return createShortConvolutionStrategy(radix); } else if (minSize <= getKaratsubaCutoffPoint()) { return createMediumConvolutionStrategy(radix); } else { float mediumCost = (float) minSize * maxSize, karatsubaCost = getKaratsubaCostFactor() * (float) Math.pow((double) minSize, LOG2_3) * maxSize / minSize, nttCost = getNTTCostFactor() * totalSize * Util.log2down(totalSize); if (mediumCost <= Math.min(karatsubaCost, nttCost)) { return createMediumConvolutionStrategy(radix); } else if (karatsubaCost <= nttCost) { return createKaratsubaConvolutionStrategy(radix); } else { ApfloatContext ctx = ApfloatContext.getContext(); NTTBuilder nttBuilder = ctx.getBuilderFactory().getNTTBuilder(); NTTStrategy nttStrategy = nttBuilder.createNTT(totalSize); return createThreeNTTConvolutionStrategy(radix, nttStrategy); } } } /** * Get the Karatsuba convolution cutoff point. * When either operand is shorter than this then the * medium-length convolution strategy should be used instead. * * @return The Karatsuba convolution cutoff point. * * @since 1.7.0 */ protected abstract int getKaratsubaCutoffPoint(); /** * Get the Karatsuba convolution cost factor. * It is used in determining the most efficient * convolution strategy for the given data lengths. * * @return The Karatsuba convolution cost factor. * * @since 1.7.0 */ protected abstract float getKaratsubaCostFactor(); /** * Get the NTT convolution cost factor. * It is used in determining the most efficient * convolution strategy for the given data lengths. * * @return The NTT convolution cost factor. * * @since 1.7.0 */ protected abstract float getNTTCostFactor(); /** * Create a short-length convolution strategy where the size of either * data set is one. * * @param radix The radix that will be used. * * @return A new short-length convolution strategy. * * @since 1.7.0 */ protected abstract ConvolutionStrategy createShortConvolutionStrategy(int radix); /** * Create a medium-length convolution strategy where the size of one * of the data sets is relatively small (but more than one). * * @param radix The radix that will be used. * * @return A new medium-length convolution strategy. * * @since 1.7.0 */ protected abstract ConvolutionStrategy createMediumConvolutionStrategy(int radix); /** * Create a Karatsuba convolution strategy. * * @param radix The radix that will be used. * * @return A new Karatsuba convolution strategy. * * @since 1.7.0 */ protected abstract ConvolutionStrategy createKaratsubaConvolutionStrategy(int radix); /** * Create a 3-NTT convolution strategy. * * @param radix The radix that will be used. * @param nttStrategy The underlying NTT strategy. * * @return A new 3-NTT convolution strategy. * * @since 1.7.0 */ protected abstract ConvolutionStrategy createThreeNTTConvolutionStrategy(int radix, NTTStrategy nttStrategy); private static final double LOG2_3 = Math.log(3.0) / Math.log(2.0); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy