matlab 从特征值中的指数看子矩阵

vs3odd8k  于 2023-05-01  发布在  Matlab
关注(0)|答案(2)|浏览(172)

在本征函数中,是否可以在Matlab中执行以下操作的等效操作?

A=rand(10,10);
indices = [2,5,6,8,9];

B=A(indices,indices)

我想有一个子矩阵作为对原矩阵的看法与给定的,非连续的指数。最好的选择是拥有原始矩阵的共享内存视图,这可能吗?
我已经找到了一个方法,它可以工作,但不是很快,因为它涉及到非向量化的for循环:

MatrixXi slice(const MatrixXi &A, const std::set<int> &indices)
{
    int n = indices.size();
    Eigen::MatrixXi B;
    B.setZero(n,n);

    std::set<int>::const_iterator iInd1 = indices.begin();
    for (int i=0; i<n;++i)
    {
        std::set<int>::const_iterator iInd2=indices.begin();
        for (int j=0; j<n;++j)
        {
            B(i,j) = A.coeffRef(*iInd1,*iInd2);
            ++iInd2;
        }
        ++iInd1;
    }

    return B;
}

如何才能使这更快?

p8h8hvxi

p8h8hvxi1#

这个问题很老了,但显然人们仍然可以在Google上找到它。因此,作为参考,您正在寻找的功能现在是本征功能的一部分。

std::vector<int> ind{4,2,5,5,3};
MatrixXi A = MatrixXi::Random(4,6);
cout << "Initial matrix A:\n" << A << "\n\n";
cout << "A(all,ind):\n" << A(Eigen::placeholders::all,ind) << "\n\n";

示例来自Eigen网站上Slicing and Indexing中的数组索引部分。
回应Cris Luengo的评论:上面的切片返回一个IndexedView,这是原始数据的视图。考虑下面的示例代码

MatrixXd m({{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}});
auto m2 = m({1,3}, {0,2});
m2 = MatrixXd{{0,0},{0,0}};
std::cout << m << std::endl;

其返回
所以我猜它会产生一个共享内存视图。

0g0grzrc

0g0grzrc2#

将矩阵遍历设为col-major(在Eigen中是默认的)http://eigen.tuxfamily.org/dox-devel/group__TopicStorageOrders.html
禁用调试Assert,EIGEN_NO_DEBUG,请参阅http://eigen.tuxfamily.org/dox/TopicPreprocessorDirectives.html,正如Deepfreeze的评论所建议的那样。
实现向量化版本是非常重要的,因为元素通常是不连续的。如果您能够做到,请查看AVX 2收集说明(前提是您有支持AVX 2的CPU)
要实现矩阵视图(你称之为共享内存),你需要实现一个Eigen表达式,如果你精通C++并了解Eigen代码库,这并不难。如果你愿意,我可以帮你开始。

相关问题