24 #ifndef LBCRYPTO_MATH_MATRIX_H 25 #define LBCRYPTO_MATH_MATRIX_H 34 #include "encoding/encodings.h" 35 #include "lattice/backend.h" 36 #include "math/backend.h" 37 #include "math/distrgen.h" 38 #include "math/nbtheory.h" 39 #include "utils/inttypes.h" 40 #include "utils/memory.h" 41 #include "utils/utilities.h" 42 using std::invalid_argument;
46 template <
class Element>
49 typedef vector<vector<Element>> data_t;
50 typedef vector<Element> data_row_t;
51 typedef std::function<Element(void)> alloc_func;
60 Matrix(alloc_func allocZero,
size_t rows,
size_t cols)
61 : data(), rows(rows), cols(cols), allocZero(allocZero) {
63 for (
auto row = data.begin(); row != data.end(); ++row) {
64 for (
size_t col = 0; col < cols; ++col) {
65 row->push_back(allocZero());
83 Matrix(alloc_func allocZero,
size_t rows,
size_t cols, alloc_func allocGen);
93 explicit Matrix(alloc_func allocZero = 0)
94 : data(), rows(0), cols(0), allocZero(allocZero) {}
104 if (this->rows != 0 || this->cols != 0) {
106 "You cannot SetSize on a non-empty matrix");
113 for (
auto row = data.begin(); row != data.end(); ++row) {
114 for (
size_t col = 0; col < cols; ++col) {
115 row->push_back(allocZero());
126 void SetAllocator(alloc_func allocZero) { this->allocZero = allocZero; }
134 : data(), rows(other.rows), cols(other.cols), allocZero(other.allocZero) {
135 deepCopyData(other.data);
155 #define ONES_FOR_TYPE(T) \ 157 Matrix<T>& Matrix<T>::Ones() { \ 158 for (size_t row = 0; row < rows; ++row) { \ 159 for (size_t col = 0; col < cols; ++col) { \ 160 data[row][col] = 1; \ 196 #define IDENTITY_FOR_TYPE(T) \ 198 Matrix<T>& Matrix<T>::Identity() { \ 199 for (size_t row = 0; row < rows; ++row) { \ 200 for (size_t col = 0; col < cols; ++col) { \ 202 data[row][col] = 1; \ 204 data[row][col] = 0; \ 219 #define GADGET_FOR_TYPE(T) \ 221 Matrix<T> Matrix<T>::GadgetVector(int64_t base) const { \ 222 Matrix<T> g(allocZero, rows, cols); \ 223 auto base_matrix = allocZero(); \ 224 size_t k = cols / rows; \ 225 base_matrix = base; \ 227 for (size_t i = 1; i < k; i++) { \ 228 g(0, i) = g(0, i - 1) * base_matrix; \ 230 for (size_t row = 1; row < rows; row++) { \ 231 for (size_t i = 0; i < k; i++) { \ 232 g(row, i + row * k) = g(0, i); \ 238 #define GADGET_FOR_TYPE_DCRT(T) \ 240 Matrix<T> Matrix<T>::GadgetVector(int64_t base) const { \ 241 Matrix<T> g(allocZero, rows, cols); \ 242 auto base_matrix = allocZero(); \ 243 base_matrix = base; \ 246 auto params = g(0, 0).GetParams()->GetParams(); \ 248 uint64_t digitCount = (long)ceil( \ 249 log2(params[0]->GetModulus().ConvertToDouble()) / log2(base)); \ 251 for (size_t k = 0; k < digitCount; k++) { \ 252 for (size_t i = 0; i < params.size(); i++) { \ 253 NativePoly temp(params[i]); \ 255 g(0, k + i * digitCount).SetElementAtIndex(i, std::move(temp)); \ 260 size_t kCols = cols / rows; \ 261 for (size_t row = 1; row < rows; row++) { \ 262 for (size_t i = 0; i < kCols; i++) { \ 263 g(row, i + row * kCols) = g(0, i); \ 284 #define EUCLIDEANNORM_FOR_TYPE(T) \ 286 double Matrix<T>::EuclideanNorm() const { \ 287 double retVal = 0.0; \ 288 double locVal = 0.0; \ 289 for (size_t row = 0; row < rows; ++row) { \ 290 for (size_t col = 0; col < cols; ++col) { \ 291 locVal = data[row][col].EuclideanNorm();\ 292 retVal = retVal+locVal*locVal; \ 295 return sqrt(retVal); \ 298 #define NORM_FOR_TYPE(T) \ 300 double Matrix<T>::Norm() const { \ 301 double retVal = 0.0; \ 302 double locVal = 0.0; \ 303 for (size_t row = 0; row < rows; ++row) { \ 304 for (size_t col = 0; col < cols; ++col) { \ 305 locVal = data[row][col].Norm(); \ 306 if (locVal > retVal) { \ 340 #pragma omp parallel for 341 for (
size_t col = 0; col < result.cols; ++col) {
342 for (
size_t row = 0; row < result.rows; ++row) {
343 result.data[row][col] = result.data[row][col] * other;
367 if (rows != other.rows || cols != other.cols) {
371 for (
size_t i = 0; i < rows; ++i) {
372 for (
size_t j = 0; j < cols; ++j) {
373 if (data[i][j] != other.data[i][j]) {
402 const data_t&
GetData()
const {
return data; }
441 if (rows != other.rows || cols != other.cols) {
443 "Addition operands have incompatible dimensions");
446 #pragma omp parallel for 447 for (
size_t j = 0; j < cols; ++j) {
448 for (
size_t i = 0; i < rows; ++i) {
449 result.data[i][j] += other.data[i][j];
462 return this->
Add(other);
480 if (rows != other.rows || cols != other.cols) {
482 "Subtraction operands have incompatible dimensions");
485 #pragma omp parallel for 486 for (
size_t j = 0; j < cols; ++j) {
487 for (
size_t i = 0; i < rows; ++i) {
488 result.data[i][j] = data[i][j] - other.data[i][j];
502 return this->
Sub(other);
561 Element&
operator()(
size_t row,
size_t col) {
return data[row][col]; }
571 return data[row][col];
583 for (
auto& elem : this->
GetData()[row]) {
599 for (
size_t i = 0; i < this->rows; i++) {
600 result(i, 0) = data[i][col];
616 for (usint row = row_start; row < row_end + 1; row++) {
619 for (
auto elem = this->
GetData()[row].begin();
620 elem != this->
GetData()[row].end(); ++elem) {
621 result(row - row_start, i) = *elem;
629 friend std::ostream& operator<<(std::ostream& os, const Matrix<Element>& m) {
631 for (
size_t row = 0; row < m.GetRows(); ++row) {
633 for (
size_t col = 0; col < m.GetCols(); ++col) {
634 os << m(row, col) <<
" ";
647 #define NOT_AN_ELEMENT_MATRIX(T) \ 649 void Matrix<T>::SwitchFormat() { \ 650 PALISADE_THROW(not_available_error, "Not a matrix of Elements"); \ 667 template <
class Archive>
668 void save(Archive& ar, std::uint32_t
const version)
const {
669 ar(::cereal::make_nvp(
"d", data));
670 ar(::cereal::make_nvp(
"r", rows));
671 ar(::cereal::make_nvp(
"c", cols));
674 template <
class Archive>
675 void load(Archive& ar, std::uint32_t
const version) {
676 if (version > SerializedVersion()) {
678 "serialized object version " + std::to_string(version) +
679 " is from a later version of the library");
681 ar(::cereal::make_nvp(
"d", data));
682 ar(::cereal::make_nvp(
"r", rows));
683 ar(::cereal::make_nvp(
"c", cols));
688 std::string SerializedObjectName()
const {
return "Matrix"; }
689 static uint32_t SerializedVersion() {
return 1; }
695 alloc_func allocZero;
699 void deepCopyData(data_t
const& src) {
701 data.resize(src.size());
702 for (
size_t row = 0; row < src.size(); ++row) {
703 for (
auto elem = src[row].begin(); elem != src[row].end(); ++elem) {
704 data[row].push_back(*elem);
717 template <
class Element>
729 template <
typename Element>
740 template <
typename Element>
750 template <
class Element>
751 std::ostream& operator<<(std::ostream& os, const Matrix<Element>& m);
799 template <
typename Element>
802 const shared_ptr<typename Element::Params> params);
804 #define SPLIT64_FOR_TYPE(T) \ 806 Matrix<T> SplitInt64IntoElements( \ 807 Matrix<int64_t> const& other, size_t n, \ 808 const shared_ptr<typename T::Params> params) { \ 809 auto zero_alloc = T::Allocator(params, Format::COEFFICIENT); \ 810 size_t rows = other.GetRows() / n; \ 811 Matrix<T> result(zero_alloc, rows, 1); \ 812 for (size_t row = 0; row < rows; ++row) { \ 813 std::vector<int64_t> values(n); \ 814 for (size_t i = 0; i < n; ++i) values[i] = other(row * n + i, 0); \ 815 result(row, 0) = values; \ 829 template <
typename Element>
832 const shared_ptr<typename Element::Params> params);
834 #define SPLIT32ALT_FOR_TYPE(T) \ 836 Matrix<T> SplitInt32AltIntoElements( \ 837 Matrix<int32_t> const& other, size_t n, \ 838 const shared_ptr<typename T::Params> params) { \ 839 auto zero_alloc = T::Allocator(params, Format::COEFFICIENT); \ 840 size_t rows = other.GetRows(); \ 841 Matrix<T> result(zero_alloc, rows, 1); \ 842 for (size_t row = 0; row < rows; ++row) { \ 843 std::vector<int32_t> values(n); \ 844 for (size_t i = 0; i < n; ++i) values[i] = other(row, i); \ 845 result(row, 0) = values; \ 859 template <
typename Element>
862 const shared_ptr<typename Element::Params> params);
864 #define SPLIT64ALT_FOR_TYPE(T) \ 866 Matrix<T> SplitInt64AltIntoElements( \ 867 Matrix<int64_t> const& other, size_t n, \ 868 const shared_ptr<typename T::Params> params) { \ 869 auto zero_alloc = T::Allocator(params, Format::COEFFICIENT); \ 870 size_t rows = other.GetRows(); \ 871 Matrix<T> result(zero_alloc, rows, 1); \ 872 for (size_t row = 0; row < rows; ++row) { \ 873 std::vector<int64_t> values(n); \ 874 for (size_t i = 0; i < n; ++i) values[i] = other(row, i); \ 875 result(row, 0) = values; \ 881 #endif // LBCRYPTO_MATH_MATRIX_H Matrix< Element > & VStack(Matrix< Element > const &other)
Definition: matrix.cpp:240
Base class for PALISADE serialization.
Definition: serializable.h:76
Matrix< Element > CofactorMatrix() const
Definition: matrix.cpp:195
Matrix< Element > Sub(Matrix< Element > const &other) const
Definition: matrix.h:479
Matrix< Element > & HStack(Matrix< Element > const &other)
Definition: matrix.cpp:258
Element const & operator()(size_t row, size_t col) const
Definition: matrix.h:570
Matrix< Element > ExtractRows(size_t row_start, size_t row_end) const
Definition: matrix.h:612
Matrix< Element > & Identity()
Matrix< Element > ScalarMult(Element const &other) const
Definition: matrix.h:338
Matrix< Element > Mult(Matrix< Element > const &other) const
Definition: matrix.cpp:64
Matrix< Element > SplitInt32AltIntoElements(Matrix< int32_t > const &other, size_t n, const shared_ptr< typename Element::Params > params)
bool operator==(Matrix< Element > const &other) const
Definition: matrix.h:387
Matrix< Element > SplitInt64AltIntoElements(Matrix< int64_t > const &other, size_t n, const shared_ptr< typename Element::Params > params)
const data_t & GetData() const
Definition: matrix.h:402
size_t GetRows() const
Definition: matrix.h:409
Matrix(alloc_func allocZero=0)
Definition: matrix.h:93
Matrix< Element > & ModEq(const Element &modulus)
Matrix< Element > operator-(Matrix< Element > const &other) const
Definition: matrix.h:501
Definition: exception.h:147
Definition: exception.h:113
Matrix< Element > & operator=(const Matrix< Element > &other)
Definition: matrix.cpp:46
void SetAllocator(alloc_func allocZero)
Definition: matrix.h:126
Matrix< Element > & Ones()
Matrix< Element > GadgetVector(int64_t base=2) const
Matrix< Element > Add(Matrix< Element > const &other) const
Definition: matrix.h:440
Matrix< Element > Transpose() const
Definition: matrix.cpp:124
bool Equal(Matrix< Element > const &other) const
Definition: matrix.h:366
Matrix< Element > & Fill(const Element &val)
Definition: matrix.cpp:54
Matrix< Element > operator*(Element const &other) const
Definition: matrix.h:356
Matrix< Element > & operator-=(Matrix< Element > const &other)
Definition: matrix.cpp:108
Matrix(alloc_func allocZero, size_t rows, size_t cols)
Definition: matrix.h:60
Main class for big integers represented as an array of native (primitive) unsigned integers...
Definition: ubintfxd.h:219
Matrix< Element > SplitInt64IntoElements(Matrix< int64_t > const &other, size_t n, const shared_ptr< typename Element::Params > params)
alloc_func GetAllocator() const
Definition: matrix.h:423
void SetSize(size_t rows, size_t cols)
Definition: matrix.h:103
Matrix(const Matrix< Element > &other)
Definition: matrix.h:133
double EuclideanNorm() const
Matrix< typename Element::Vector > RotateVecResult(Matrix< Element > const &inMat)
Definition: matrix-lattice-impl.cpp:72
void SwitchFormat()
Definition: matrix-lattice-impl.cpp:113
Matrix< typename Element::Integer > Rotate(Matrix< Element > const &inMat)
Definition: matrix-lattice-impl.cpp:39
Matrix< Element > ExtractRow(size_t row) const
Definition: matrix.h:580
void SetFormat(Format format)
Definition: matrix-lattice-impl.cpp:104
size_t GetCols() const
Definition: matrix.h:416
Matrix< double > Cholesky(const Matrix< int32_t > &input)
Matrix< Element > operator*(Matrix< Element > const &other) const
Definition: matrix.h:328
Definition: binfhecontext.h:36
Definition: exception.h:126
Matrix< Element > operator+(Matrix< Element > const &other) const
Definition: matrix.h:461
Matrix< Element > & operator+=(Matrix< Element > const &other)
Definition: matrix.cpp:92
Matrix< Element > ExtractCol(size_t col) const
Definition: matrix.h:597
Element & operator()(size_t row, size_t col)
Definition: matrix.h:561
void Determinant(Element *result) const
Definition: matrix.cpp:143
bool operator!=(Matrix< Element > const &other) const
Definition: matrix.h:395
Matrix< Element > & ModSubEq(Matrix< Element > const &b, const Element &modulus)
Matrix< int32_t > ConvertToInt32(const Matrix< BigInteger > &input, const BigInteger &modulus)
Definition: matrix-impl.cpp:197