gpt4 book ai didi

c++ - Eigen 稀疏 LU 求解器

转载 作者:行者123 更新时间:2023-11-28 04:11:41 25 4
gpt4 key购买 nike

我正在使用 C++ 中的 Eigen 库来求解稀疏线性方程:Ax=b 其中,A 是一个稀疏方阵,b 是一个矩形稀疏矩阵。我有多个 A 矩阵实例,每个实例都有多个右侧 b。因此,我想对所有 A 矩阵进行因式分解一次并存储它们,然后存储每个 A 和每个 b 的解。

我尝试使用 C++ vector 来存储所有求解器。这是我写的示例代码:

vector<Eigen::SparseMatrix<double>> A;
//fill in all A matrices

vector<Eigen::SparseLU<Eigen::SparseMatrix<double>>> solver_A;

Eigen::SparseLU<Eigen::SparseMatrix<double>> solver;

for (int i=0;i<A.size();i++){
solver.analyzePattern(A[i]);
solver.factorize(A[i]);
solver_A.push_back(solver);
}

//Later, solver_A entries are to be used to solve for various right hand sides

我正在使用 3.3.7 版本的 Eigen,并在 linux 中使用 gcc 编译器和 c++17 标准进行编译。由于 solver_A.push_back(solver) 行,我收到以下编译错误:

