c++ - 使用数组填充对称矩阵

标签 c++ arrays matrix boost symmetric

我正在尝试创建一个对称矩阵 n x n 矩阵,并使用 boost< 使用 n*(n+1)/2 维数组填充它 c++ 中的库。

到目前为止,我已经能够创建矩阵,并使用以下代码用随机值填充它

#include <iostream>
#include <fstream>    
#include </usr/include/boost/numeric/ublas/matrix.hpp>
#include </usr/include/boost/numeric/ublas/matrix_sparse.hpp>
#include </usr/include/boost/numeric/ublas/symmetric.hpp>
#include </usr/include/boost/numeric/ublas/io.hpp>

using namespace std;



int test_boost () {
    using namespace boost::numeric::ublas;
    symmetric_matrix<double, upper> m_sym (3, 3);

    double filler[6] = {0, 1, 2, 3, 4, 5};        

    for (unsigned i = 0; i < m_sym.size1 (); ++ i)
        for (unsigned j = i; j < m_sym.size2 (); ++ j)
            m_sym (i, j) = filler[i+j*m_sym.size1()];

    std::cout << m_sym << std::endl;
    return 0;
}

我想做的是使用数组 filler 中的值填充对称矩阵的上部(或下部)。所以输出的上对称矩阵应该是

         |      0    |      1    |      2    |
------------------------------------------------
   0 |          0           1           3    
   1 |          1           2           4
   2 |          3           4           5

知道怎么做吗?

最佳答案

我会通过保留一个从头到尾遍历 filler 的迭代器来稍微简化一下:

symmetric_matrix<double, upper> m_sym (3, 3);

double filler[6] = {0, 1, 2, 3, 4, 5};        

assert(m_sym.size1() == m_sym.size2());

double const* in = std::begin(filler);
for (size_t i = 0; i < m_sym.size1(); ++ i)
    for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
        m_sym (i, j) = *in++;

打印: Live On Coliru

我个人建议创建一个辅助函数,例如:

Live On Wandbox

#include <iostream>
#include <fstream>    
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/symmetric.hpp>
#include <boost/numeric/ublas/io.hpp>

namespace bnu = boost::numeric::ublas;

template <typename T = double>
bnu::symmetric_matrix<T, bnu::upper> make_symmetric(std::initializer_list<T> filler) {
    size_t n = (sqrt(8*filler.size() + 1) - 1)/2;
    assert((n*(n+1))/2 == filler.size());

    bnu::symmetric_matrix<T, bnu::upper> result(n, n);

    auto in = std::begin(filler);
    for (size_t i = 0; i < result.size1(); ++ i)
        for (size_t j = 0; j <= i && in != std::end(filler); ++ j)
            result (i, j) = *in++;

    return result;
}

int main() {
    std::cout << make_symmetric({0,1,2}) << "\n";
    std::cout << make_symmetric({0,1,2,3,4,5}) << "\n";
    std::cout << make_symmetric({0,1,2,3,4,5,6,7,8,9}) << "\n";
}

打印

[2,2]((0,1),(1,2))
[3,3]((0,1,3),(1,2,4),(3,4,5))
[4,4]((0,1,3,6),(1,2,4,7),(3,4,5,8),(6,7,8,9))

Note: the size checks use the series expansion for 1 + ... + n and the inverse of that: n = 1/2 (sqrt(8 x + 1) - 1)

关于c++ - 使用数组填充对称矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48911543/

相关文章:

P1881 中基于 C++ 模块的时期与潜在的#pragma-based 时期

c++ - 如何在 C++ 中向量化 for 循环?

node.js - 是否可以像在 Python 中使用 Pandas 一样对 NodeJS 中的函数进行向量化?

c++ - 如何处理非常大的矩阵(例如 1000000 x 1000000)

c++ - 错误 LNK2019 : unresolved external symbol error?

c++ - Eigen 矩阵分配需要很长时间——有解决办法吗?

java - java中不同的数字

javascript - 使用数组数组对键值对对象数组进行排序

c++ - 最小化数字 - c++

OpenGL移动对象并保持变换