TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
TBNN.cpp
1/****************************************************************************
2* Copyright (c) 2023, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15#include <PrePostNN.h>
16#include <TBNN.h>
17#include <cmath>
18#include <cstddef>
19#include <iostream>
20#include <keras_model.h>
21#include <string>
22#include <vector>
23
24int sgn(double v)
25{
26 return (v > 0) - (v < 0);
27}
28
29TBNN::TBNN(string keras_model_file,string preproc_file)
30{
31 _ppNN = new PrePostNN(preproc_file);
32 _model.LoadModel(keras_model_file);
33}
34
36{
37 delete(_ppNN);
38}
39
40std::vector<double> TBNN::predict(std::vector<double> lambda, std::vector<std::vector<double>> T)
41{
42 process_lambda(lambda);
43 process_T(T);
44 applyNN();
45 process_b();
46 return(_b);
47}
48
49void TBNN::process_lambda(std::vector<double> lambda)
50{
51 std::vector<double> lc; // lambda centre
52 std::vector<double> lcr; // lambda centre reduit
53 size_t nbl = lambda.size(); // nombre d'invariants lambda
54
55 lc.resize(nbl);
56 lcr.resize(nbl);
57 _plambda.resize(nbl);
58
59 switch(_ppNN->get_ppl())
60 {
61 case LNORM:
62 // centrage des lambda
63 if( _ppNN->get_lmean().size() == nbl )
64 for(unsigned int i=0; i<nbl; i++)
65 lc[i] = lambda[i] - _ppNN->get_lmean()[i];
66 else
67 for(unsigned int i=0; i<nbl; i++)
68 lc[i] = lambda[i];
69 // reduction des lambda
70 for(unsigned int i=0; i<nbl; i++)
71 _plambda[i] = lc[i] / _ppNN->get_lmax()[i];
72 break;
73 case LU:
74 // puissance alpha
75 if( _ppNN->get_alpha().size() == nbl )
76 for(unsigned int i=0; i<nbl; i++)
77 lc[i] = sgn(lambda[i]) * pow(std::fabs(lambda[i]),_ppNN->get_alpha()[i]);
78 else
79 for(unsigned int i=0; i<nbl; i++)
80 lc[i] = lambda[i];
81 // centrage des lambda
82 if( _ppNN->get_lmean().size() == nbl )
83 for(unsigned int i=0; i<nbl; i++)
84 lc[i] = lc[i] - _ppNN->get_lmean()[i];
85 // reduction des lambda
86 for(unsigned int i=0; i<nbl; i++)
87 lcr[i] = lc[i] / _ppNN->get_lmax()[i];
88 // multiplication par transpose(au)
89 for(unsigned int i=0; i<nbl; i++)
90 {
91 _plambda[i] = 0.;
92 for(unsigned int j=0; j<nbl; j++)
93 _plambda[i] += _ppNN->get_lambda_au()[j][i] * lcr[j];
94 }
95 break;
96 case LUS:
97 // puissance alpha
98 if( _ppNN->get_alpha().size() == nbl )
99 for(unsigned int i=0; i<nbl; i++)
100 lc[i] = sgn(lambda[i]) * pow(std::fabs(lambda[i]),_ppNN->get_alpha()[i]);
101 else
102 for(unsigned int i=0; i<nbl; i++)
103 lc[i] = lambda[i];
104 // centrage des lambda
105 if( _ppNN->get_lmean().size() == nbl )
106 for(unsigned int i=0; i<nbl; i++)
107 lc[i] = lc[i] - _ppNN->get_lmean()[i];
108 // reduction des lambda
109 for(unsigned int i=0; i<nbl; i++)
110 lcr[i] = lc[i] / _ppNN->get_lmax()[i];
111 // multiplication par transpose(as)
112 for(unsigned int i=0; i<nbl; i++)
113 {
114 _plambda[i] = 0.;
115 for(unsigned int j=0; j<nbl; j++)
116 _plambda[i] += _ppNN->get_lambda_as()[j][i] * lcr[j];
117 }
118 break;
119 default:
120 // on lance une exception
121 cerr << "Mauvaise methode de pre traitement des lambda" << endl;
122 break;
123 }
124}
125
126void TBNN::process_T(std::vector<std::vector<double>> T)
127{
128 size_t nbt = T.size(); // nombre de tenseurs T
129 size_t nbb = T[0].size(); // taille de chacun des tenseurs T
130
131 _pT.resize(nbt);
132 for(unsigned i=0; i<nbt; i++)
133 _pT[i].resize(nbb);
134
135 // le premier tenseur T0 reste inchange
136 for(unsigned int j=0; j<nbb; j++)
137 _pT[0][j] = T[0][j];
138
139 // pre process de T
140 switch(_ppNN->get_ppt())
141 {
142 case TF:
143 // on calcule la norme de Frobenius de chaque tenseur
144 for(unsigned int i=1; i<nbt; i++)
145 {
146 double normf = 0.;
147 for(unsigned int j=0; j<nbb; j++)
148 normf += T[i][j] * T[i][j];
149 normf = sqrt(normf);
150 for(unsigned int j=0; j<nbb; j++)
151 _pT[i][j] = T[i][j] / (normf + _ppNN->get_t_thresh());
152 }
153 break;
154 case TR:
155 // on divise le tenseur Ti par la norme globale
156 for(unsigned int i=1; i<nbt; i++)
157 for(unsigned int j=0; j<nbb; j++)
158 _pT[i][j] = T[i][j] / _ppNN->get_tfn()[i-1];
159 break;
160 default:
161 // on lance une exception
162 cerr << "Mauvaise methode de pre traitement des tenseurs T" << endl;
163 break;
164 }
165}
166
167void TBNN::process_b()
168{
169 std::vector<int> iT = _ppNN->get_iT();
170 size_t nbt = iT.size();
171 size_t nbb = _pT[0].size();
172
173 // calcul de _pb a partir de _g et de _pT
174 _pb.resize(nbb);
175 for(unsigned int i=0; i<nbb; i++)
176 {
177 _pb[i] = 0;
178 for(unsigned int j=0; j<nbt; j++)
179 _pb[i] += _g[j] * _pT[iT[j]][i];
180 }
181
182 // post process de b
183 _b.resize(nbb);
184 for(unsigned int i=0; i<nbb; i++)
185 _b[i] = _ppNN->get_bsigma() * _pb[i];
186}
187
188void TBNN::applyNN()
189{
190 std::vector<int> il = _ppNN->get_ilambda();
191 std::vector<int> iT = _ppNN->get_iT();
192 Tensor in((int)il.size());
193 Tensor out;
194 size_t nbt = iT.size();
195
196 _g.resize(nbt);
197
198 // l'entree du reseau est determinee par les indices des lambdas definis dans le vecteur il
199 for(unsigned int i=0; i<il.size(); i++)
200 in.data_[i] = (float)_plambda[il[i]];
201
202 // on fait la prediction a l'aide du reseau de neurones
203 _model.Apply(&in,&out);
204
205 // on stocke les sorties dans _g
206 for(unsigned int i=0; i<nbt; i++) _g[i] = out(i);
207
208}
vector< double > get_alpha()
Definition PrePostNN.h:33
enum pp_lambda get_ppl()
Definition PrePostNN.h:41
vector< double > get_lmax()
Definition PrePostNN.h:35
vector< double > get_lmean()
Definition PrePostNN.h:34
vector< vector< double > > get_lambda_au()
Definition PrePostNN.h:39
~TBNN()
Definition TBNN.cpp:35
std::vector< double > predict(std::vector< double > lambda, std::vector< std::vector< double > > T)
Definition TBNN.cpp:40
TBNN(string keras_model_file, string preproc_file)
Definition TBNN.cpp:29