PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/ensemble/ClassEnsembleBase.cxx

https://gitlab.com/ineris/GPEC
C++ | 934 lines | 711 code | 186 blank | 37 comment | 142 complexity | 0f20400f36ba362b5638dc06d6b973cf MD5 | raw file
Possible License(s): GPL-3.0
  1. // Copyright (C) 2013-2015 INERIS
  2. // Author(s) : Edouard Debry
  3. //
  4. // This file is part of GPEC.
  5. //
  6. // GPEC is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // GPEC is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with GPEC. If not, see <http://www.gnu.org/licenses/>.
  18. #ifndef GPEC_FILE_CLASS_ENSEMBLE_BASE_CXX
  19. #include "ClassEnsembleBase.hxx"
  20. namespace GPEC
  21. {
  22. // Construct.
  23. template<class C>
  24. void ClassEnsembleBase<C>::construct()
  25. {
  26. // Read configuration.
  27. Ops::Ops ops(this->configuration_file_);
  28. // Local default ensemble directory.
  29. if (this->container_directory_[0] != '-')
  30. {
  31. if (this->container_directory_[0] != '/')
  32. this->container_directory_ = ClassGPEC::ensemble_directory_
  33. + "/" + this->container_directory_;
  34. #ifdef GPEC_WITH_LOGGER
  35. *(ClassGPEC::log_ptr_) << Fblue() << Info(3) << Reset()
  36. << "Overwrites container directory with \""
  37. << this->container_directory_ << "\"." << endl;
  38. #endif
  39. }
  40. ops.SetPrefix("ensemble.");
  41. if (ops.Exists("parameter"))
  42. {
  43. vector<string> str_vector = ops.GetEntryList("parameter");
  44. for (vector<string>::iterator it = str_vector.begin(); it != str_vector.end(); it++)
  45. parameter_[*it] = ops.Get<real_container>("parameter." + *it);
  46. #ifdef GPEC_WITH_LOGGER
  47. *(ClassGPEC::log_ptr_) << Fmagenta() << Info(3) << Reset()
  48. << "Load global parameters :" << parameter_ << endl;
  49. #endif
  50. }
  51. if (ops.Exists(this->name_))
  52. {
  53. ops.SetPrefix("ensemble." + this->name_ + ".");
  54. if (ops.Exists("parameter"))
  55. {
  56. vector<string> str_vector = ops.GetEntryList("parameter");
  57. for (vector<string>::iterator it = str_vector.begin(); it != str_vector.end(); it++)
  58. parameter_[*it] = ops.Get<real_container>("parameter." + *it);
  59. #ifdef GPEC_WITH_LOGGER
  60. *(ClassGPEC::log_ptr_) << Fmagenta() << Info(3) << Reset()
  61. << "Load local parameters :" << parameter_ << endl;
  62. #endif
  63. }
  64. }
  65. #ifdef GPEC_WITH_LOGGER
  66. else
  67. *(this->log_ptr_) << Bred() << Warning() << Reset() << "Nothing known about ensemble \"" << this->name_
  68. << "\" in ensemble section of configuration file \"" << ClassGPEC::configuration_file_
  69. << "\"." << endl;
  70. #endif
  71. ops.Close();
  72. if (this->container_directory_[0] != '-')
  73. {
  74. make_directory(this->container_directory_);
  75. #ifdef GPEC_WITH_LOGGER
  76. *(ClassGPEC::log_ptr_) << Fyellow() << User(0, "EXPLANATION") << Reset()
  77. << "Create container directory (\"" << this->container_directory_
  78. << "\") for this ensemble if it does not exists (never overwritten)."
  79. << " If you do not want it at all, set it to \"-\"." << endl;
  80. #endif
  81. }
  82. }
  83. // Constructors.
  84. template<class C>
  85. ClassEnsembleBase<C>::ClassEnsembleBase(const string &name)
  86. : ClassPolyContainer<C>(name, "ensemble"), t_begin_(0), t_end_(0), algorithm_("")
  87. {
  88. #ifdef GPEC_WITH_LOGGER
  89. *(ClassGPEC::log_ptr_) << Bcyan() << Fblack() << Info() << Reset() << "Instantiate base ensemble :" << endl;
  90. #endif
  91. construct();
  92. return;
  93. }
  94. // Destructor.
  95. template<class C>
  96. ClassEnsembleBase<C>::~ClassEnsembleBase()
  97. {
  98. return;
  99. }
  100. // Clear.
  101. template<class C>
  102. void ClassEnsembleBase<C>::Clear()
  103. {
  104. ClassPolyContainer<C>::Clear();
  105. parameter_.clear();
  106. ClearWeight();
  107. }
  108. // Add one container.
  109. template<class C>
  110. void ClassEnsembleBase<C>::AddSimulation(const C &simulation, string container_file)
  111. {
  112. if (container_file.empty())
  113. {
  114. ostringstream sout;
  115. sout << this->container_directory_ << "/" << simulation.species_
  116. << "_D" << showpos << int(rint(simulation.GetForecastDayMean()))
  117. << "_" << simulation.GetName() << "_" << simulation.type_
  118. << C::GetFileExtension();
  119. // << "_" << algorithm.Name() << "_" << noshowpos << this->Ncontainer_ << C::GetFileExtension();
  120. container_file = sout.str();
  121. }
  122. ClassPolyContainer<C>::AddContainer(simulation, container_file);
  123. }
  124. // Get methods.
  125. template<class C>
  126. string ClassEnsembleBase<C>::GetAlgorithm() const
  127. {
  128. return algorithm_;
  129. }
  130. template<class C>
  131. int ClassEnsembleBase<C>::GetWeightTimeBegin() const
  132. {
  133. return t_begin_;
  134. }
  135. template<class C>
  136. int ClassEnsembleBase<C>::GetWeightTimeEnd() const
  137. {
  138. return t_end_;
  139. }
  140. template<class C>
  141. real ClassEnsembleBase<C>::GetParameter(const string &name) const
  142. {
  143. typename map<string, real_container>::const_iterator it = parameter_.begin();
  144. while (it != parameter_.end())
  145. if (it->first == name)
  146. break;
  147. else
  148. it++;
  149. return it->second;
  150. }
  151. template<class C>
  152. void ClassEnsembleBase<C>::CollectParameterList(vector<string> &list) const
  153. {
  154. list.clear();
  155. for (typename map<string, real_container>::const_iterator it = parameter_.begin();
  156. it != parameter_.end(); it++)
  157. list.push_back(it->first);
  158. }
  159. template<class C>
  160. void ClassEnsembleBase<C>::CollectWeight(Vector1I &shape, Vector<real> &weight) const
  161. {
  162. shape.Reallocate(3);
  163. shape(0) = t_end_ - t_begin_;
  164. shape(1) = weight_(t_begin_).GetSize();
  165. shape(2) = this->Ncontainer_;
  166. int Nsize = shape(0) * shape(1) * shape(2);
  167. if (Nsize == 0)
  168. return;
  169. weight.Reallocate(Nsize);
  170. weight.Fill(this->bad_value_);
  171. int i(0);
  172. for (int t = t_begin_; t < t_end_; t++)
  173. if (weight_(t).GetSize() > 0)
  174. for (int l = 0; l < weight_(t).GetSize(); l++)
  175. {
  176. if (weight_(t)(l).GetSize() > 0)
  177. for (int j = 0; j < this->container_index_(t).GetSize(); j++)
  178. weight(i + this->container_index_(t)(j)) = weight_(t)(l)(j);
  179. i += this->Ncontainer_;
  180. }
  181. }
  182. template<class C>
  183. void ClassEnsembleBase<C>::CollectWeightTime(const int &t, Vector1I &shape, Vector<real> &weight) const
  184. {
  185. shape.Reallocate(2);
  186. shape(0) = weight_(t).GetSize();
  187. shape(1) = this->Ncontainer_;
  188. int Nsize = shape(0) * shape(1);
  189. if (Nsize == 0)
  190. return;
  191. weight.Reallocate(Nsize);
  192. weight.Fill(this->bad_value_);
  193. int i(0);
  194. for (int l = 0; l < weight_(t).GetSize(); l++)
  195. {
  196. if (weight_(t)(l).GetSize() > 0)
  197. for (int j = 0; j < this->container_index_(t).GetSize(); j++)
  198. weight(i + this->container_index_(t)(j)) = weight_(t)(l)(j);
  199. i += this->Ncontainer_;
  200. }
  201. }
  202. template<class C>
  203. void ClassEnsembleBase<C>::CollectWeightLocation(const int &l, Vector1I &shape, Vector<real> &weight) const
  204. {
  205. check_index(0, weight_location_.GetSize(), l);
  206. shape.Reallocate(2);
  207. shape(0) = t_end_ - t_begin_;
  208. shape(1) = this->Ncontainer_;
  209. int Nsize = shape(0) * shape(1);
  210. if (Nsize == 0)
  211. return;
  212. weight.Reallocate(Nsize);
  213. weight.Fill(this->bad_value_);
  214. int i(0);
  215. for (int t = t_begin_; t < t_end_; t++)
  216. if (weight_(t).GetSize() > 0)
  217. {
  218. if (weight_(t)(l).GetSize() > 0)
  219. for (int j = 0; j < this->container_index_(t).GetSize(); j++)
  220. weight(i + this->container_index_(t)(j)) = weight_(t)(l)(j);
  221. i += this->Ncontainer_;
  222. }
  223. }
  224. template<class C>
  225. void ClassEnsembleBase<C>::CollectLocationWeight(const int &j, Vector<int> &location) const
  226. {
  227. check_index(0, weight_location_.GetSize(), j);
  228. location = weight_location_(j);
  229. }
  230. // Set methods.
  231. template<class C>
  232. void ClassEnsembleBase<C>::SetParameter(const string &name, const real &value)
  233. {
  234. parameter_[name] = value;
  235. }
  236. template<class C>
  237. void ClassEnsembleBase<C>::ReloadParameter()
  238. {
  239. // Read configuration.
  240. Ops::Ops ops(this->configuration_file_);
  241. ops.SetPrefix("ensemble.");
  242. if (ops.Exists("parameter"))
  243. {
  244. vector<string> str_vector = ops.GetEntryList("parameter");
  245. for (vector<string>::iterator it = str_vector.begin(); it != str_vector.end(); it++)
  246. parameter_[*it] = ops.Get<real_container>("parameter." + *it);
  247. }
  248. if (ops.Exists(this->name_))
  249. {
  250. ops.SetPrefix("ensemble." + this->name_ + ".");
  251. if (ops.Exists("parameter"))
  252. {
  253. vector<string> str_vector = ops.GetEntryList("parameter");
  254. for (vector<string>::iterator it = str_vector.begin(); it != str_vector.end(); it++)
  255. parameter_[*it] = ops.Get<real_container>("parameter." + *it);
  256. }
  257. }
  258. ops.Close();
  259. }
  260. template<class C>
  261. void ClassEnsembleBase<C>::SetLocationWeightRaw(const int &j, const Vector<int> &location)
  262. {
  263. check_index(0, weight_location_.GetSize(), j);
  264. weight_location_(j) = location;
  265. }
  266. template<class C>
  267. void ClassEnsembleBase<C>::SetDirectory(const string directory)
  268. {
  269. ClassPolyContainer<C>::SetDirectory(directory, "ensemble");
  270. if (this->container_directory_[0] != '/')
  271. this->container_directory_ = ClassGPEC::ensemble_directory_
  272. + "/" + this->container_directory_;
  273. make_directory(this->container_directory_);
  274. #ifdef GPEC_WITH_LOGGER
  275. *(ClassGPEC::log_ptr_) << Fmagenta() << Info(1) << Reset()
  276. << "Set container directory to \"" << this->container_directory_ << "\"." << endl;
  277. #endif
  278. }
  279. // Read and write weights.
  280. template<class C>
  281. void ClassEnsembleBase<C>::ReadWeight(const string &algorithm, string weight_file, const int rank)
  282. {
  283. if (this->rank_ == rank)
  284. {
  285. if (weight_.GetSize() > 0)
  286. throw GPEC::Error("Weights seems already computed, clear them before.");
  287. algorithm_ = algorithm;
  288. if (weight_file.empty())
  289. weight_file = this->container_directory_ + "/weight_" + this->name_ + "_" + algorithm_ + "_"
  290. + this->container_(0).GetSpecies() + "_" + this->container_(0).GetType() + ".bin";
  291. else if (weight_file[0] != '/')
  292. weight_file = this->container_directory_ + "/" + weight_file;
  293. check_file(weight_file);
  294. string config_file = get_config_file(weight_file);
  295. // Read configuration.
  296. Ops::Ops ops(config_file);
  297. t_begin_ = ops.Get<int>("t_begin");
  298. t_end_ = ops.Get<int>("t_end");
  299. int Nt = ops.Get<int>("Nt");
  300. int Nl = ops.Get<int>("Nlocation");
  301. string algorithm = ops.Get<string>("algorithm");
  302. if (algorithm != algorithm_)
  303. throw GPEC::Error("Weights in file \"" + weight_file +
  304. "\" seem computed with algorithm \"" + algorithm + "\".");
  305. ops.Close();
  306. weight_location_.Reallocate(Nl);
  307. weight_.Reallocate(Nt);
  308. ifstream fin(weight_file.c_str(), ifstream::binary);
  309. for (int j = 0; j < weight_location_.GetSize(); j++)
  310. {
  311. fin.read(reinterpret_cast<char*>(&Nl), sizeof(int));
  312. weight_location_(j).Reallocate(Nl);
  313. fin.read(reinterpret_cast<char*>(weight_location_(j).GetData()), Nl * sizeof(int));
  314. }
  315. for (int t = t_begin_; t < t_end_; t++)
  316. {
  317. weight_(t).Reallocate(weight_location_.GetSize());
  318. for (int j = 0; j < weight_location_.GetSize(); j++)
  319. {
  320. int Ns(0);
  321. fin.read(reinterpret_cast<char*>(&Ns), sizeof(int));
  322. weight_(t)(j).Reallocate(Ns);
  323. fin.read(reinterpret_cast<char*>(weight_(t)(j).GetData()), Ns * sizeof(real_container));
  324. }
  325. }
  326. fin.close();
  327. }
  328. }
  329. template<class C>
  330. void ClassEnsembleBase<C>::WriteWeight(string weight_file, const int rank) const
  331. {
  332. if (this->rank_ == rank)
  333. {
  334. if (weight_.GetSize() == 0)
  335. throw GPEC::Error("Weights not yet computed.");
  336. if (weight_file.empty())
  337. weight_file = this->container_directory_ + "/weight_" + this->name_ + "_" + algorithm_ + "_"
  338. + this->container_(0).GetSpecies() + "_" + this->container_(0).GetType() + ".bin";
  339. else if (weight_file[0] != '/')
  340. weight_file = this->container_directory_ + "/" + weight_file;
  341. string config_file = get_config_file(weight_file);
  342. #ifdef GPEC_WITH_LOGGER
  343. *(this->log_ptr_) << Fyellow() << Info() << Reset() << "Write weights of ensemble \""
  344. << this->name_ << "\" to binary file \"" << weight_file
  345. << "\" with lua configuration file \"" << config_file << "\"." << endl;
  346. #endif
  347. // Write lua configuration.
  348. Ops::Ops ops;
  349. ops.Push("name", this->name_);
  350. ops.Push("Ncontainer", this->Ncontainer_);
  351. ops.Push("t_begin", t_begin_);
  352. ops.Push("t_end", t_end_);
  353. ops.Push("Nt", weight_.GetSize());
  354. ops.Push("Nlocation", weight_location_.GetSize());
  355. ops.Push("algorithm", algorithm_);
  356. typename map<string, real_container>::const_iterator it;
  357. for (it = parameter_.begin(); it != parameter_.end(); it++)
  358. ops.Push("parameter." + it->first, it->second);
  359. ops.WriteLuaDefinition(config_file);
  360. ops.Close();
  361. ofstream fout(weight_file.c_str(), ofstream::binary);
  362. for (int j = 0; j < weight_location_.GetSize(); j++)
  363. {
  364. int Nl = weight_location_(j).GetSize();
  365. fout.write(reinterpret_cast<char*>(&Nl), sizeof(int));
  366. fout.write(reinterpret_cast<char*>(weight_location_(j).GetData()), Nl * sizeof(int));
  367. }
  368. for (int t = t_begin_; t < t_end_; t++)
  369. for (int j = 0; j < weight_(t).GetSize(); j++)
  370. {
  371. int Ns = weight_(t)(j).GetSize();
  372. fout.write(reinterpret_cast<char*>(&Ns), sizeof(int));
  373. fout.write(reinterpret_cast<char*>(weight_(t)(j).GetData()), Ns * sizeof(real_container));
  374. }
  375. fout.close();
  376. }
  377. }
  378. #ifdef GPEC_WITH_MPI
  379. template<class C>
  380. void ClassEnsembleBase<C>::MPI_GatherWeightLocation(const int recv_rank)
  381. {
  382. if (this->rank_ == recv_rank)
  383. {
  384. for (int irank = 0; irank < this->Nrank_; irank++)
  385. if (irank != recv_rank)
  386. {
  387. int nbuf;
  388. MPI::COMM_WORLD.Recv(&nbuf, 1, MPI::INT, irank, 0);
  389. Vector1I ibuf(nbuf);
  390. MPI::COMM_WORLD.Recv(ibuf.GetData(), nbuf, MPI::INT, irank, 1);
  391. int n = weight_location_.GetSize();
  392. weight_location_.Resize(ibuf(0) + n);
  393. int i(1);
  394. for (int j = 0; j < ibuf(0); j++)
  395. {
  396. Vector1I tmp(ibuf(i++));
  397. for (int k = 0; k < tmp.GetSize(); k++)
  398. tmp(k) = ibuf(i++);
  399. weight_location_(j + n) = tmp;
  400. }
  401. MPI::COMM_WORLD.Recv(&nbuf, 1, MPI::INT, irank, 2);
  402. Vector1T rbuf(nbuf);
  403. MPI::COMM_WORLD.Recv(rbuf.GetData(), nbuf, GPEC_MPI_REAL, irank, 3);
  404. for (int t = t_begin_; t < t_end_; t++)
  405. weight_(t).Resize(ibuf(0) + n);
  406. int k(0);
  407. for (int j = 0; j < ibuf(0); j++)
  408. for (int t = t_begin_; t < t_end_; t++)
  409. {
  410. if (ibuf(i) > 0)
  411. {
  412. Vector1T tmp(ibuf(i));
  413. for (int s = 0; s < tmp.GetSize(); s++)
  414. tmp(s) = rbuf(k++);
  415. weight_(t)(j + n) = tmp;
  416. }
  417. i++;
  418. }
  419. }
  420. }
  421. else
  422. {
  423. int nbuf(1);
  424. for (int j = 0; j < weight_location_.GetSize(); j++)
  425. nbuf += (1 + weight_location_(j).GetSize());
  426. nbuf += (t_end_ - t_begin_) * weight_location_.GetSize();
  427. Vector1I ibuf(nbuf);
  428. int i(0);
  429. ibuf(i++) = weight_location_.GetSize();
  430. for (int j = 0; j < weight_location_.GetSize(); j++)
  431. {
  432. ibuf(i++) = weight_location_(j).GetSize();
  433. for (int k = 0; k < weight_location_(j).GetSize(); k++)
  434. ibuf(i++) = weight_location_(j)(k);
  435. }
  436. for (int j = 0; j < weight_location_.GetSize(); j++)
  437. for (int t = t_begin_; t < t_end_; t++)
  438. ibuf(i++) = weight_(t)(j).GetSize();
  439. MPI::COMM_WORLD.Send(&nbuf, 1, MPI::INT, recv_rank, 0);
  440. MPI::COMM_WORLD.Send(ibuf.GetData(), nbuf, MPI::INT, recv_rank, 1);
  441. nbuf = 0;
  442. for (int j = 0; j < weight_location_.GetSize(); j++)
  443. for (int t = t_begin_; t < t_end_; t++)
  444. nbuf += weight_(t)(j).GetSize();
  445. Vector1T rbuf(nbuf);
  446. i = 0;
  447. for (int j = 0; j < weight_location_.GetSize(); j++)
  448. for (int t = t_begin_; t < t_end_; t++)
  449. for (int s = 0; s < weight_(t)(j).GetSize(); s++)
  450. rbuf(i++) = weight_(t)(j)(s);
  451. MPI::COMM_WORLD.Send(&nbuf, 1, MPI::INT, recv_rank, 2);
  452. MPI::COMM_WORLD.Send(rbuf.GetData(), nbuf, GPEC_MPI_REAL, recv_rank, 3);
  453. }
  454. MPI::COMM_WORLD.Barrier();
  455. }
  456. template<class C>
  457. void ClassEnsembleBase<C>::MPI_GatherWeightTime(const int recv_rank)
  458. {
  459. if (this->rank_ == recv_rank)
  460. {
  461. for (int irank = 0; irank < this->Nrank_; irank++)
  462. if (irank != recv_rank)
  463. {
  464. int t_begin, t_end;
  465. MPI::COMM_WORLD.Recv(&t_begin, 1, MPI::INT, irank, 0);
  466. MPI::COMM_WORLD.Recv(&t_end, 1, MPI::INT, irank, 1);
  467. int n = weight_location_.GetSize();
  468. for (int t = t_begin; t < t_end; t++)
  469. weight_(t).Reallocate(n);
  470. int nbuf;
  471. MPI::COMM_WORLD.Recv(&nbuf, 1, MPI::INT, irank, 2);
  472. Vector1I ibuf(nbuf);
  473. MPI::COMM_WORLD.Recv(ibuf.GetData(), nbuf, MPI::INT, irank, 3);
  474. nbuf = Norm1(ibuf);
  475. Vector1T rbuf(nbuf);
  476. MPI::COMM_WORLD.Recv(rbuf.GetData(), nbuf, GPEC_MPI_REAL, irank, 5);
  477. int i(0), k(0);
  478. for (int j = 0; j < n; j++)
  479. for (int t = t_begin; t < t_end; t++)
  480. {
  481. if (ibuf(i) > 0)
  482. {
  483. Vector1T tmp(ibuf(i));
  484. for (int s = 0; s < tmp.GetSize(); s++)
  485. tmp(s) = rbuf(k++);
  486. weight_(t)(j) = tmp;
  487. }
  488. i++;
  489. }
  490. t_begin_ = min<int>(t_begin_, t_begin);
  491. t_end_ = max<int>(t_end_, t_end);
  492. }
  493. }
  494. else
  495. {
  496. MPI::COMM_WORLD.Send(&t_begin_, 1, MPI::INT, recv_rank, 0);
  497. MPI::COMM_WORLD.Send(&t_end_, 1, MPI::INT, recv_rank, 1);
  498. int nbuf = (t_end_ - t_begin_) * weight_location_.GetSize();
  499. Vector1I ibuf(nbuf);
  500. int i(0);
  501. for (int j = 0; j < weight_location_.GetSize(); j++)
  502. for (int t = t_begin_; t < t_end_; t++)
  503. ibuf(i++) = weight_(t)(j).GetSize();
  504. MPI::COMM_WORLD.Send(&nbuf, 1, MPI::INT, recv_rank, 2);
  505. MPI::COMM_WORLD.Send(ibuf.GetData(), nbuf, MPI::INT, recv_rank, 3);
  506. nbuf = Norm1(ibuf);
  507. Vector1T rbuf(nbuf);
  508. i = 0;
  509. for (int j = 0; j < weight_location_.GetSize(); j++)
  510. for (int t = t_begin_; t < t_end_; t++)
  511. for (int s = 0; s < weight_(t)(j).GetSize(); s++)
  512. rbuf(i++) = weight_(t)(j)(s);
  513. MPI::COMM_WORLD.Send(rbuf.GetData(), nbuf, GPEC_MPI_REAL, recv_rank, 5);
  514. }
  515. MPI::COMM_WORLD.Barrier();
  516. }
  517. #endif
  518. // Clear weights.
  519. template<class C>
  520. void ClassEnsembleBase<C>::ClearWeight()
  521. {
  522. algorithm_ = "";
  523. t_begin_ = 0;
  524. t_end_ = 0;
  525. weight_location_.Clear();
  526. weight_.Clear();
  527. }
  528. template<class C>
  529. void ClassEnsembleBase<C>::Aggregate(C &aggregate, string name, string comment, const bool mask_negative_value) const
  530. {
  531. if (weight_.GetSize() == 0)
  532. throw GPEC::Error("Weights not yet computed.");
  533. int Nt = t_end_ - t_begin_;
  534. int Nlocation_local(0);
  535. for (int j = 0; j < weight_location_.GetSize(); j++)
  536. Nlocation_local += weight_location_(j).GetSize();
  537. int Nsize = Nt * Nlocation_local;
  538. Vector1I time(Nsize), location(Nsize);
  539. Vector1T data(Nsize);
  540. data.Zero();
  541. int i(0);
  542. for (int j = 0; j < weight_location_.GetSize(); j++)
  543. {
  544. Vector2I simulation_location(this->container_(0).GetNt());
  545. for (int t = t_begin_; t < t_end_; t++)
  546. simulation_location(t) = weight_location_(j);
  547. Vector3T simulation_data;
  548. this->load_container(weight_location_(j), simulation_location, simulation_data);
  549. for (int l = 0; l < weight_location_(j).GetSize(); l++)
  550. for (int t = t_begin_; t < t_end_; t++)
  551. if (weight_(t).GetSize() > 0)
  552. if (weight_(t)(j).GetSize() > 0)
  553. {
  554. time(i) = t - t_begin_;
  555. location(i) = weight_location_(j)(l);
  556. for (int s = 0; s < weight_(t)(j).GetSize(); s++)
  557. data(i) += simulation_data(t)(l)(s) * weight_(t)(j)(s);
  558. i++;
  559. }
  560. }
  561. time.Resize(i);
  562. location.Resize(i);
  563. data.Resize(i);
  564. aggregate.Set(this->container_(0));
  565. Vector1I forecast;
  566. this->CollectForecastDayMean(forecast, t_begin_, t_end_);
  567. aggregate.template SetData<real_container>(this->container_(0).GetDate(t_begin_),
  568. this->container_(0).GetDate(t_end_),
  569. time,
  570. location,
  571. forecast,
  572. data,
  573. mask_negative_value);
  574. if (name.empty())
  575. name = this->name_ + algorithm_;
  576. if (comment.empty())
  577. comment = "aggregated ensemble \"" + this->name_ + "\" with algorithm \"" + algorithm_ + "\"";
  578. aggregate.SetName(name);
  579. aggregate.AddComment(comment);
  580. #ifdef GPEC_WITH_TIME
  581. #ifdef GPEC_WITH_LOGGER
  582. *(this->log_ptr_) << Byellow() << Fblack() << User(0, "TIME") << Reset()
  583. << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  584. #else
  585. cout << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  586. #endif
  587. load_container_time = clock_t(0);
  588. #endif
  589. }
  590. // Best model.
  591. template<class C>
  592. void ClassEnsembleBase<C>::BestModel(C &best_model)
  593. {
  594. best_model.Clear();
  595. string name = this->name_ + "BestModel";
  596. string comment = "Best model of ensemble \"" + this->name_ + "\"";
  597. Aggregate(best_model, name, comment, true);
  598. }
  599. template<class C>
  600. void ClassEnsembleBase<C>::BestModelIndex(C &best_model_index)
  601. {
  602. int Nt = t_end_ - t_begin_;
  603. int Nlocation_local(0);
  604. for (int j = 0; j < weight_location_.GetSize(); j++)
  605. Nlocation_local += weight_location_(j).GetSize();
  606. int Nsize = Nt * Nlocation_local;
  607. Vector1I time(Nsize), location(Nsize);
  608. Vector1T data(Nsize);
  609. data.Zero();
  610. int i(0);
  611. for (int j = 0; j < weight_location_.GetSize(); j++)
  612. {
  613. Vector2I simulation_location(this->container_(0).GetNt());
  614. for (int t = t_begin_; t < t_end_; t++)
  615. simulation_location(t) = weight_location_(j);
  616. Vector3T simulation_data;
  617. this->load_container(weight_location_(j), simulation_location, simulation_data);
  618. for (int l = 0; l < weight_location_(j).GetSize(); l++)
  619. for (int t = t_begin_; t < t_end_; t++)
  620. if (weight_(t).GetSize() > 0)
  621. if (weight_(t)(j).GetSize() > 0)
  622. {
  623. time(i) = t - t_begin_;
  624. location(i) = weight_location_(j)(l);
  625. int s;
  626. for (s = 0; s < weight_(t)(j).GetSize(); s++)
  627. if (weight_(t)(j)(s) > real_container(0))
  628. break;
  629. data(i) = real_container(this->container_index_(t)(s));
  630. i++;
  631. }
  632. }
  633. time.Resize(i);
  634. location.Resize(i);
  635. data.Resize(i);
  636. best_model_index.Set(this->container_(0));
  637. Vector1I forecast;
  638. this->CollectForecastDayMean(forecast, t_begin_, t_end_);
  639. best_model_index.template SetData<real_container>(this->container_(0).GetDate(t_begin_),
  640. this->container_(0).GetDate(t_end_),
  641. time,
  642. location,
  643. forecast,
  644. data);
  645. best_model_index.SetName(this->name_ + "BestModelIndex");
  646. best_model_index.AddComment("Best model index of ensemble \"" + this->name_ + "\"");
  647. }
  648. // Median.
  649. template<class C>
  650. void ClassEnsembleBase<C>::Median(C &median, int t_begin, int t_end)
  651. {
  652. if (! this->is_loaded_)
  653. throw GPEC::Error("Ensemble not loaded yet.");
  654. algorithm_ = "Median";
  655. median.Clear();
  656. int Nt = this->container_(0).GetNt();
  657. t_begin_ = t_begin;
  658. t_end_ = t_end;
  659. if (t_end_ == 0)
  660. t_end_ = Nt;
  661. weight_.Reallocate(Nt);
  662. for (int t = t_begin_; t < t_end_; t++)
  663. {
  664. weight_(t).Reallocate(1);
  665. int Nsim = this->container_index_(t).GetSize();
  666. if (Nsim > 0)
  667. {
  668. weight_(t)(0).Reallocate(Nsim);
  669. weight_(t)(0).Fill(1 / real_container(Nsim));
  670. }
  671. }
  672. this->set_location_per_rank(this->container_(0).GetNlocation());
  673. weight_location_.Reallocate(1);
  674. weight_location_(0) = this->location_rank_;
  675. string name = this->name_ + "Median";
  676. string comment = "Median of ensemble \"" + this->name_ + "\"";
  677. Aggregate(median, name, comment, true);
  678. }
  679. // Standard deviation.
  680. template<class C>
  681. void ClassEnsembleBase<C>::StandardDeviation(const C &median, C &std) const
  682. {
  683. if (median.GetNt() == 0)
  684. throw GPEC::Error("Median not computed yet.");
  685. std.Clear();
  686. int Nt = median.GetNt();
  687. int Nlocation_local = this->location_rank_.GetSize();
  688. int Nsize = Nt * Nlocation_local;
  689. Vector1I std_time(Nsize), std_location(Nsize);
  690. Vector1T std_data(Nsize);
  691. std_data.Zero();
  692. int i(0);
  693. for (int j = 0; j < this->location_rank_.GetSize(); j++)
  694. {
  695. int loc = this->location_rank_(j);
  696. // Get median data.
  697. Vector1I median_time;
  698. Vector1T median_data;
  699. median.CollectDataLocation(loc, median_time, median_data);
  700. Vector2I simulation_location2(this->container_(0).GetNt());
  701. for (int t = t_begin_; t < t_end_; t++)
  702. simulation_location2(t).PushBack(loc);
  703. Vector1I &simulation_location1 = simulation_location2(t_begin_);
  704. Vector3T simulation_data;
  705. this->load_container(simulation_location1, simulation_location2, simulation_data);
  706. for (int j = 0; j < median_time.GetSize(); j++)
  707. {
  708. int t = median_time(j);
  709. std_time(i) = t;
  710. std_location(i) = loc;
  711. for (int s = 0; s < this->container_index_(t + t_begin_).GetSize(); s++)
  712. {
  713. real_container tmp = simulation_data(t + t_begin_)(0)(s) - median_data(j);
  714. std_data(i) += tmp * tmp;
  715. }
  716. // If median exist for this time, there should be at least one model.
  717. std_data(i) = sqrt(std_data(i) / real_container(this->container_index_(t + t_begin_).GetSize()));
  718. i++;
  719. }
  720. }
  721. std_time.Resize(i);
  722. std_location.Resize(i);
  723. std_data.Resize(i);
  724. std.Set(median);
  725. Vector1I std_forecast(Nt);
  726. for (int t = 0; t < Nt; t++)
  727. std_forecast(t) = median.GetForecastDay(t);
  728. std.template SetData<real_container>(median.GetDateBegin(),
  729. median.GetDateEnd(),
  730. std_time,
  731. std_location,
  732. std_forecast,
  733. std_data);
  734. std.SetName(this->name_ + "Std");
  735. std.AddComment("Standard deviation of ensemble \"" + this->name_ + "\"");
  736. #ifdef GPEC_WITH_TIME
  737. #ifdef GPEC_WITH_LOGGER
  738. *(this->log_ptr_) << Byellow() << Fblack() << User(0, "TIME") << Reset()
  739. << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  740. #else
  741. cout << "load_container_time = " << real_container(load_container_time) / CLOCKS_PER_SEC << endl;
  742. #endif
  743. load_container_time = clock_t(0);
  744. #endif
  745. }
  746. }
  747. #define GPEC_FILE_CLASS_ENSEMBLE_BASE_CXX
  748. #endif