Antares Simulator
Power System Simulator
stdDeviation.h
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 #ifndef __SOLVER_VARIABLE_STORAGE_STD_DEVIATION_H__
22 #define __SOLVER_VARIABLE_STORAGE_STD_DEVIATION_H__
23 
24 #include <cmath>
25 #include <float.h>
26 
27 using HighPrecision = long double;
28 
29 namespace Antares::Solver::Variable::R::AllYears
30 {
31 template<class NextT = Empty, int FileFilter = Variable::Category::FileLevel::allFile>
32 struct StdDeviation: public NextT
33 {
34 public:
36  typedef NextT NextType;
37 
38  enum
39  {
41  count = 1 + NextT::count,
42 
43  categoryFile = NextT::categoryFile | Variable::Category::FileLevel::allFile,
44  };
45 
46  struct Data
47  {
48  double value;
49  uint32_t indice;
50  };
51 
53  static const char* Name()
54  {
55  return "std deviation";
56  }
57 
58 protected:
59  void initializeFromStudy(Antares::Data::Study& study)
60  {
61  stdDeviationHourly.assign(HOURS_PER_YEAR, 0.);
62  stdDeviationDaily.assign(DAYS_PER_YEAR, 0.);
63  stdDeviationWeekly.assign(WEEKS_PER_YEAR, 0.);
64  stdDeviationMonthly.assign(MONTHS_PER_YEAR, 0.);
65  // Next
66  NextType::initializeFromStudy(study);
67 
68  yearsWeight = study.parameters.getYearsWeight();
69  yearsWeightSum = study.parameters.getYearsWeightSum();
70  }
71 
72  void reset()
73  {
74  // Reset
75  stdDeviationHourly.assign(HOURS_PER_YEAR, 0.);
76  stdDeviationDaily.assign(DAYS_PER_YEAR, 0.);
77  stdDeviationWeekly.assign(WEEKS_PER_YEAR, 0.);
78  stdDeviationMonthly.assign(MONTHS_PER_YEAR, 0.);
79  stdDeviationYear = 0.;
80  // Next
81  NextType::reset();
82  }
83 
84  void merge(unsigned int year, const IntermediateValues& rhs)
85  {
86  // Ratio take into account MC year weight
87  double pRatio = (double)yearsWeight[year] / (double)yearsWeightSum;
88 
89  unsigned int i;
90  // StdDeviation value for each hour throughout all years
91  for (i = 0; i != HOURS_PER_YEAR; ++i)
92  {
93  stdDeviationHourly[i] += rhs.hour[i] * rhs.hour[i] * pRatio;
94  }
95  // StdDeviation value for each day throughout all years
96  for (i = 0; i != DAYS_PER_YEAR; ++i)
97  {
98  stdDeviationDaily[i] += rhs.day[i] * rhs.day[i] * pRatio;
99  }
100  // StdDeviation value for each week throughout all years
101  for (i = 0; i != WEEKS_PER_YEAR; ++i)
102  {
103  stdDeviationWeekly[i] += rhs.week[i] * rhs.week[i] * pRatio;
104  }
105  // StdDeviation value for each month throughout all years
106  for (i = 0; i != MONTHS_PER_YEAR; ++i)
107  {
108  stdDeviationMonthly[i] += rhs.month[i] * rhs.month[i] * pRatio;
109  }
110  // StdDeviation value throughout all years
111  stdDeviationYear += rhs.year * rhs.year * pRatio;
112 
113  // Next
114  NextType::merge(year, rhs);
115  }
116 
117  template<class S, class VCardT>
118  void buildSurveyReport(SurveyResults& report,
119  const S& results,
120  int dataLevel,
121  int fileLevel,
122  int precision) const
123  {
124  if (!(fileLevel & Category::FileLevel::id))
125  {
126  switch (precision)
127  {
128  case Category::hourly:
129  InternalExportValues<S, HOURS_PER_YEAR, VCardT, Category::hourly>(
130  report,
131  results,
132  stdDeviationHourly.data());
133  break;
134  case Category::daily:
135  InternalExportValues<S, DAYS_PER_YEAR, VCardT, Category::daily>(
136  report,
137  results,
138  stdDeviationDaily.data());
139  break;
140  case Category::weekly:
141  InternalExportValues<S, WEEKS_PER_YEAR, VCardT, Category::weekly>(
142  report,
143  results,
144  stdDeviationWeekly.data());
145  break;
146  case Category::monthly:
147  InternalExportValues<S, MONTHS_PER_YEAR, VCardT, Category::monthly>(
148  report,
149  results,
150  stdDeviationMonthly.data());
151  break;
152  case Category::annual:
153  InternalExportValues<S, 1, VCardT, Category::annual>(report,
154  results,
155  &stdDeviationYear);
156  break;
157  }
158  }
159  // Next
160  NextType::template buildSurveyReport<S, VCardT>(report,
161  results,
162  dataLevel,
163  fileLevel,
164  precision);
165  }
166 
167 public:
168  std::vector<HighPrecision> stdDeviationMonthly;
169  std::vector<HighPrecision> stdDeviationWeekly;
170  std::vector<HighPrecision> stdDeviationDaily;
171  std::vector<HighPrecision> stdDeviationHourly;
172  HighPrecision stdDeviationYear = 0;
173 
174 private:
175  template<class S, unsigned int Size, class VCardT, int PrecisionT>
176  void InternalExportValues(SurveyResults& report,
177  const S& results,
178  const HighPrecision* array) const
179  {
180  assert(report.data.columnIndex < report.maxVariables && "Column index out of bounds");
181 
182  // Caption
183  report.captions[0][report.data.columnIndex] = report.variableCaption;
184  report.captions[1][report.data.columnIndex] = report.variableUnit;
185  report.captions[2][report.data.columnIndex] = "std";
186 
187  // Precision
188  report.precision[report.data.columnIndex] = PrecisionToPrintfFormat<
189  VCardT::decimal>::Value();
190 
191  // Non applicability
192  report.nonApplicableStatus[report.data.columnIndex] = *report.isCurrentVarNA;
193 
194  // Values
195  double* target = report.values[report.data.columnIndex];
196  // A mere copy
197 
198  auto squareRootChecked = [](double d) { return d >= 0 ? std::sqrt(d) : 0.; };
199 
200  switch (PrecisionT)
201  {
202  case Category::hourly:
203  {
204  for (unsigned int i = 0; i != Size; ++i)
205  {
206  double v = results.avgdata.hourly[i];
207  double a = array[i];
208  target[i] = squareRootChecked(a - v * v);
209  }
210  }
211  break;
212  case Category::daily:
213  {
214  for (unsigned int i = 0; i != Size; ++i)
215  {
216  double v = results.avgdata.daily[i];
217  double a = array[i];
218  target[i] = squareRootChecked(a - v * v);
219  }
220  }
221  break;
222  case Category::weekly:
223  {
224  for (unsigned int i = 0; i != Size; ++i)
225  {
226  double v = results.avgdata.weekly[i];
227  double a = array[i];
228  target[i] = squareRootChecked(a - v * v);
229  }
230  }
231  break;
232  case Category::monthly:
233  {
234  for (unsigned int i = 0; i != Size; ++i)
235  {
236  double v = results.avgdata.monthly[i];
237  double a = array[i];
238  target[i] = squareRootChecked(a - v * v);
239  }
240  }
241  break;
242  case Category::annual:
243  {
244  const double d = *array - results.avgdata.allYears * results.avgdata.allYears;
245  *target = squareRootChecked(d);
246  }
247  break;
248  }
249 
250  // Next column index
251  ++report.data.columnIndex;
252  }
253 
254  template<class S, unsigned int Size, class VCardT, int PrecisionT, class A>
255  void InternalExportValuesMC(SurveyResults& report, const S& /*results*/, const A& array) const
256  {
257  if (not(PrecisionT & Category::annual))
258  {
259  return;
260  }
261  assert(report.data.columnIndex < report.maxVariables && "Column index out of bounds");
262 
263  // Caption
264  report.captions[0][report.data.columnIndex] = report.variableCaption;
265  report.captions[1][report.data.columnIndex] = report.variableUnit;
266  report.captions[2][report.data.columnIndex] = "std";
267 
268  // Precision
269  report.precision[report.data.columnIndex] = PrecisionToPrintfFormat<
270  VCardT::decimal>::Value();
271 
272  // Non applicability
273  report.nonApplicableStatus[report.data.columnIndex] = *report.isCurrentVarNA;
274 
275  (void)::memcpy(report.data.matrix[report.data.columnIndex], array, Size * sizeof(double));
276 
277  // Next column index
278  ++report.data.columnIndex;
279  }
280 
281 private:
282  std::vector<float> yearsWeight;
283  float yearsWeightSum;
284 
285 }; // class StdDeviation
286 
287 } // namespace Antares::Solver::Variable::R::AllYears
288 
289 #endif // __SOLVER_VARIABLE_STORAGE_STD_DEVIATION_H__
Definition: study.h:57
Temporary buffer for allocating results for a single year.
Definition: intermediate.h:42
Type week[WEEKS_PER_YEAR]
Values for each week.
Definition: intermediate.h:128
Type year
Year.
Definition: intermediate.h:134
Antares::Memory::Stored< Type >::Type hour
Values for each hour in the year.
Definition: intermediate.h:132
Type month[MONTHS_PER_YEAR]
Values for each month.
Definition: intermediate.h:126
Type day[DAYS_PER_YEAR]
Values for each day in the year.
Definition: intermediate.h:130
@ count
The count if item in the list.
Definition: stdDeviation.h:41
static const char * Name()
Name of the filter.
Definition: stdDeviation.h:53
NextT NextType
Type of the net item in the list.
Definition: stdDeviation.h:36