Antares Simulator
Power System Simulator
Loading...
Searching...
No Matches
matrix-dp-make.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#ifndef __ANTARES_SOLVER_MISC_MATRIX_DP_MAKE_HXX__
22#define __ANTARES_SOLVER_MISC_MATRIX_DP_MAKE_HXX__
23
24namespace Antares
25{
26namespace Solver
27{
28template<class T, class U1, class U2, class U3, class U4>
29T MatrixDPMake(U1& L, U2& A, U3& B, U4& C, uint size, T* temp, bool CIsIdentity)
30{
31 enum
32 {
34 dichotomie = 10,
36 maxLoopCount = 10,
37 };
38
39 T rho = T(1);
40 T top = T(1);
41 T bot = T(0);
42 T r;
43
44 if (not Cholesky<T>(L, A, size, temp))
45 {
46 for (uint j = 0; j != size; ++j)
47 {
48 for (uint k = 0; k <= j; ++k)
49 {
50 B[j][k] = A[j][k];
51 }
52 }
53 // A est definie positive ou semi-dp: pas de redressement à faire et LtL = A
54 return T(1);
55 }
56
57 // Il faut trouver B definie positive et proche de A
58 for (uint j = 0; j != size; ++j)
59 {
60 B[j][j] = T(1);
61 }
62
63 uint compteur = 0;
64 do
65 {
66 for (uint i = 0; i != dichotomie; ++i)
67 {
68 r = (top + bot) / T(2);
69 if (not CIsIdentity)
70 {
71 for (uint j = 0; j != size; ++j)
72 {
73 for (uint k = 0; k < j; ++k)
74 {
75 B[j][k] = A[j][k] * r + C[j][k] * (T(1) - r);
76 }
77 }
78 }
79 else
80 {
81 for (uint j = 0; j != size; ++j)
82 {
83 for (uint k = 0; k < j; ++k)
84 {
85 B[j][k] = A[j][k] * r; // + C[j][k] * (T(1) - r);
86 }
87 }
88 }
89
90 if (Cholesky<T>(L, B, size, temp))
91 {
92 top = r;
93 }
94 else
95 {
96 bot = r;
97 rho = bot;
98 }
99 }
100
101 if (rho < T(1))
102 {
103 // la derniere matrice n'etait pas bonne, il faut recalculer
104 if (r != rho)
105 {
106 if (!CIsIdentity)
107 {
108 for (uint j = 0; j != size; ++j)
109 {
110 for (uint k = 0; k < j; ++k)
111 {
112 B[j][k] = A[j][k] * rho + C[j][k] * (T(1) - rho);
113 }
114 }
115 }
116 else
117 {
118 for (uint j = 0; j != size; ++j)
119 {
120 for (uint k = 0; k < j; ++k)
121 {
122 B[j][k] = A[j][k] * rho; // + C[j][k] * (T(1) - rho);
123 }
124 }
125 }
126 Cholesky<T>(L, B, size, temp);
127 }
128 return rho;
129 }
130
131 // avoid infinite loops
132 if (++compteur > maxLoopCount) // si on n'a pas eu convergence C n'est pas valide
133 {
134 return T(-1);
135 }
136 } while (true);
137
138 return rho;
139}
140
141} // namespace Solver
142} // namespace Antares
143
144#endif // __ANTARES_SOLVER_MISC_MATRIX_DP_MAKE_HXX__