2014-11-06 2 views
0

У меня есть одна проблема, пытаясь вычислить 1-норму разреженной матрицы. Я использую функцию scipy.sparse.linalg.onenormest, но это дает мне ошибку, потому что оператор может действовать только на квадратную матрицу.Python: L1-норма разреженной неквадратической матрицы

Вот Пример кода:

from scipy import sparse 

row = array([0,2,2,0,1,2]) 
col = array([0,0,1,2,2,2]) 
data = array([1,2,3,4,5,6]) 

A = sparse.csc_matrix((data,(row,col)), shape=(5,3)) 

onenormest(A) 

это ошибка:

Traceback (most recent call last): 
    File "<ipython console>", line 1, in <module> 
    File "C:\Python27\lib\site-packages\scipy\sparse\linalg\_onenormest.py", line 76, in onenormest 
    raise ValueError('expected the operator to act like a square matrix') 
ValueError: expected the operator to act like a square matrix 

Оператор onenormest работает, если я определяю как квадратная матрица, но это не то, что я хочу.

Кто-нибудь знает, как вычислить 1-норму разреженной неквадратной матрицы?

+0

Вы действительно хотите ['L^1-norm'] (http://mathworld.wolfram.com/L1-Norm.html)? Я не знаю, что такое «1-норма». – will

+0

Точно так, поэтому в этом примере норма L1 должна быть 15 –

+0

Разве это не должно быть 21? – will

ответ

1

Я думаю, что вы хотите numpy.linalg.norm;

from numpy import linalg 
from scipy import sparse 


row = array([0,2,2,0,1,2]) 
col = array([0,0,1,2,2,2]) 
data = array([1,2,3,4,5,6]) 

A = sparse.csc_matrix((data,(row,col)), shape=(5,3)) 

print linalg.norm(A.todense(), ord=1) #15 

Это не работает для вызова A.data, так как .data разреженного объекта матрицы только данные - это выглядит как вектор вместо этого.

Если ваша разреженная матрица мала, то это нормально. Если он большой, то, очевидно, это проблема. В этом случае вы можете написать свою собственную рутину.

Если вы заинтересованы только в L^1-norm и отливку плотной не представляется возможным, то вы можете сделать это через что-то вроде этого:

def sparseL1Norm = lambda A: max([numpy.abs(A).getcol(i).sum() for i in range(A.shape[1])]) 
+0

Спасибо за ответ. Я пробовал, но норма оператора не работает с разреженными матрицами. –

+0

Хорошо, это работает! –

+0

FYI, у меня есть сильное подозрение, что @nutbu 'np.abs (A) .sum (axis = 0) .max()' будет работать лучше, особенно для больших матриц. – will

1

Это находит L1-норма каждого столбца:

from scipy import sparse 
import numpy as np 

row = np.array([0,2,2,0,1,2]) 
col = np.array([0,0,1,2,2,2]) 
data = np.array([1,2,3,-4,-5,-6]) # made negative to exercise abs 
A = sparse.csc_matrix((data,(row,col)), shape=(5,3)) 
print(abs(A).sum(axis=0)) 

дает

[[ 3 3 15]] 

Вы могли бы взять макс найти L1-норму матрицы:

print(abs(A).sum(axis=0).max()) 
# 15 

abs(A) является разреженной матрицей:

In [29]: abs(A) 
Out[29]: 
<5x3 sparse matrix of type '<type 'numpy.int64'>' 
    with 6 stored elements in Compressed Sparse Column format> 

и sum и max являются методами разреженной матрицы, так abs(A).sum(axis=0).max() вычисляет L1 -норм без уплотнения матрицы.

Примечание: Большинство функций NumPy (таких как np.abs) не предназначены для работы с разреженными матрицами. Хотя np.abs(A) возвращает правильный результат, он прибывает туда по косвенному маршруту. Более прямой маршрут - использовать abs(A), который вызывает A.__abs__(). Thanks to pv. для пункт это вне.

+0

Спасибо! Кажется, это работает. Но то, что я хотел бы иметь, - это то же поведение функции нормы Матлаба (X, p), которая дает в результате 15. 15 является нормой L1 третьего столбца A, которая является более высокой нормой L1 (первая колонка норма = 4, вторая норма столбца = 3, норма третьей колонки = 15) –

+0

Это не работает, так как 'A.data' для разреженной матрицы просто' [1 2 3 4 5 6] ' – will

+0

Да точно. Таким образом, результатом является то 21. Но если, например, я определить A = sparse.csc_matrix ((данные, (строка, столбец)), форма = (5,5)) , а затем рассчитать onenormest (А) результат равен 15, поэтому работает для квадратной разреженной матрицы, но не с неквадратной матрицей :( –

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