LLL算法JAVA实现

package password;

import java.util.Arrays;

import Jama.Matrix;

public class LLLAlgorithm {
    public int n;
    public double s;
    public double[][] m;
    public double[][] mm;

    public LLLAlgorithm(int n) {
        this.n = n;
    }

    public double[][] getM() {
        return m;
    }

    public void setM(double[][] m) {
        this.m = m;
    }

    // 矩阵跟一个数相乘
    public double[] multi(double[] a, double b) {
        double[] c = new double[n];
        for (int i = 0; i < n; i++)
            c[i] = a[i] * b;
        return c;
    }

    // 求正交化系数
    public double[] coefficient(double[][] a, int k) {
        double[] coeff = new double[n];
        for (int j = 0; j < k; j++)
            coeff[j] = dotProduct(m[k], a[j]) / dotProduct(a[j], a[j]);
        return coeff;
    }

    // 约定条件
    public boolean lovaszCondition(double[][] c, int k) {
        double[] a = coefficient(c, k);
        for (int i = 0; i < k; i++) {
            if (Math.abs(a[i]) > 0.5d) {
                return false;
            }
        }
        if (dotProduct(c[k], c[k]) >= ((s - Math.pow(a[k - 1], 2)) * dotProduct(
                c[k - 1], c[k - 1]))) {
            return true;
        } else {
            return false;
        }
    }

    // 施密特正交化
    public void orthogonality() {
        for (int i = 0; i < n; i++) {
            mm[i] = Arrays.copyOf(m[i], n);
            double[] s = coefficient(mm, i);
            ;
            for (int j = 0; j < i; j++)
                mm[i] = subtract(mm[i], multi(mm[j], s[j]));
        }
    }

    // 计算size Reduction
    public double[] size(int k) {
        double[] b = new double[n];
        for (int j = 0; j < k; j++)
            b[j] = dotProduct(m[k], m[j]) / dotProduct(m[j], m[j]);
        return b;
    }

    // 向量做差
    public double[] subtract(double[] a, double[] b) {
        double[] c = new double[n];
        for (int i = 0; i < n; i++)
            c[i] = a[i] - b[i];
        return c;
    }

    // 交换位置
    public void swap(int a, int b, double[][] m) {
        double[] temp = new double[n];
        temp = Arrays.copyOf(m[a], n);
        m[a] = Arrays.copyOf(m[b], n);
        m[b] = Arrays.copyOf(temp, n);
    }

    // 两个向量相称
    public double dotProduct(double[] a, double[] b) {
        double x = 0;
        for (int i = 0; i < n; i++)
            x += a[i] * b[i];
        return x;
    }

    public void LLLAlgorithms() {
        int k = 1;
        double[] s;
        while (k < n) {
            orthogonality();
            s = coefficient(mm, k);
            // System.out.println(k+1);
            for (int j = 0; j < k; j++) {
                m[k] = subtract(m[k], multi(m[j], Math.floor(s[j] + 0.5d)));
            }
            orthogonality();
            if (lovaszCondition(mm, k) == true) {
                k++;
            } else {
                swap(k, k - 1, m);
                swap(k, k - 1, mm);
                k = Math.max(k - 1, 1);
            }
        }
    }

    public double[][] getMm() {
        return mm;
    }

    public void setMm(double[][] mm) {
        this.mm = mm;
    }

    public void tostring(double[][] m) {
        for (int i = 0; i < n; i++) {
            System.out.println(Arrays.toString(m[i]));
        }
    }

    public double hadamardRatio() {// 哈达玛比例
        double x = 1;
        for (int i = 0; i < n; i++)
            x *= Math.pow(dotProduct(m[i], m[i]), 0.5d);
        return Math.pow(determinant() / x, (1d / (double) n));
    }

    public double determinant() {// 行列式的绝对值
        Matrix a = new Matrix(m);
        if (a.det() > 0)
            return a.det();
        else
            return -a.det();
    }

    // 求两个向量的距离
    public double range(double[] rig, double[] ans) {
        double a = 0;
        for (int i = 0; i < rig.length; i++) {
            a = a + Math.pow(rig[i] - ans[i], 2);
        }
        return a;
    }

}

你可能感兴趣的:(JAVA)