- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将特征向量序列化为 QDataStream
:
#include "utils.h"
#include "Eigen/Eigen"
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
qRegisterMetaTypeStreamOperators<Eigen::Vector3d>("Eigen::Vector3d");
Eigen::Vector3d vec(9, 4, 5);
QByteArray data;
QDataStream ds(&data, QIODevice::ReadWrite);
ds << vec;
Eigen::Vector3d vv;
ds >> vv;
qDebug() << vv[1];
return a.exec();
}
实用程序.cpp
#pragma once
#include "utils.h"
Q_DECLARE_METATYPE(Eigen::Vector3d)
QDataStream &operator<<(QDataStream &out, const Eigen::Vector3d &v)
{
out << v[0] << v[1] << v[2];
return out;
}
QDataStream &operator>>(QDataStream &in, Eigen::Vector3d &v)
{
in >> v[0] >> v[1] >> v[2];
return in;
}
问题是 main 打印 0,所以我想我没有正确进行序列化。 |那么我在这里做错了什么?
最佳答案
一切正常,除了你永远不会读回任何东西,因为 QIODevice
只有一个读写位置。您需要将设备倒回到开始位置。我猜您尝试了很多不必要的代码是出于绝望。
与其用英语说调试输出的内容,不如用 Q_ASSERT
在代码中说:这样就无需解释了。
下面重现了您的问题,并演示了解决方案。它还将数据流支持扩展到所有常量大小的矩阵。
#include <QtCore>
#include <Eigen/Eigen>
template <typename T, int R, int C>
QDataStream &operator<<(QDataStream &out, const Eigen::Matrix<T, R, C> &m) {
Q_STATIC_ASSERT(R != Eigen::Dynamic && C != Eigen::Dynamic);
for (int i = 0; i < R; i ++)
for (int j = 0; j < C; j ++)
out << m(i, j);
return out;
}
template <typename T, int R, int C>
QDataStream &operator>>(QDataStream &in, Eigen::Matrix<T, R, C> &m) {
Q_STATIC_ASSERT(R != Eigen::Dynamic && C != Eigen::Dynamic);
for (int i = 0; i < R; i ++)
for (int j = 0; j < C; j ++)
in >> m(i, j);
return in;
}
int main() {
QByteArray data;
QDataStream ds(&data, QIODevice::ReadWrite);
Eigen::Vector3d const v1(9, 4, 5);
ds << v1;
Eigen::Vector3d v2;
ds >> v2;
Q_ASSERT(v2 != v1);
Q_ASSERT(ds.status() != QDataStream::Ok);
ds.device()->seek(0);
ds >> v2;
Q_ASSERT(v1 == v2);
}
一个完整的解决方案将处理整数、 float 和任意大小的复杂数据类型之间的互操作:
// https://github.com/KubaO/stackoverflown/tree/master/questions/eigen-stream-50905799
#include <QtCore>
#include <Eigen/Eigen>
#include <type_traits>
namespace detail {
enum EigenType : quint8 {
Double = 0x00,
CDouble = 0x01,
ScalarMask = 0x0F,
Vector = 0x40, // d x 1
RowVector = 0x80, // 1 x d
Matrix = 0xC0, // d x d
StructureMask = 0xC0
};
template <typename T> void dumpElement(QDataStream &out, T el)
{ out << (double)el; }
template <typename T> void dumpElement(QDataStream &out, const std::complex<T> &el)
{ out << (double)el.real() << (double)el.imag(); }
template <typename T> void readDouble(QDataStream &in, T &el)
{ double v; in >> v; el = v; }
template <typename T> void readDouble(QDataStream &in, std::complex<T> &el)
{ double v; in >> v; el.real(v); el.imag(0); }
template <typename T> void readComplex(QDataStream &in, T &el)
{ double re, im; in >> re >> im; el = re; }
template <typename T> void readComplex(QDataStream &in, std::complex<T> &el)
{ double re, im; in >> re >> im; el.real(re); el.imag(im); }
} // namespace detail
template <typename D>
QDataStream &operator<<(QDataStream &out, const Eigen::MatrixBase<D> &m) {
quint8 type = 0;
if (std::is_integral<typename D::Scalar>::value ||
std::is_floating_point<typename D::Scalar>::value)
type = detail::Double;
else if (std::is_same<std::complex<float>, typename D::Scalar>::value ||
std::is_same<std::complex<double>, typename D::Scalar>::value)
type = detail::CDouble;
else {
out.setStatus(QDataStream::WriteFailed);
return out;
}
if (m.cols() == 1)
out << (type |= detail::Vector) << (quint32)m.rows();
else if (m.rows() == 1)
out << (type |= detail::RowVector) << (quint32)m.cols();
else
out << (type |= detail::Matrix) << (quint32)m.rows() << (quint32)m.cols();
for (int i = 0; i < m.rows(); i ++)
for (int j = 0; j < m.cols(); j ++)
detail::dumpElement(out, m(i, j));
return out;
}
template <typename D>
QDataStream &operator>>(QDataStream &in, Eigen::MatrixBase<D> &m) {
using std::swap;
quint8 type;
quint32 rows, cols;
in >> type;
if (in.status() != QDataStream::Ok)
return in;
bool const complex = (type & detail::ScalarMask) == detail::CDouble;
quint8 t = type & detail::StructureMask;
if (t == detail::Vector) {
cols = 1;
in >> rows;
}
else if (t == detail::RowVector) {
rows = 1;
in >> cols;
}
else if (t == detail::Matrix) {
in >> rows >> cols;
}
else {
in.setStatus(QDataStream::ReadCorruptData);
return in;
}
if (in.status() != QDataStream::Ok)
return in;
if ((rows == 1 && m.ColsAtCompileTime == 1) || (cols == 1 && m.RowsAtCompileTime == 1))
swap(rows, cols); // row- and column-vectors are interchangeable
m.derived().resize(rows, cols);
if (m.rows() == rows && m.cols() == cols) {
if (!complex) {
for (uint i = 0; i < rows; i ++)
for (uint j = 0; j < cols; j ++)
detail::readDouble(in, m(i, j));
} else {
for (uint i = 0; i < rows; i ++)
for (uint j = 0; j < cols; j ++)
detail::readComplex(in, m(i, j));
}
} else {
double dummy;
for (uint i = 0; i < (rows*cols*(complex ? 2 : 1)); ++i)
in >> dummy;
}
return in;
}
template <typename T> QDebug operator<<(QDebug d, const std::complex<T> &c) {
return d << c.real() << ";" << c.imag();
}
template <typename T1, typename T2> struct Eigen::internal::cast_impl<std::complex<T1>, T2> {
EIGEN_DEVICE_FUNC static inline T2 run(const std::complex<T1> &x) { return x.real(); }
};
template <typename T1, typename T2 = T1, typename T3 = T1> void test() {
QByteArray data;
QDataStream ds(&data, QIODevice::ReadWrite);
using namespace Eigen;
Matrix<T1,3,1> const v1 = Matrix<T3,3,1>::Random().template cast<T1>();
Matrix<T1,1,3> const v2 = Matrix<T3,1,3>::Random().template cast<T1>();
Matrix<T1,4,4> const m1 = Matrix<T3,4,4>::Random().template cast<T1>();
Matrix<T1,Dynamic,Dynamic> const m2 = Matrix<T3,Dynamic,Dynamic>::Random(4, 4).template cast<T1>();
Matrix<T1,Dynamic,Dynamic> const m3 = Matrix<T3,Dynamic,Dynamic>::Random(2, 5).template cast<T1>();
ds << v1 << v1 << v2 << v2 << m1 << m1 << m2 << m2 << m3;
Matrix<T2,3,1> iv3 = Matrix<T2,3,1>::Random();
Matrix<T2,1,3> irv3;
Matrix<T2,4,4> im4;
Matrix<T2,Dynamic,Dynamic> imX;
ds >> iv3;
Q_ASSERT(iv3.template cast<T3>() != v1.template cast<T3>());
Q_ASSERT(ds.status() != QDataStream::Ok);
ds.device()->reset();
ds.resetStatus();
Q_ASSERT(ds.status() == QDataStream::Ok);
ds >> iv3 >> irv3;
Q_ASSERT(ds.status() == QDataStream::Ok);
Q_ASSERT(iv3.template cast<T3>() == v1.template cast<T3>());
Q_ASSERT((irv3.template cast<T3>() == Eigen::Matrix<T3,1,3>(v1.template cast<T3>())));
ds >> irv3 >> iv3;
Q_ASSERT(irv3.template cast<T3>() == v2.template cast<T3>());
Q_ASSERT((iv3.template cast<T3>() == Eigen::Matrix<T3,3,1>(v2.template cast<T3>())));
ds >> im4 >> imX;
Q_ASSERT(im4.template cast<T3>() == m1.template cast<T3>());
Q_ASSERT(imX.template cast<T3>() == m1.template cast<T3>());
ds >> im4 >> imX;
Q_ASSERT(im4.template cast<T3>() == m2.template cast<T3>());
Q_ASSERT(imX.template cast<T3>() == m2.template cast<T3>());
ds >> imX;
Q_ASSERT(imX.template cast<T3>() == m3.template cast<T3>());
}
int main() {
test<int>();
test<float>();
test<double>();
test<std::complex<float>>();
test<std::complex<double>>();
test<short, float>();
test<float, short, short>();
test<int, double>();
test<double, int, int>();
test<float, double>();
test<double, float, float>();
test<float, std::complex<float>>();
test<float, std::complex<double>>();
test<double, std::complex<float>, float>();
test<double, std::complex<double>>();
test<std::complex<float>, float, float>();
test<std::complex<double>, float, float>();
test<std::complex<float>, double, double>();
test<std::complex<double>, double, double>();
test<short, std::complex<float>>();
test<std::complex<float>, short, short>();
test<int, std::complex<double>>();
test<std::complex<double>, int, int>();
}
关于c++ - 将特征向量序列化为 QDataStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50905799/
我想用一个向量执行以下操作。 a = np.array(np.arange(0, 4, 1)) 我想得到一个乘法,结果是一个矩阵 | 0 1 2 3 4 -| - - - - - - - 0
正如标题所述,我正在尝试使用 gsub,其中我使用向量作为“模式”和“替换”。目前,我的代码如下所示: names(x1) names(x1) [1] "2110023264A.Ms.Amp
所以当我需要做一些线性代数时,我更容易将向量视为列向量。因此,我更喜欢 (n,1) 这样的形状。 形状 (n,) 和 (n,1) 之间是否存在显着的内存使用差异? 什么是首选方式? 以及如何将 (n,
我不明白为什么 seq() 可以根据元素中是否存在小数点输出不同的类,而 c() 总是创建一个 num向量,无论是否存在小数。 例如: seqDec <- seq(1, 2, 0.5) # num v
机器学习与传统编程的一个重要区别在于机器学习比传统编程涉及了更多的数学知识。不过,随着机器学习的飞速发展,各种框架应运而生,在数据分析等应用中使用机器学习时,使用现成的库和框架成为常态,似乎越来越不需
寻找有关如何将 RegEnable 用作向量的示例/建议。此外,我想控制输入和使能信号成为 Vector 中寄存器索引的函数。 首先,我如何声明 RegEnable() 的 Vector,其次如何迭代
假设我有一个包含变量名称的向量 v1,我想为每个变量分配一个值(存储在单独的向量中)。我如何在没有迭代的情况下做到这一点? v1 <- c("a","b","c") v2 <- c(1,2,3) 我想
R 提供了三种类型来存储同质对象列表:向量、矩阵 和数组。 据我所知: 向量是一维数组的特殊情况 矩阵是二维数组的特例 数组还可以具有任意维度级别(包括 1 和 2)。 在向量上使用一维数组和在矩阵上
我正在绕着numpy/scipy中的所有选项转圈。点积、乘法、matmul、tensordot、einsum 等 我想将一维向量与二维矩阵(这将是稀疏csr)相乘并对结果求和,这样我就有了一个一维向量
我是一个 IDL 用户,正在慢慢切换到 numpy/scipy,并且有一个操作我在 IDL 中非常经常做,但无法用 numpy 重现: IDL> a = [2., 4] IDL> b = [3., 5
在python计算机图形工具包中,有一个vec3类型用于表示三分量向量,但是我如何进行以下乘法: 三分量向量乘以其转置结果得到 3*3 矩阵,如下例所示: a = vec3(1,1,1) matrix
我正在构建一款小型太空射击游戏。当涉及到空间物理学时,我曾经遇到过数学问题。 用文字描述如下:有一个最大速度。因此,如果您全速行驶,您的飞船将在屏幕上一遍又一遍地移动,就像在旧的小行星游戏中一样。如果
我正在尝试在 python 中实现 Vector3 类。如果我用 c++ 或 c# 编写 Vector3 类,我会将 X、Y 和 Z 成员存储为 float ,但在 python 中,我读到鸭式是要走
我是 Spark 和 Scala 的新手,我正在尝试阅读有关 MLlib 的文档。 http://spark.apache.org/docs/1.4.0/mllib-data-types.html上的
我有一个包含四个逻辑向量的数据框, v1 , v2 , v3 , v4 是对还是错。我需要根据 boolean 向量的组合对数据帧的每一行进行分类(例如, "None" , "v1 only" , "
我正在创建一个可视化来说明主成分分析的工作原理,方法是绘制一些实际数据的特征值(为了说明的目的,我将子集化为二维)。 我想要来自 this fantastic PCA tutorial 的这两个图的组
我有以下排序向量: > v [1] -1 0 1 2 4 5 2 3 4 5 7 8 5 6 7 8 10 11 如何在不遍历整个向量的情况下删除 -1、0 和 11
有什么方法可以让 R 对向量和其他序列数据结构使用基于零的索引,例如在 C 和 python 中。 我们有一些代码在 C 中进行一些数值处理,我们正在考虑将其移植到 R 中以利用其先进的统计功能,但是
我有一个函数可以查询我的数据库中最近的 X 个条目,它返回一个 map 向量,如下所示: [{:itemID "item1" :category "stuff" :price 5} {:itemI
我有 ([[AA ww me bl qw 100] [AA ee rr aa aa 100] [AA qq rr aa aa 90]] [[CC ww me bl qw 100] [CC ee rr
我是一名优秀的程序员,十分优秀!