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