2013-06-04 3 views
0

У меня возник вопрос о том, как сохранить нижний треугольный коэффициент заданной симметричной матрицы (это матрица расстояний) в вектор.симметричная матричная половина векторизации

Как правило, я хотел бы непосредственно генерировать нижние треугольные записи, только присваивая координаты (Y,Z) набора точек на прямоугольной сетке: и на самом деле это то место, где я ужасно застрял.

Итак, я начал думать о том, чтобы атаковать проблему с несколько иной точки зрения: генерирование матрицы полного расстояния (опять же дано пары), а затем половина векторизации матрицы расстояния.

Тем не менее, я действительно не знаю, как достичь цели с помощью for петель.

Кроме того, я также знаю, что может быть любое внешнее Java библиотека, которая реализует функции vech: Vech возвращает вектор, полученный путем устранения всех supradiagonal элементов квадратной матрицы X и укладки колонки результат один над другим. Это используется в матричном исчислении, где лежащая в основе матрица симметрична, и было бы бессмысленно сохранять значения выше главной диагонали.

По существу, учитывая матрицу A = {{a,c},{b,d}}, применяя vech(A), результат будет vech(A) = {a,b,d}.

EDIT

Я имею в виду что-то вроде следующего:

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

Packed хранения верхней треугольника A:

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

За последнее предложение; что ты уже испробовал? –

+0

@OliCharlesworth: Я пробовал несколько циклов, но не удался, я отредактирую свой вопрос, включая мой опрос. – fpe

+0

Я предлагаю обменивать свой вопрос: спросите, как это сделать, сначала используя стандартные for-loops, а затем укажите, что вы также хотели бы узнать о библиотеке, иначе этот вопрос будет не конструктивным. – Dukeling

ответ

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

Case 2х2 Матрица:

выборка [0] [0], [1] [0], [1] [1] (пропуск [0] [1])

Роу-крупный заказ: (C, C#, Java) a [i] [j] - это элемент в строке i, столбец j.

Код сглаживает нижний левый треугольник.

Колонка-крупный заказ: (MATLAB, SciLab) а [I] [J] является элементом в столбце I, строки J.

Код сглаживает верхний правый треугольник.

Другая последовательность

Другой треугольник будет представлен как:

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

В сочетании с зеркальным отображением на главной диагонали, одна получает оригинальную треугольник снова:

  a[j][i] 
+0

, и если я хотел бы использовать элементы 'v' в стиле' column-major'? – fpe

+0

Разница между строкой-строкой и столбцом-майором - '[i] [j]' ↔ '[j] [i]' или зеркалирование в главной диагонали. –

0

Я не могу придумать библиотеку, которая позволила бы вам это сделать, хотя я уверен есть один где-то, но вы могли бы использовать для петли следующим образом:

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.

1

Есть еще одна интересная вещь во всей этой упаковке. Вы также можете определить алгоритм сопоставления для преобразования (i, j) positon в симметричную матрицу в эквивалентное смещение в массиве flatten (как описано выше). Вы можете использовать идеи 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 является размером симметричной матрицы.

+0

Nice другой перспективы. –

Смежные вопросы