Antares Simulator
Power System Simulator
matrix-to-buffer.hxx
1 /*
2 ** Copyright 2007-2025, RTE (https://www.rte-france.com)
3 ** See AUTHORS.txt
4 ** SPDX-License-Identifier: MPL-2.0
5 ** This file is part of Antares-Simulator,
6 ** Adequacy and Performance assessment for interconnected energy networks.
7 **
8 ** Antares_Simulator is free software: you can redistribute it and/or modify
9 ** it under the terms of the Mozilla Public Licence 2.0 as published by
10 ** the Mozilla Foundation, either version 2 of the License, or
11 ** (at your option) any later version.
12 **
13 ** Antares_Simulator is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** Mozilla Public Licence 2.0 for more details.
17 **
18 ** You should have received a copy of the Mozilla Public Licence 2.0
19 ** along with Antares_Simulator. If not, see <https://opensource.org/license/mpl-2-0/>.
20 */
21 
22 #ifndef __ANTARES_LIBS_ARRAY_MATRIX_TO_BUFFER_SENDER_HXX__
23 #define __ANTARES_LIBS_ARRAY_MATRIX_TO_BUFFER_SENDER_HXX__
24 
25 #ifdef YUNI_OS_MSVC
26 #define ANTARES_MATRIX_SNPRINTF sprintf_s
27 #else
28 #define ANTARES_MATRIX_SNPRINTF snprintf
29 #endif
30 
31 #include <antares/utils/utils.h>
32 
33 namespace Antares
34 {
35 namespace // anonymous
36 {
37 template<class T>
38 struct MatrixScalar
39 {
40  static inline void Append(std::string& file, T v, const char* const)
41  {
42  if (Utils::isZero(v))
43  {
44  file.append(std::to_string(0));
45  }
46  else
47  {
48  file.append(std::to_string(v));
49  }
50  }
51 };
52 
53 template<>
54 struct MatrixScalar<double>
55 {
56  static void Append(std::string& file, double v, const char* const format)
57  {
58  if (Utils::isZero(v))
59  {
60  file += '0';
61  }
62  else
63  {
64  char ConversionBuffer[128];
65  const int sizePrintf = Utils::isZero(v - floor(v))
66  ? ANTARES_MATRIX_SNPRINTF(ConversionBuffer,
67  sizeof(ConversionBuffer),
68  "%.0f",
69  v)
70  : ANTARES_MATRIX_SNPRINTF(ConversionBuffer,
71  sizeof(ConversionBuffer),
72  format,
73  v);
74 
75  if (sizePrintf >= 0 and sizePrintf < (int)(sizeof(ConversionBuffer)))
76  {
77  file += (const char*)ConversionBuffer;
78  }
79  else
80  {
81  file += "ERR";
82  }
83  }
84  }
85 };
86 
87 template<>
88 struct MatrixScalar<float>
89 {
90  static void Append(std::string& file, float v, const char* const format)
91  {
92  if (Utils::isZero(v))
93  {
94  file += '0';
95  }
96  else
97  {
98  char ConversionBuffer[128];
99  const int sizePrintf = Utils::isZero(v - floor(v))
100  ? ANTARES_MATRIX_SNPRINTF(ConversionBuffer,
101  sizeof(ConversionBuffer),
102  "%.0f",
103  (double)v)
104  : ANTARES_MATRIX_SNPRINTF(ConversionBuffer,
105  sizeof(ConversionBuffer),
106  format,
107  (double)v);
108 
109  if (sizePrintf >= 0 and sizePrintf < (int)(sizeof(ConversionBuffer)))
110  {
111  file += (const char*)ConversionBuffer;
112  }
113  else
114  {
115  file += "ERR";
116  }
117  }
118  }
119 };
120 
121 } // anonymous namespace
122 
123 template<class T, class ReadWriteT, class PredicateT>
124 std::unique_ptr<I_mtx_to_buffer_dumper<T, ReadWriteT, PredicateT>>
125 matrix_to_buffer_dumper_factory::get_dumper(const Matrix<T, ReadWriteT>* mtx,
126  std::string& data,
127  PredicateT& predicate)
128 {
129  if (mtx->width == 1)
130  {
131  return std::make_unique<one_column__dumper<T, ReadWriteT, PredicateT>>(mtx,
132  data,
133  predicate);
134  }
135  else
136  {
137  return std::make_unique<multiple_columns__dumper<T, ReadWriteT, PredicateT>>(mtx,
138  data,
139  predicate);
140  }
141 }
142 
143 template<class T, class ReadWriteT, class PredicateT>
144 void I_mtx_to_buffer_dumper<T, ReadWriteT, PredicateT>::set_print_format(bool isDecimal,
145  uint precision)
146 {
147  // Determining the string format to use according the given precision
148  format_ = "%.0f";
149 
150  if (isDecimal and precision)
151  {
152  const char* const sfmt[] = {
153  "%.0f",
154  "%.1f",
155  "%.2f",
156  "%.3f",
157  "%.4f",
158  "%.5f",
159  "%.6f",
160  "%.7f",
161  "%.8f",
162  "%.9f",
163  "%.10f",
164  "%.11f",
165  "%.12f",
166  "%.13f",
167  "%.14f",
168  "%.15f",
169  "%.16f",
170  };
171  assert(precision <= 16);
172  format_ = sfmt[precision];
173  }
174 }
175 
176 template<class T, class ReadWriteT, class PredicateT>
177 void one_column__dumper<T, ReadWriteT, PredicateT>::run()
178 {
179  for (uint y = 0; y != (this->mtx_)->height; ++y)
180  {
181  MatrixScalar<ReadWriteT>::Append(this->buffer_,
182  (ReadWriteT)this->predicate_((this->mtx_)->entry[0][y]),
183  this->format_.c_str());
184  this->buffer_ += '\n';
185  }
186 }
187 
188 template<class T, class ReadWriteT, class PredicateT>
189 void multiple_columns__dumper<T, ReadWriteT, PredicateT>::run()
190 {
191  for (uint y = 0; y < (this->mtx_)->height; ++y)
192  {
193  MatrixScalar<ReadWriteT>::Append(this->buffer_,
194  (ReadWriteT)this->predicate_((this->mtx_)->entry[0][y]),
195  this->format_.c_str());
196  for (uint x = 1; x < (this->mtx_)->width; ++x)
197  {
198  this->buffer_ += '\t';
199  MatrixScalar<ReadWriteT>::Append(this->buffer_,
200  (ReadWriteT)this->predicate_(
201  (this->mtx_)->entry[x][y]),
202  this->format_.c_str());
203  }
204  this->buffer_ += '\n';
205  }
206 }
207 
208 } // namespace Antares
209 
210 #undef ANTARES_MATRIX_SNPRINTF
211 
212 #endif // __ANTARES_LIBS_ARRAY_MATRIX_TO_BUFFER_SENDER_HXX__