为什么这个矩阵乘法函数产生不正确的输出?

时间:2016-11-17 18:29:12

标签: java matrix-multiplication

我目前的实现如下,取自this question并修改为使用独占或替代添加,如此处的评论。假设(并且,对于此实现的目标,可接受),所有输入矩阵将是4x4。

/**
* Produces the product of two matrices, treating the first parameter as the "left" matrix.
*/
public static int[][] multiplyMatrices(int[][] a, int[][] b)
{
    int[][] resultMatrix = new int[4][4];
    for (int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            for(int k = 0; k < 4; k++)
            {
                resultMatrix[i][j] = resultMatrix[i][j] ^ multiplyPolynomials(a[i][k], b[k][j]);
            }
        }
    }
    return resultMatrix;
}

multiplyPolynomials功能如here所述。

/**
* Multiplies two polynomials (mod 2) represented as integers.
* The first is converted into a binary string, which is then used
* to select a number of appropriate bit shifts of the
* second, which are then added together.
*/
public static int multiplyPolynomials(int n, int m)
{
    int result = 0x00000000;
    String ns = toBitString(n);

    for (int i = 0; i < ns.length(); i++)
    {
        int bitIndex = (ns.length() - i) -1;
        if (ns.charAt(bitIndex) == '1')
        {
            int temp = m;
            temp = temp << i;
            result = result ^ temp;
        }
    }
    return result;
}

运行multiplyMatrices后,resultMatrix作为reduceMatrix的参数传递,定义如下,第二个参数为0x011b。 (toBitString只是Integer.toBinaryString的快捷方式。)

/*
* Reduces all elements of the matrix modulo a given polynomial.
* Treats the values as bit-string representations of polynomials mod 2.
* Works by XORing various left-shifts of the modulo value with the value being reduced.
* NOTE: This comment describes both reduceMatrix() and moduloReduce().
*/
public static int[][] reduceMatrix(int[][] m, int p)
{
    int[][] reducedM = new int[4][4];

    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            reducedM[i][j] = moduloReduce(m[i][j], p);
        }
    }

    return reducedM;
}

public static int moduloReduce(int f, int p)
{
    String fs = toBitString(f);
    String ps = toBitString(p);
    int temp = f;
    int q = 0;
    while (toBitString(temp).length() >= ps.length())
    {
        int j = toBitString(temp).length()-1;
        int k = ps.length()-1;
        q = p << (j-k);
        temp = temp ^ q;
    }
    return temp;
}

使用以下两个矩阵作为输入进行测试,给出的值显式为十六进制:

02 03 01 01
01 02 03 01
01 01 02 03
03 01 01 02
----------
10 26 03 15
23 41 33 04
51 32 14 43
12 12 12 12

使用这些输入,输出矩阵(十六进制,缩减mod 0x011b)为:

10 26 03 15
23 41 33 04
51 32 14 43
12 12 12 12

但是,手动完成减少会产生不同的结果:

06 af 55 7c
b7 e0 4b ca
a7 35 2e a1
66 3d 06 5c

很明显,编写的程序无法正常工作。但是,以下第二个输入矩阵(使用相同的第一个矩阵)将返回正确的结果:

30 ca 96 24
32 92 09 23
3f ca 43 63
7d 5a f8 96

上述输入的预期(和收到)结果如下:

74 b2 97 d8 
68 ea b9 51 
fb 39 0a 60 
a7 a9 00 1b 

显然,multiplyMatrices的输出并非所有情况下的预期结果。使用的矩阵乘法算法似乎适用于链接问题的海报,我之前已经验证multiplyPolynomials按预期工作。 multiplyMatrices输出不准确的最可能原因是什么?为什么有些输入会产生正确的输出呢?

0 个答案:

没有答案