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

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; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy