我在C++中有二进制矩阵,我用8位值向量重复.
例如,以下矩阵:
1 0 1 0 1 0 1
0 1 1 0 0 1 1
0 0 0 1 1 1 1
Run Code Online (Sandbox Code Playgroud)
表示为:
const uint8_t matrix[] = {
0b01010101,
0b00110011,
0b00001111,
};
Run Code Online (Sandbox Code Playgroud)
我这样做的原因是因为然后计算这样的矩阵和8位向量的乘积变得非常简单和有效(每行只有一个按位AND和奇偶校验计算),这比单独计算每个位.
我现在正在寻找一种有效的方法来转置这样的矩阵,但是我无法弄清楚如何在不必手动计算每个位的情况下进行转换.
只是为了澄清一下,对于上面的例子,我想从转置中得到以下结果:
const uint8_t transposed[] = {
0b00000000,
0b00000100,
0b00000010,
0b00000110,
0b00000001,
0b00000101,
0b00000011,
0b00000111,
};
Run Code Online (Sandbox Code Playgroud)
注意:我更喜欢一种算法,它可以用任意大小的矩阵来计算,但我也对只能处理某些大小的算法感兴趣.
对于乘法大二进制矩阵(10Kx20K),我通常要做的是将矩阵转换为浮点数并执行浮点矩阵乘法,因为整数矩阵乘法非常慢(请看这里).
但这一次,我需要执行超过数十万次这样的乘法运算,甚至平均事情上的毫秒级性能提升.
我想要一个int或float矩阵作为结果,因为产品可能有非0或1的元素.输入矩阵元素都是0或1,因此它们可以存储为单个位.
在行向量和列向量之间的内积中(为了产生输出矩阵的一个元素),乘法简化为按位AND.添加仍然是添加,但我们可以添加具有填充计数功能的位,而不是单独循环它们.
一些其他布尔/二进制矩阵函数或位而不是计数它们,产生位矩阵结果,但这不是我需要的.
下面是一个示例代码,显示将问题形成为std::bitset, AND并且count操作比矩阵乘法更快.
#include <iostream>
using std::cout; using std::endl;
#include <vector>
using std::vector;
#include <chrono>
#include <Eigen/Dense>
using Eigen::Map; using Eigen::Matrix; using Eigen::MatrixXf;
#include <random>
using std::random_device; using std::mt19937; using std::uniform_int_distribution;
#include <bitset>
using std::bitset;
using std::floor;
const int NROW = 1000;
const int NCOL = 20000;
const float DENSITY = 0.4;
const float DENOMINATOR = 10.0 - (10*DENSITY);
void fill_random(vector<float>& vec) { …Run Code Online (Sandbox Code Playgroud) 我想将8x8 二进制矩阵乘以由无符号字符表示的8位向量表示为无符号64位整数.但是,由于一些其他问题,矩阵必须按列排序,因此不容易匹配字节以便于乘法.
知道如何加快这样的计算吗?每项操作都是重要的,我需要进行数十亿次这样的计算.
乘法是在2元素场(F-2)上进行的.