Разреженная матрица в Matlab: установите для незаписанных элементов значение -1 вместо 0

Я хочу создать разреженную матрицу, состоящую в основном из -1, но также включающую некоторые 0 и 1. Это часть более крупного проекта, поэтому важно, чтобы я не переключал -1 на 0. По умолчанию разреженная (A) в Matlab отслеживает только ненулевые элементы. Есть ли способ отслеживать только не (минус один) элементы? Например, если

A = 
-1 -1 -1  0 
 1 -1 -1 -1

затем

new_sparse(A) =
(1,4) = 0
(2,1) = 1

Спасибо!


person Matthew Thirkettle    schedule 07.09.2015    source источник
comment
Разве вы не можете определить A = sparse([1 2], [4 1], [1 2]) и изменить свой код, чтобы вместо A использовать A-1? (но не явно, иначе вы можете потерять разреженность)   -  person Luis Mendo    schedule 07.09.2015
comment
Луис: Да, это работает, спасибо. Я надеялся, что у Matlab есть более чистое решение, так что мне не придется изменять (уже написанный) код ниже по течению.   -  person Matthew Thirkettle    schedule 08.09.2015


Ответы (1)


Нет, невозможно переопределить sparse для использования других значений. Что вы можете сделать, хотя и требует много времени и памяти, так это использовать accumarray:

x_ind; % I presume this to contain the column index of the number
y_ind; % I presume this to contain the row  index of the number
value; % I presume this to contain the value (0 or 1)
new_mat = accumarray([x_ind y_ind],value,[],[],-1);

new_mat теперь будет содержать заданные вами значения 0 и 1, а во всех остальных местах будет иметь -1. Вам не нужно устанавливать аргумент size (третий), так как он просто создаст матрицу размера max(x_ind) x max(y_ind), если вы поставите []. Четвертый входной аргумент, функция, также может быть пустым, поскольку каждая комбинация x_ind и y_ind будет содержать только одно значение, поэтому по умолчанию достаточно mean.

Пример:

A = [0 1 ; -1 0];
x_ind = [1;2;2];
y_ind = [1;1;2];
value = [0;1;0];
new_mat = accumarray([x_ind y_ind],value,[],[],-1);

new_mat = 
          0    1
          -1   0

Другой метод, который я бы предпочел, состоит в том, чтобы просто добавить единицу ко всем значениям, таким образом сделав 1 2 и установив 0 в 1. Таким образом -1 сопоставляется с 0, и поэтому вы в любом случае можете использовать sparse. В примере это установит A = [1 2;0 1], который вы можете вызвать с вашими соответствующими значениями, используя A-1.

Просто примечание: sparse хранит три значения для каждого элемента (строка, столбец, значение) плюс некоторые накладные расходы. Таким образом, если ваша матрица пуста менее чем на 70 %, sparse на самом деле потребляет больше памяти, чем обычная полная матрица.

person Adriaan    schedule 07.09.2015
comment
Привет, спасибо за ваш ответ. Не могли бы вы привести пример? Я получаю сообщение об ошибке, но это, вероятно, потому, что я неверно истолковал ваш ответ. Если А = [0 1 ; -1 0], то верно ли, что: x_ind = [1 ; 2; 2] (0 отображается в столбце 1, 1 отображается в столбце 2, 0 отображается в столбце 2); у_инд = [1; 1; 2] (0 отображается в строке 1, 1 отображается в строке 1, 0 отображается в строке 2); значение = [0; 1; 0] (значения 0, 1, 0); new_mat = accumarray(x_ind,y_ind,значение,[],[],-1)? Делая это, я получаю следующую ошибку: Третий вход SZ должен быть полным вектором-строкой с одним элементом для каждого столбца SUBS. - person Matthew Thirkettle; 08.09.2015
comment
Странно, что вы получаете эту ошибку. Установка третьего аргумента на [] должна заставить его использовать значение по умолчанию; см. мой обновленный ответ. - person Adriaan; 08.09.2015
comment
Я все еще получаю сообщение об ошибке после прямого копирования вашего кода в R2015b: Ошибка при использовании accumarray Когда SUBS является вектором-столбцом, третья входная SZ должна иметь форму [N 1]. Это странно, потому что SZ или значение равно 3x1. - person Matthew Thirkettle; 08.09.2015
comment
Ах да, извините. Я снова помню, я всегда делаю это неправильно, извиняюсь. Я обновил ответ. [x_ind y_ind] должен быть 1 аргументом, а не двумя, как я выразился. - person Adriaan; 08.09.2015
comment
Не знал о пустом состоянии на 70%, спасибо! - person Matthew Thirkettle; 08.09.2015
comment
Вы, конечно, можете сделать матрицу с нулевым разбросом всего 10%, но это только увеличит память. Таким образом, это не строгое условие в том смысле, что оно не будет работать иначе, а скорее эмпирическое правило. whos A дает вам его размер в байтах (в вашей оперативной памяти), проверьте его самостоятельно на наличие разреженных и неразреженных матриц, содержащих одинаковые значения. - person Adriaan; 08.09.2015