-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathvs_eigen_io.h
179 lines (169 loc) · 5.93 KB
/
vs_eigen_io.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/**
* Copyright (c) 2016-2023 shuyuanmao <[email protected]>. All rights reserved.
* @author shuyuanmao <[email protected]>
* @date 2022-05-04 14:54
* @details file I/O for Eigen dense/sparse matrix.
*/
#pragma once
#include <fstream>
#include <typeinfo>
#include <Eigen/Dense>
#include <Eigen/Sparse>
namespace vs {
/** @brief write Eigen dense matrix into ofstream in inner format.
* @param[in/out]f: ostream where matrix data will be written to.
* @param[in]m: Eigen dense matrix
* @return where writting ok.
*/
template <typename T, int _Rows, int _Cols>
bool writeEigenDense(std::ofstream& f, const Eigen::Matrix<T, _Rows, _Cols>& m) {
uint32_t rows = m.rows();
uint32_t cols = m.cols();
uint32_t id = 0;
const auto& t = typeid(T);
if (t == typeid(int)) {
id = 1;
} else if (t == typeid(float)) {
id = 2;
} else if (t == typeid(double)) {
id = 3;
}
if (id == 0) return false;
f.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
f.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
f.write(reinterpret_cast<const char*>(&id), sizeof(id));
for (uint32_t i = 0; i < rows; i++)
for (uint32_t j = 0; j < cols; j++) {
const auto& v = m(i, j);
f.write(reinterpret_cast<const char*>(&v), sizeof(v));
}
f.flush();
return true;
}
/** @brief write Eigen dense matrix into file in inner format.
* @param[in]binfile: file path where matrix data will be written to.
* @param[in]m: Eigen dense matrix
* @return where writting ok.
*/
template <typename T, int _Rows, int _Cols>
bool writeEigenDense(const char* binfile, const Eigen::Matrix<T, _Rows, _Cols>& m) {
std::ofstream fout(binfile, std::ios::binary);
if (!fout.is_open()) return false;
return writeEigenDense(fout, m);
}
/** @brief read Eigen dense matrix from ifstream.
* @param[in]f: ifstream of file which is written by writeEigenDense().
* @return Eigen dense matrix, return empty mat if read failed.
*/
template <typename T>
Eigen::Matrix<T, -1, -1> readEigenDense(std::ifstream& f) {
uint32_t rows, cols, id;
f.read(reinterpret_cast<char*>(&rows), sizeof(rows));
f.read(reinterpret_cast<char*>(&cols), sizeof(cols));
f.read(reinterpret_cast<char*>(&id), sizeof(id));
Eigen::Matrix<T, -1, -1> m(rows, cols);
if (id == 1) {
for (uint32_t i = 0; i < rows; i++)
for (uint32_t j = 0; j < cols; j++) {
int v;
f.read(reinterpret_cast<char*>(&v), sizeof(v));
m(i, j) = v;
}
} else if (id == 2) {
for (uint32_t i = 0; i < rows; i++)
for (uint32_t j = 0; j < cols; j++) {
float v;
f.read(reinterpret_cast<char*>(&v), sizeof(v));
m(i, j) = v;
}
} else if (id == 3) {
for (uint32_t i = 0; i < rows; i++)
for (uint32_t j = 0; j < cols; j++) {
double v;
f.read(reinterpret_cast<char*>(&v), sizeof(v));
m(i, j) = v;
}
} else {
return Eigen::Matrix<T, -1, -1>();
}
return m;
}
/** @brief read Eigen dense matrix from file.
* @param[in]binfile: file path which is written by writeEigenDense().
* @return Eigen dense matrix, return empty mat if read failed.
*/
template <typename T>
Eigen::Matrix<T, -1, -1> readEigenDense(const char* binfile) {
std::ifstream fin(binfile, std::ios::binary);
if (!fin.is_open()) return Eigen::Matrix<T, -1, -1>();
return readEigenDense<T>(fin);
}
/** @brief write Eigen sparse matrix into ofstream in inner format.
* @param[in/out]f: ostream where matrix data will be written to.
* @param[in]m: Eigen sparse matrix
* @return where writting ok.
*/
template <typename T>
bool writeEigenSparse(std::ofstream& f, const Eigen::SparseMatrix<T>& m) {
uint32_t rows = m.rows();
uint32_t cols = m.cols();
uint32_t cnt = m.nonZeros();
f.write(reinterpret_cast<const char*>(&rows), sizeof(rows));
f.write(reinterpret_cast<const char*>(&cols), sizeof(cols));
f.write(reinterpret_cast<const char*>(&cnt), sizeof(cnt));
for (int k = 0; k < m.outerSize(); ++k)
for (typename Eigen::SparseMatrix<T>::InnerIterator it(m, k); it; ++it) {
int r = it.row(); // row index
int c = it.col(); // col index (here it is equal to k)
T v = it.value();
f.write(reinterpret_cast<const char*>(&r), sizeof(r));
f.write(reinterpret_cast<const char*>(&c), sizeof(c));
f.write(reinterpret_cast<const char*>(&v), sizeof(v));
}
f.flush();
return true;
}
/** @brief write Eigen sparse matrix into file in inner format.
* @param[in]binfile: file path where matrix data will be written to.
* @param[in]m: Eigen sparse matrix
* @return where writting ok.
*/
template <typename T>
bool writeEigenSparse(const char* binfile, const Eigen::SparseMatrix<T>& m) {
std::ofstream fout(binfile, std::ios::binary);
if (!fout.is_open()) return false;
return writeEigenSparse(fout, m);
}
/** @brief read Eigen sparse matrix from ifstream.
* @param[in]f: ifstream of file which is written by writeEigenSparse().
* @return Eigen sparse matrix, return empty mat if read failed.
*/
template <typename T>
Eigen::SparseMatrix<T> readEigenSparse(std::ifstream& f) {
uint32_t rows, cols, cnt;
f.read(reinterpret_cast<char*>(&rows), sizeof(rows));
f.read(reinterpret_cast<char*>(&cols), sizeof(cols));
f.read(reinterpret_cast<char*>(&cnt), sizeof(cnt));
Eigen::SparseMatrix<T> m(rows, cols);
m.reserve(cnt);
for (uint32_t i = 0; i < cnt; i++) {
int r, c;
T v;
f.read(reinterpret_cast<char*>(&r), sizeof(r));
f.read(reinterpret_cast<char*>(&c), sizeof(c));
f.read(reinterpret_cast<char*>(&v), sizeof(v));
m.insert(r, c) = v;
}
return m;
}
/** @brief read Eigen sparse matrix from file.
* @param[in]binfile: file path which is written by writeEigenSparse().
* @return Eigen sparse matrix, return empty mat if read failed.
*/
template <typename T>
Eigen::SparseMatrix<T> readEigenSparse(const char* binfile) {
std::ifstream fin(binfile, std::ios::binary);
if (!fin.is_open()) return Eigen::SparseMatrix<T>();
return readEigenSparse<T>(fin);
}
} // namespace vs