2017-03-02 63 views
2

Matlab代碼C++ - MATLAB:更新稀疏矩陣列塊這裏

N = 4096; 
x  = linspace(-1,1,N);  
A = sparse(100000,100000); 
index = 1:32; 

A(index,index) = kernel(x(index),x(index)); 
    //kernel here outputs a 32 x 32 matrix 

我必須將MATLAB代碼轉換爲C++,但我被困在稀疏功能,我嘗試使用:

N=4096; 
Eigen::VectorXd x = Eigen::VectorXd::LinSpaced(N,-1,1); 
Eigen::SparseMatrix<double> A(Asize,Asize); 
A.block(1,1,index.size(), index.size()) = Kernel(); 

但SparseMatrix具有爲只讀函數,因此不能用於更新矩陣。

另外一點:

我已經通過本徵的文件消失了,查了不同形式的稀疏矩陣聲明:

typedef Eigen::Triplet<double> T; 
std::vector<T>tripleList; 
tripleList.reserve(nnz); 

for(...) 
{ 
    // ... 
    tripletList.push_back(T(i,j,v_ij)); //?? what are these values? 
    } 
A.setFromTriplets(tripleList.begin(), tripleList.end()); 

但我不明白什麼應該是NNZ的價值,應該這是我從Matlab代碼中獲得的價值,我應該通過for循環來推什麼值?它們是隨機的嗎?如果矩陣大小太大,我該如何選擇「推數值」。

此外,最後一個問題仍然存在,聲明後的稀疏矩陣如何得到塊更新更新?

+0

'nnz'表示「非零數」。我假設這是爲了Eigen中的內存分配。此外,'A(index,index)= kernel(x(index),x(index));'這可以用C++中的一個簡單的雙重嵌套循環來完成,你不需要一行代碼 –

+2

根據[documentaion ](https://eigen.tuxfamily.org/dox/group__TutorialSparse.html)出於性能原因,寫入子稀疏矩陣是有限的。只有你可以更新連續的列組。在編譯時應該知道子矩陣的大小 – rahnema1

+0

@AnderBiguri它如何在雙重嵌套循環中完成?你建議使用函數「插入」?但是如果同一行重複多次,我必須每次首先存儲來自Kernel()的結果,然後將其插入到稀疏矩陣中。 – user7440094

回答

3

通常,特徵稀疏矩陣塊是常量。該規則的例外是例如m.col(i)列主要矩陣或.row(i)主要一列。

至於你的第二點,nnz是非零的數量。通過指定矩陣需要在開始處保留多少個非零值,可以最小化構建稀疏矩陣時所需的重新分配/副本的數量。請參閱documentation。此外,請注意other overload是有用的,如果你知道每個列中需要多少個元素。 關於for循環,假設您有三個數組:columnIndicesrowIndicesvalues,全部長度爲nnz。您的for循環如下所示:

for(int i = 0; i < nnz; i++) 
{ 
    tripletList.push_back(T(columnIndices[i], rowIndices[i], values[i])); 
} 

或者,您可以計算for循環中每個三元組的值。

+0

這個方法在值爲零時有效嗎?因爲我瀏覽了文檔,它說:「用非零元素填充」。如果我想將一個已經存在的稀疏矩陣更新爲一些包含零的小矩陣? – user7440094