Antares Simulator
Power System Simulator
cholesky.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 
23 #define ANTARES_CHOLESKY_EPSIMIN ((T)1.0e-9)
24 
25 #include <cmath>
26 
27 namespace Antares::Solver
28 {
29 template<class T, class U1, class U2>
30 bool Cholesky(U1& L, U2& A, uint size, T* temp)
31 {
32  using namespace Yuni;
33 
34  for (uint i = 0; i != size; ++i)
35  {
36  temp[i] = 0;
37  }
38 
39  T som;
40 
41  for (uint i = 0; i < size; ++i)
42  {
43  auto& Li = L[i];
44 
45  // on calcule d'abord L[i][i]
46  som = A[i][i];
47  for (int j = 0; j <= (int)(i - 1); ++j)
48  {
49  som -= Li[j] * Li[j];
50  }
51 
52  if (som > ANTARES_CHOLESKY_EPSIMIN)
53  {
54  Li[i] = std::sqrt(som);
55 
56  // maintenant on cherche L[k][i], k > i.
57  for (uint k = i + 1; k < size; ++k)
58  {
59  auto& Lk = L[k];
60  auto& Ak = A[k];
61 
62  if (temp[k] == Ak[k])
63  {
64  Lk[i] = 0;
65  }
66  else
67  {
68  som = Ak[i];
69  for (int j = 0; j <= (int)(i - 1); ++j)
70  {
71  som -= Li[j] * Lk[j];
72  }
73 
74  Lk[i] = som / Li[i];
75  temp[k] += Lk[i] * Lk[i];
76 
77  // si temp[k] = A[k][k] la matrice n'est pas dp mais il est encore possible
78  // qu'elle soit sdp.
79  // si temp > A[k][k] alors il est certain que A n'est ni sdp ni dp donc on
80  // arrete le calcul
81  if (temp[k] > Ak[k])
82  {
83  return true;
84  }
85  }
86  }
87  }
88  else
89  {
90  // annule le reste de la colonne
91  for (uint k = i; k != size; ++k)
92  {
93  L[k][i] = 0;
94  }
95  }
96  }
97 
98  return false;
99 }
100 
101 } // namespace Antares::Solver
102 
103 #undef ANTARES_CHOLESKY_EPSIMIN