1 /*!
2  * \file tfel-check/src/Column.cxx
3  *
4  *  Created on: 23 mai 2013
5  *      Author: rp238441
6  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
7  * reserved.
8  * This project is publicly released under either the GNU GPL Licence
9  * or the CECILL-A licence. A copy of thoses licences are delivered
10  * with the sources of TFEL. CEA or EDF may also distribute this
11  * project under specific licensing conditions.
12  */
13 
14 #include<sstream>
15 #include<stdexcept>
16 #include<algorithm>
17 #include"TFEL/Raise.hxx"
18 #include"TFEL/Math/Evaluator.hxx"
19 #include"TFEL/Check/Column.hxx"
20 
21 namespace tfel{
22 
23   namespace check{
24 
25     static std::vector<double>
eval(const tfel::utilities::TextData & d,const std::string & f)26     eval(const tfel::utilities::TextData& d,
27 	 const std::string& f){
28       struct Variable{
29 	unsigned short p;
30 	std::vector<double>  values;
31       };
32       auto matches=[](const std::string& vn){
33 	if(vn.size()<2){
34 	  return false;
35 	}
36 	if(vn[0]!='$'){
37 	  return false;
38 	}
39 	auto p = std::begin(vn)+1;
40 	for(;p!=vn.end();++p){
41 	  const char c = *p;
42 	  if(!((c>='0')&&(c<='9'))){
43 	    return false;
44 	  }
45 	}
46 	return true;
47       };
48       auto convert = [](const std::string& vn){
49 	auto p = std::begin(vn)+1;
50 	unsigned short value{0};
51 	for(;p!=vn.end();++p){
52 	  const char c = *p;
53 	  raise_if(!((c>='0')&&(c<='9')),
54 		   "tfel::check::eval::convert: "
55 		   "invalid input '"+vn+"'");
56 	  value*=10;
57 	  value+=c-'0';
58 	}
59 	return value;
60       };
61       tfel::math::Evaluator e{f};
62       std::vector<Variable> variables;
63       unsigned short p = 0u;
64       for(const auto& v : e.getVariablesNames()){
65 	raise_if(!matches(v),"tfel::check::eval: undeclared "
66 		 "variable '"+v+"'");
67 	variables.push_back(Variable{p,d.getColumn(convert(v))});
68 	++p;
69       }
70       if(variables.empty()){
71 	return d.getColumn(convert(f));
72       }
73       std::vector<double> r;
74       r.resize(variables[0].values.size());
75       for(std::vector<double>::size_type i=0;i!=r.size();++i){
76 	for(const auto& v:variables){
77 	  e.setVariableValue(v.p,v.values[i]);
78 	}
79 	r[i] = e.getValue();
80       }
81       return r;
82     } // end of eval
83 
84     Column::Column(Column&&) = default;
85     Column::Column(const Column&)  = default;
86     Column& Column::operator=(Column&&)  = default;
87     Column& Column::operator=(const Column&)  = default;
88 
Column(const int n)89     Column::Column(const int n)
90       : num(n),
91 	byName(false) {
92       this->name = std::to_string(this->num);
93     }
94 
Column(std::string n)95     Column::Column(std::string n)
96       : name(std::move(n)),
97 	num(0),
98 	byName(true)
99     {}
100 
getName() const101     std::string Column::getName() const {
102       return this->name;
103     }
104 
getValues()105     const std::vector<double>& Column::getValues() {
106       return this->values;
107     }
clearValues()108     void Column::clearValues() {
109       this->values.clear();
110     }
111 
resizeValues(std::vector<double>::size_type size)112     void Column::resizeValues(std::vector<double>::size_type size) {
113       this->values.resize(size);
114     }
115 
setValue(unsigned pos,double value)116     void Column::setValue(unsigned pos, double value) {
117       this->values.at(pos) = value;
118     }
119 
setFilename(std::string file)120     void Column::setFilename(std::string file) {
121       this->f = file;
122       this->data = std::make_shared<tfel::utilities::TextData>(file,"alcyone");
123       if (this->byName) {
124 	const auto& l = data->getLegends();
125 	if(std::find(l.begin(),l.end(),this->name)!=l.end()){
126 	  this->num = data->findColumn(name);
127 	  this->values = this->data->getColumn(this->num);
128 	} else {
129 	  this->values = eval(*(this->data),this->name);
130 	  return;
131 	}
132       } else {
133 	this->data->getColumn(this->values, this->num);
134       }
135     }
136 
getFilename() const137     const std::string& Column::getFilename() const {
138       return this->f;
139     }
140 
141     const std::shared_ptr<tfel::utilities::TextData>
getData() const142     Column::getData() const {
143       return this->data;
144     }
145 
146     Column::~Column() = default;
147 
148   } // end of namespace check
149 
150 } // end of namespace tfel
151