1 /*
2  * Copyright © 2004 Ondra Kamenik
3  * Copyright © 2019 Dynare Team
4  *
5  * This file is part of Dynare.
6  *
7  * Dynare is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Dynare is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "twod_matrix.hh"
22 #include "tl_exception.hh"
23 
24 #include <memory>
25 #include <fstream>
26 #include <iomanip>
27 #include <limits>
28 
ConstTwoDMatrix(const TwoDMatrix & m)29 ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix &m)
30   : ConstGeneralMatrix(m)
31 {
32 }
33 
ConstTwoDMatrix(const TwoDMatrix & m,int first_col,int num)34 ConstTwoDMatrix::ConstTwoDMatrix(const TwoDMatrix &m, int first_col, int num)
35   : ConstGeneralMatrix(m, 0, first_col, m.nrows(), num)
36 {
37 }
38 
ConstTwoDMatrix(const ConstTwoDMatrix & m,int first_col,int num)39 ConstTwoDMatrix::ConstTwoDMatrix(const ConstTwoDMatrix &m, int first_col, int num)
40   : ConstGeneralMatrix(m, 0, first_col, m.nrows(), num)
41 {
42 }
43 
ConstTwoDMatrix(int first_row,int num,const TwoDMatrix & m)44 ConstTwoDMatrix::ConstTwoDMatrix(int first_row, int num, const TwoDMatrix &m)
45   : ConstGeneralMatrix(m, first_row, 0, num, m.ncols())
46 {
47 }
48 
ConstTwoDMatrix(int first_row,int num,const ConstTwoDMatrix & m)49 ConstTwoDMatrix::ConstTwoDMatrix(int first_row, int num, const ConstTwoDMatrix &m)
50   : ConstGeneralMatrix(m, first_row, 0, num, m.ncols())
51 {
52 }
53 
54 void
writeMat(mat_t * fd,const std::string & vname) const55 ConstTwoDMatrix::writeMat(mat_t *fd, const std::string &vname) const
56 {
57   size_t dims[2];
58   dims[0] = nrows();
59   dims[1] = ncols();
60   auto data = std::make_unique<double[]>(nrows()*ncols());
61 
62   for (int j = 0; j < ncols(); j++)
63     for (int i = 0; i < nrows(); i++)
64       data[j*nrows()+i] = get(i, j);
65 
66   matvar_t *v = Mat_VarCreate(vname.c_str(), MAT_C_DOUBLE, MAT_T_DOUBLE, 2, dims, data.get(), 0);
67 
68   Mat_VarWrite(fd, v, MAT_COMPRESSION_NONE);
69 
70   Mat_VarFree(v);
71 }
72 
73 TwoDMatrix &
operator =(const ConstTwoDMatrix & m)74 TwoDMatrix::operator=(const ConstTwoDMatrix &m)
75 {
76   GeneralMatrix::operator=(m);
77   return *this;
78 }
79 
80 void
copyRow(int from,int to)81 TwoDMatrix::copyRow(int from, int to)
82 {
83   if (from != to)
84     copyRow(ConstTwoDMatrix(*this), from, to);
85 }
86 
87 void
copyRow(const ConstTwoDMatrix & m,int from,int to)88 TwoDMatrix::copyRow(const ConstTwoDMatrix &m, int from, int to)
89 {
90   getRow(to) = m.getRow(from);
91 }
92 
93 void
addRow(double d,const ConstTwoDMatrix & m,int from,int to)94 TwoDMatrix::addRow(double d, const ConstTwoDMatrix &m, int from, int to)
95 {
96   getRow(to).add(d, m.getRow(from));
97 }
98 
99 void
copyColumn(int from,int to)100 TwoDMatrix::copyColumn(int from, int to)
101 {
102   if (from != to)
103     copyColumn(ConstTwoDMatrix(*this), from, to);
104 }
105 
106 void
copyColumn(const ConstTwoDMatrix & m,int from,int to)107 TwoDMatrix::copyColumn(const ConstTwoDMatrix &m, int from, int to)
108 {
109   getCol(to) = m.getCol(from);
110 }
111 
112 void
addColumn(double d,const ConstTwoDMatrix & m,int from,int to)113 TwoDMatrix::addColumn(double d, const ConstTwoDMatrix &m, int from, int to)
114 {
115   getCol(to).add(d, m.getCol(from));
116 }
117 
118 void
save(const std::string & fname) const119 TwoDMatrix::save(const std::string &fname) const
120 {
121   std::ofstream fd{fname, std::ios::out | std::ios::trunc};
122   if (fd.fail())
123     TL_RAISE("Cannot open file for writing in TwoDMatrix::save");
124 
125   fd << std::setprecision(std::numeric_limits<double>::max_digits10);
126 
127   for (int row = 0; row < nrows(); row++)
128     {
129       for (int col = 0; col < ncols(); col++)
130         fd << ' ' << get(row, col);
131       fd << '\n';
132     }
133   fd.close();
134 }
135