对称矩阵半矢量化

时间:2013-06-04 09:05:15

标签: java matrix

我正面临一个问题,即如何将给定对称矩阵的下三角因子(它是一个距离矩阵)存储到一个向量中。

一般来说,我想直接生成下三角形条目,只需在矩形网格上给出一组点的坐标(Y,Z):实际上它就是我被卡住的地方。

所以,我开始考虑从稍微不同的角度来解决问题:生成全距离矩阵(再次给出(Y,Z)对),然后对距离矩阵进行一半矢量化。

尽管如此,我并没有真正了解如何通过for循环实现目标。

此外我还知道可能有任何外部Java库实现vech函数: vech 返回通过消除方阵的所有超对角元素获得的向量X并将结果堆叠在另一列之上。这在矩阵演算中有用,其中底层矩阵是对称的,将值保持在主对角线之上是没有意义的。

基本上,给定矩阵A = {{a,c},{b,d}},通过应用vech(A),结果将是 vech(A) = {a,b,d}

修改

我的意思如下:

    a11 a12 a13 a14
        a22 a23 a24
 A=         a33 a34  (aij = aji)
                a44

A的上三角形的打包存储:

  AP = { a11, a12, a22, a13, a23, a33, a14, a24, a34, a44 }

3 个答案:

答案 0 :(得分:2)

public static double[] vech(double[][] a) {
    int na = Math.min(a.length, a[0].length); // Dimension of the matrix
    int nv = na * (na + 1) / 2; // 1 + 2 + 3 + .. + na
    double[] v = new double[nv];
    int k = 0; // index in v.
    for (int i = 0; i < na; ++i) {
        for (int j = 0; j <= i; ++j) {
            v[k] = a[i][j];
            ++k;
        }
    }
    return v;
}

案例2x2矩阵:

选择[0] [0],[1] [0],[1] [1](跳过[0] [1])

行主要顺序:(C,C#,Java) a [i] [j]是第i行第j列的元素。

代码展平左下角三角形。

列主要顺序:(MATLAB,SciLab) a [i] [j]是第i列第j行的元素。

代码会使右上三角变平。

其他顺序

另一个三角形将给出:

        for (int j = i; j < na; ++j) {

结合主对角线的镜像,再次接收原始三角形:

            a[j][i]

答案 1 :(得分:1)

所有这些包装还有另一个有趣的事情。您还可以定义映射算法,将对称矩阵中的(i, j)位置转换为展平数组中的等效偏移量(就像您描述的那样)。您可以使用Arithmetic progression的想法来定义此类映射。我在RandomSymmetricMatrixSource.java中处理la4j课时这样做了。因此,您可以使用这些公式(它不处理i == j时的情况):

int flatten(int i, int j) {
  int offset = -1;

  if (i < j) {
    offset = j - (i + 1) + (int)((((size - 1) + (size - i)) / 2.0) * i);
  } else {
    offset = i - (j + 1) + (int)((((size - 1) + (size - j)) / 2.0) * j);
  }

  return offset;
}

,其中size是对称矩阵的大小。

答案 2 :(得分:0)

我想不出一个可以让你这样做的库,虽然我确定某个地方有一个,但你可以使用for循环如下:

ArrayList<ArrayList<int>> matrix = new ArrayList<ArrayList<int>>();
// add other arraylists to your matrix here i.e.:

ArrayList<Integer> first = new ArrayList<Integer>();
first.add(1);
first.add(2);
first.add(3);

ArrayList<Integer> second = new ArrayList<Integer>();
second.add(4);
second.add(5);
second.add(6);

ArrayList<Integer> third = new ArrayList<Integer>();
third.add(7);
third.add(8);
third.add(9);

matrix.add(first);
matrix.add(second);
matrix.add(third);

ArrayList<int> finalArray = new ArrayList<int>();

for(int i=0; i<matrix.size(); i++)
{
    ArrayList<Integer> inner = matrix.get(i);
    for(int j=0; j<i+1; j++)
    {
        finalArray.add(inner.get(j));
    }
}   

这会:matrix=[[1, 2, 3], [4, 5, 6], [7, 8, 9]]finalArray=[1, 4, 5, 7, 8, 9]

当然,这是假设您的矩阵是使用arraylists构建的。