我確實有一個實現最小化算法的函數。我並沒有包括所有的瓦爾,只是矩陣來說明類型:當分配稀疏矩陣導致稀疏矩陣時出現「no operator found」
typedef Eigen::SparseMatrix<double> SpMat;
typedef Eigen::VectorXd Vec;
int lm_solver(void (*f_dz)(Vec* x_, int m, Vec* dz_, SpMat* W_),
void (*f_H)(Vec* x_, SpMat* jac_,int n_, int m_),
Vec* x, int nx, int mm, int nnz,
double tol=1e-9, int max_iter = 100){
SpMat A(mm, nx);
SpMat H1(mm, nx);
SpMat H2(mm, nx);
SpMat H(mm, nx);
SpMat W(mm, mm);
Vec rhs(nx);
Vec dz(nx);
Vec dx(nx);
Vec a(1);
Vec b(1);
double f, f_prev, lbmda, rho, nu, tau;
bool updateH, converged;
int iter_;
// reserve matrices memory
H.reserve(nnz);
W.reserve(mm);
while (!converged && iter_ < max_iter){
// get the system matrices
if (updateH){ // if the Jacobian computation is not locked...
f_dz(x, mm, &dz, &W); // Residual increment (z-h(x)) vector creation or update: fill dz and W
f_H(x, &H, nx, mm); // Jacobian matrix creation or update: fill H
// Start forming the auxiliary matrices of A
H1 = H.transpose() * W;
H2 = H1 * H;
}
// set the first value of lmbda
if (iter_ == 1)
lbmda = tau * H2.diagonal().maxCoeff();
// form the system matrix A = H^t·W·H + lambda·I
A = H2 + lbmda * Idn;
// form the right hand side: H^t·W·dz
rhs = H1 * dz;
// Solve the increment: dx = solve(A, rhs);
solver.compute(A);
dx = solver.solve(rhs);
// calculate the objective function: Least squares function
a = 0.5 * dz * W * dz; //vector x matrix x vector -> vector of 1 element
f = a.coeffRef(0);
// calculate the gain ratio
b = 0.5 * dx * (lbmda * dx - rhs); //vector x matrix x vector -> vector of 1 element
rho = (f_prev - f)/b.coeffRef(0);
}
return 0;
}
的過程執行以下操作:
- 聲明稀疏矩陣的矩陣(3210)
- 儲備矩陣存儲
- 調用外部函數來填充
H
,dz
和W
- 做矩陣乘法和將結果存儲到中間矩陣中
也是稀疏的。
此功能在.h
文件的唯一功能。當我獨自一人編譯靜態庫被編譯成靜態庫.lib
,它完美地編譯。
然而,當我使用的庫項目從另一個項目中,我得到以下錯誤:
error: C2679: binary '=' : no operator found which takes a right-hand operand of type 'const Eigen::CwiseBinaryOp' (or there is no acceptable conversion)
\eigen\src/Core/Matrix.h(206): could be 'Eigen::Matrix<_Scalar,_Rows,_Cols> &Eigen::Matrix<_Scalar,_Rows,_Cols>::operator =(const Eigen::Matrix<_Scalar,_Rows,_Cols> &)'
with
[
_Scalar=double,
_Rows=-1,
_Cols=1
]
d:\proyectos\proyectos_i+d\ingrid\eigen\eigen_3_3_3\eigen\src/Core/Matrix.h(281): or 'Eigen::Matrix<_Scalar,_Rows,_Cols> &Eigen::Matrix<_Scalar,_Rows,_Cols>::operator =(Eigen::Matrix<_Scalar,_Rows,_Cols> &&)'
with
[
_Scalar=double,
_Rows=-1,
_Cols=1
]
while trying to match the argument list '(Vec, const Eigen::CwiseBinaryOp)'
此錯誤標誌線:
H1 = H.transpose() * W;
H2 = H1 * H;
rhs = H1 * dz;
b = 0.5 * dx * (lbmda * dx - rhs);
a = 0.5 * dz * W * dz;
我從這個理解,我不能存儲在一個新的稀疏矩陣中稀疏矩陣乘法的結果。我不知道這個解決方案。
(我使用3.3.3本徵)
你是對的,但編譯器在此之前拋出了另一個錯誤。 –
@SantiPeñate-Vera請提供一個MCVE。即,提供應該編譯的內容(除了你看到的錯誤外),但刪除所有不必要的東西。在你的代碼片段中沒有'Idn',也沒有聲明'solver'。 – chtz
我試圖在「清潔」項目上重現問題 –