org.apfloat.internal.FloatModMath Maven / Gradle / Ivy
/*
* Apfloat arbitrary precision arithmetic library
* Copyright (C) 2002-2017 Mikko Tommila
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.apfloat.internal;
/**
* Modulo arithmetic functions for float
data.
*
* @version 1.0
* @author Mikko Tommila
*/
public class FloatModMath
extends FloatElementaryModMath
{
/**
* Default constructor.
*/
public FloatModMath()
{
}
/**
* Create a table of powers of n:th root of unity.
*
* @param w The n:th root of unity modulo the current modulus.
* @param n The table length (= transform length).
*
* @return Table of table[i]=wi mod m
, i = 0, ..., n-1.
*/
public final float[] createWTable(float w, int n)
{
float[] wTable = new float[n];
float wTemp = 1;
for (int i = 0; i < n; i++)
{
wTable[i] = wTemp;
wTemp = modMultiply(wTemp, w);
}
return wTable;
}
/**
* Get forward n:th root of unity. This is w
.
*
* Assumes that the modulus is prime.
*
* @param primitiveRoot Primitive root of the modulus.
* @param n The transform length.
*
* @return Forward n:th root of unity.
*/
public float getForwardNthRoot(float primitiveRoot, long n)
{
return modPow(primitiveRoot, getModulus() - 1 - (getModulus() - 1) / (float) n);
}
/**
* Get inverse n:th root of unity. This is w-1
.
*
* Assumes that the modulus is prime.
*
* @param primitiveRoot Primitive root of the modulus.
* @param n The transform length.
*
* @return Inverse n:th root of unity.
*/
public float getInverseNthRoot(float primitiveRoot, long n)
{
return modPow(primitiveRoot, (getModulus() - 1) / (float) n);
}
/**
* Modular inverse, that is 1 / a
. Assumes that the modulus is prime.
*
* @param a The operand.
*
* @return a-1 mod m
.
*/
public final float modInverse(float a)
{
return modPow(a, getModulus() - 2);
}
/**
* Modular division. Assumes that the modulus is prime.
*
* @param a The dividend.
* @param b The divisor.
*
* @return a*b-1 mod m
.
*/
public final float modDivide(float a, float b)
{
return modMultiply(a, modInverse(b));
}
/**
* Modular negation.
*
* @param a The argument.
*
* @return -a mod m
.
*/
public final float negate(float a)
{
return (a == 0 ? 0 : getModulus() - a);
}
/**
* Modular power. Assumes that the modulus is prime.
*
* @param a The base.
* @param n The exponent.
*
* @return an mod m
.
*/
public final float modPow(float a, float n)
{
assert (a != 0 || n != 0);
if (n == 0)
{
return 1;
}
else if (n < 0)
{
return modPow(a, getModulus() - 1 + n);
}
long exponent = (long) n;
while ((exponent & 1) == 0)
{
a = modMultiply(a, a);
exponent >>= 1;
}
float r = a;
while ((exponent >>= 1) > 0)
{
a = modMultiply(a, a);
if ((exponent & 1) != 0)
{
r = modMultiply(r, a);
}
}
return r;
}
}