<pre>/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘<b>void __gnu_cxx::new_allocator&lt;_Tp&gt;::construct(_Up*, _Args&amp;&amp; ...) [with _Up = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Args = {const Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double, 0, int&gt;, Eigen::COLAMDOrdering&lt;int&gt; &gt;&amp;}; _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;]</b>’:
<b>/usr/include/c++/7/bits/alloc_traits.h:475:4:</b> required from ‘<b>static void std::allocator_traits&lt;std::allocator&lt;_CharT&gt; &gt;::construct(std::allocator_traits&lt;std::allocator&lt;_CharT&gt; &gt;::allocator_type&amp;, _Up*, _Args&amp;&amp; ...) [with _Up = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Args = {const Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double, 0, int&gt;, Eigen::COLAMDOrdering&lt;int&gt; &gt;&amp;}; _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; std::allocator_traits&lt;std::allocator&lt;_CharT&gt; &gt;::allocator_type = std::allocator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt;]</b>’
<b>/usr/include/c++/7/bits/stl_vector.h:943:30:</b> required from ‘<b>void std::vector&lt;_Tp, _Alloc&gt;::push_back(const value_type&amp;) [with _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Alloc = std::allocator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt;; std::vector&lt;_Tp, _Alloc&gt;::value_type = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;]</b>’
<b>header_files/coefficient_computations.cpp:476:51:</b> required from here
<b>/usr/include/c++/7/ext/new_allocator.h:136:4:</b> <font color="#EF2929"><b>error: </b></font>‘Eigen::SparseLU&lt;_MatrixType, _OrderingType&gt;::SparseLU(const Eigen::SparseLU&lt;_MatrixType, _OrderingType&gt;&amp;) [with _MatrixType = Eigen::SparseMatrix&lt;double&gt;; _O<b>rderingType = Eigen::COLAMDOrdering&lt;int&gt;]</b>’ is private within this context
{ <font color="#EF2929"><b>::new((void *)__p) _Up(std::forward&lt;_Args&gt;(__args)...)</b></font>; }
<font color="#EF2929"><b>^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</b></font>
In file included from <b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/SparseLU:44:0</b>,
from <b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/Sparse:31</b>,
from <b>../Eigen_3_3_7/unsupported/Eigen/SparseExtra:13</b>,
from <b>header_files/general_functions.hpp:17</b>,
from <b>header_files/coefficient_computations.hpp:17</b>,
from <b>header_files/coefficient_computations.cpp:2</b>:
<b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/src/SparseLU/SparseLU.h:393:5:</b> <font color="#34E2E2"><b>note: </b></font>declared private here
<font color="#34E2E2"><b>SparseLU</b></font> (const SparseLU&amp; );
<font color="#34E2E2"><b>^~~~~~~~</b></font>
In file included from <b>/usr/include/c++/7/vector:62:0</b>,
from <b>header_files/coefficient_computations.hpp:13</b>,
from <b>header_files/coefficient_computations.cpp:2</b>:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘<b>void std::_Construct(_T1*, _Args&amp;&amp; ...) [with _T1 = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Args = {Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double, 0, int&gt;, Eigen::COLAMDOrdering&lt;int&gt; &gt;}]</b>’:
<b>/usr/include/c++/7/bits/stl_uninitialized.h:83:18:</b> required from ‘<b>static _ForwardIterator std::__uninitialized_copy&lt;_TrivialValueTypes&gt;::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*&gt;; _ForwardIterator = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*; bool _TrivialValueTypes = false]</b>’
<b>/usr/include/c++/7/bits/stl_uninitialized.h:134:15:</b> required from ‘<b>_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*&gt;; _ForwardIterator = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*]</b>’
<b>/usr/include/c++/7/bits/stl_uninitialized.h:289:37:</b> required from ‘<b>_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator&lt;_Tp&gt;&amp;) [with _InputIterator = std::move_iterator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*&gt;; _ForwardIterator = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*; _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;]</b>’
<b>/usr/include/c++/7/bits/stl_uninitialized.h:311:2:</b> required from ‘<b>_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&amp;) [with _InputIterator = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*; _ForwardIterator = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*; _Allocator = std::allocator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt;]</b>’
<b>/usr/include/c++/7/bits/vector.tcc:426:6:</b> required from ‘<b>void std::vector&lt;_Tp, _Alloc&gt;::_M_realloc_insert(std::vector&lt;_Tp, _Alloc&gt;::iterator, _Args&amp;&amp; ...) [with _Args = {const Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double, 0, int&gt;, Eigen::COLAMDOrdering&lt;int&gt; &gt;&amp;}; _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Alloc = std::allocator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt;; std::vector&lt;_Tp, _Alloc&gt;::iterator = __gnu_cxx::__normal_iterator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*, std::vector&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt; &gt;; typename std::_Vector_base&lt;_Tp, _Alloc&gt;::pointer = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;*]</b>’
<b>/usr/include/c++/7/bits/stl_vector.h:948:21:</b> required from ‘<b>void std::vector&lt;_Tp, _Alloc&gt;::push_back(const value_type&amp;) [with _Tp = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;; _Alloc = std::allocator&lt;Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt; &gt;; std::vector&lt;_Tp, _Alloc&gt;::value_type = Eigen::SparseLU&lt;Eigen::SparseMatrix&lt;double&gt; &gt;]</b>’
<b>header_files/coefficient_computations.cpp:476:51:</b> required from here
<b>/usr/include/c++/7/bits/stl_construct.h:75:7:</b> <font color="#EF2929"><b>error: </b></font>‘Eigen::SparseLU&lt;_MatrixType, _OrderingType&gt;::SparseLU(const Eigen::SparseLU&lt;_MatrixType, _OrderingType&gt;&amp;) [with _MatrixType = Eigen::SparseMatrix&lt;double&gt;; _O<b>rderingType = Eigen::COLAMDOrdering&lt;int&gt;]</b>’ is private within this context
{ <font color="#EF2929"><b>::new(static_cast&lt;void*&gt;(__p)) _T1(std::forward&lt;_Args&gt;(__args)...)</b></font>; }
<font color="#EF2929"><b>^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~</b></font>
In file included from <b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/SparseLU:44:0</b>,
from <b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/Sparse:31</b>,
from <b>../Eigen_3_3_7/unsupported/Eigen/SparseExtra:13</b>,
from <b>header_files/general_functions.hpp:17</b>,
from <b>header_files/coefficient_computations.hpp:17</b>,
from <b>header_files/coefficient_computations.cpp:2</b>:
<b>../Eigen_3_3_7/unsupported/Eigen/../../Eigen/src/SparseLU/SparseLU.h:393:5:</b> <font color="#34E2E2"><b>note: </b></font>declared private here
<font color="#34E2E2"><b>SparseLU</b></font> (const SparseLU&amp; );
<font color="#34E2E2"><b>^~~~~~~~</b></font>
</pre>

如果注释了“solver_A.push_back(solver)”这一行,则编译成功。感谢您提供解决此问题或使用替代解决方案的任何帮助。

最佳答案

vector::push_back要求 vector 元素可以复制或移动构造。 SparseLU两者都不是,因为它有一个私有(private)复制构造函数(https://eigen.tuxfamily.org/dox/SparseLU_8h_source.html):

private:
// Disable copy constructor
SparseLU (const SparseLU& );

您可以通过多种方式解决这个问题。例如,通过构建具有适当大小的求解器 vector ,使其不需要动态增长 (https://godbolt.org/z/vS85P8):

vector<Eigen::SparseMatrix<double>> A;

vector<Eigen::SparseLU<Eigen::SparseMatrix<double>>> solver_A(A.size());

for (int i=0;i<A.size();i++) {
solver_A[i].analyzePattern(A[i]);
solver_A[i].factorize(A[i]);
}

如果那不可能,另一种选择是将您的求解器包装成可移动类型,例如 std::unique_ptr<Eigen::SparseMatrix<double>> .

作为旁注,您可以使用 compute而不是 analyzePattern然后 factorize .

关于c++ - Eigen 稀疏 LU 求解器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57648192/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com