Paradiseo-eo sources added
git-svn-id: svn://scm.gforge.inria.fr/svnroot/paradiseo@40 331e1502-861f-0410-8da2-ba01fb791d7f
This commit is contained in:
parent
bc1f453978
commit
c3aec878e5
3609 changed files with 342772 additions and 0 deletions
905
trunk/paradiseo-eo/doc/html/_fun_def_8cpp-source.html
Normal file
905
trunk/paradiseo-eo/doc/html/_fun_def_8cpp-source.html
Normal file
|
|
@ -0,0 +1,905 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>EO: FunDef.cpp Source File</title>
|
||||
<link href="doxygen.css" rel="stylesheet" type="text/css">
|
||||
</head><body>
|
||||
<!-- Generated by Doxygen 1.3.9.1 -->
|
||||
<div class="qindex"> <form class="search" action="search.php" method="get">
|
||||
<a class="qindex" href="main.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="namespaces.html">Namespace List</a> | <a class="qindex" href="hierarchy.html">Class Hierarchy</a> | <a class="qindex" href="classes.html">Alphabetical List</a> | <a class="qindex" href="annotated.html">Class List</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="namespacemembers.html">Namespace Members</a> | <a class="qindex" href="functions.html">Class Members</a> | <a class="qindex" href="pages.html">Related Pages</a> | <span class="search"><u>S</u>earch for <input class="search" type="text" name="query" value="" size="20" accesskey="s"/></span></form></div>
|
||||
<div class="nav">
|
||||
<a class="el" href="dir_000007.html">contrib</a> / <a class="el" href="dir_000008.html">mathsym</a> / <a class="el" href="dir_000022.html">fun</a></div>
|
||||
<h1>FunDef.cpp</h1><div class="fragment"><pre class="fragment">00001 <span class="comment">/* </span>
|
||||
00002 <span class="comment"> * Copyright (C) 2005 Maarten Keijzer</span>
|
||||
00003 <span class="comment"> *</span>
|
||||
00004 <span class="comment"> * This program is free software; you can redistribute it and/or modify</span>
|
||||
00005 <span class="comment"> * it under the terms of version 2 of the GNU General Public License as </span>
|
||||
00006 <span class="comment"> * published by the Free Software Foundation. </span>
|
||||
00007 <span class="comment"> *</span>
|
||||
00008 <span class="comment"> * This program is distributed in the hope that it will be useful,</span>
|
||||
00009 <span class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
|
||||
00010 <span class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span>
|
||||
00011 <span class="comment"> * GNU General Public License for more details.</span>
|
||||
00012 <span class="comment"> *</span>
|
||||
00013 <span class="comment"> * You should have received a copy of the GNU General Public License</span>
|
||||
00014 <span class="comment"> * along with this program; if not, write to the Free Software</span>
|
||||
00015 <span class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</span>
|
||||
00016 <span class="comment"> */</span>
|
||||
00017
|
||||
00018
|
||||
00019 <span class="preprocessor">#include <sstream></span>
|
||||
00020 <span class="preprocessor">#include "Sym.h"</span>
|
||||
00021 <span class="preprocessor">#include "FunDef.h"</span>
|
||||
00022 <span class="preprocessor">#include <LanguageTable.h></span>
|
||||
00023
|
||||
00024 <span class="keyword">using</span> <span class="keyword">namespace </span>std;
|
||||
00025 <span class="keyword">using</span> <span class="keyword">namespace </span>boost::numeric;
|
||||
00026
|
||||
00027 vector<const FunDef*> language;
|
||||
00028
|
||||
00029 token_t add_function(FunDef* function) {
|
||||
00030 language.push_back(function);
|
||||
00031 <span class="keywordflow">return</span> token_t(language.size()-1);
|
||||
00032 }
|
||||
00033
|
||||
00034 <span class="keyword">const</span> FunDef& get_element(token_t token) { <span class="keywordflow">return</span> *language[token]; }
|
||||
00035
|
||||
00036 <span class="comment">/* Printing */</span>
|
||||
00037
|
||||
00038 string c_print(<span class="keyword">const</span> Sym& sym) {
|
||||
00039 <span class="keywordflow">return</span> c_print(sym, vector<string>());
|
||||
00040 }
|
||||
00041
|
||||
00042 string c_print(<span class="keyword">const</span> Sym& sym, <span class="keyword">const</span> vector<string>& vars) {
|
||||
00043 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00044 vector<string> names(args.size());
|
||||
00045 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00046 names[i] = c_print(args[i], vars);
|
||||
00047 }
|
||||
00048 <span class="keywordflow">return</span> language[sym.token()]->c_print(names, vars);
|
||||
00049 }
|
||||
00050
|
||||
00051 <span class="comment">/* Evaluation */</span>
|
||||
00052
|
||||
00053
|
||||
00054 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> Sym& sym, <span class="keyword">const</span> std::vector<double>& inputs) {
|
||||
00055 <span class="keywordflow">return</span> language[sym.token()]->eval(sym.args(), inputs);
|
||||
00056 }
|
||||
00057
|
||||
00058
|
||||
00059 <span class="comment">/* Interval Logic */</span>
|
||||
00060 Interval eval(<span class="keyword">const</span> Sym& sym, <span class="keyword">const</span> vector<Interval>& inputs) {
|
||||
00061 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00062 vector<Interval> interv(args.size());
|
||||
00063 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00064 interv[i] = eval(args[i], inputs);
|
||||
00065
|
||||
00066 <span class="keywordflow">if</span> (!valid(interv[i])) <span class="keywordflow">throw</span> interval_error();
|
||||
00067 }
|
||||
00068 <span class="keywordflow">return</span> language[sym.token()]->eval(interv, inputs);
|
||||
00069 }
|
||||
00070
|
||||
00071 <span class="comment">/* */</span>
|
||||
00072 <span class="keywordtype">void</span> add_function_to_table(LanguageTable& table, token_t token) {
|
||||
00073 <span class="keyword">const</span> FunDef& fundef = *language[token];
|
||||
00074
|
||||
00075 <span class="keywordflow">if</span> (fundef.has_varargs() == <span class="keyword">false</span>) {
|
||||
00076 table.add_function(token, fundef.min_arity());
|
||||
00077 } <span class="keywordflow">else</span> { <span class="comment">// sum or prod (or min or max)</span>
|
||||
00078 table.add_function(token, 2);
|
||||
00079 }
|
||||
00080 }
|
||||
00081
|
||||
00082
|
||||
00083 <span class="comment">// by default it is eager</span>
|
||||
00084 <span class="keywordtype">double</span> FunDef::eval(<span class="keyword">const</span> SymVec& args, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{
|
||||
00085 vector<double> values(args.size());
|
||||
00086 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00087 values[i] = ::eval(args[i], inputs);
|
||||
00088 }
|
||||
00089
|
||||
00090 <span class="keywordflow">return</span> eval(values, inputs);
|
||||
00091 }
|
||||
00092
|
||||
00093 <span class="comment">/* Variable Handling */</span>
|
||||
00094 FunDef* make_var(<span class="keywordtype">int</span> idx); <span class="comment">// defined in FunDefs.h</span>
|
||||
00095 <span class="keyword">static</span> vector<token_t> var_token;
|
||||
00096
|
||||
00097 Sym SymVar(<span class="keywordtype">unsigned</span> idx) {
|
||||
00098 <span class="keywordflow">if</span> (var_token.size() <= idx) {
|
||||
00099 <span class="comment">// it is new</span>
|
||||
00100 var_token.resize(idx+1, token_t(-1));
|
||||
00101 var_token[idx] = add_function( make_var(idx) );
|
||||
00102 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (var_token[idx] == token_t(-1)) {
|
||||
00103 var_token[idx] = add_function( make_var(idx) );
|
||||
00104 }
|
||||
00105 <span class="keywordflow">return</span> Sym(var_token[idx]);
|
||||
00106 }
|
||||
00107
|
||||
00108
|
||||
00109 <span class="comment">/* Constant Handling */</span>
|
||||
00110
|
||||
00111 <span class="keyword">struct </span>HashDouble{
|
||||
00112 size_t operator()(<span class="keywordtype">double</span> val)<span class="keyword"> const </span>{
|
||||
00113 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> h = 0;
|
||||
00114 <span class="keywordtype">char</span>* s = (<span class="keywordtype">char</span>*)&val;
|
||||
00115 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i=0 ; i<<span class="keyword">sizeof</span>(double); ++i)
|
||||
00116 h = 5*h + s[i];
|
||||
00117 <span class="keywordflow">return</span> size_t(h);
|
||||
00118 }
|
||||
00119 };
|
||||
00120
|
||||
00121 <span class="preprocessor">#if USE_TR1</span>
|
||||
00122 <span class="preprocessor"></span><span class="keyword">typedef</span> std::tr1::unordered_map<double, token_t> DoubleSet;
|
||||
00123 <span class="keyword">typedef</span> std::tr1::unordered_map<Sym, token_t> LambdaSet;
|
||||
00124 <span class="preprocessor">#else</span>
|
||||
00125 <span class="preprocessor"></span><span class="keyword">typedef</span> hash_map<double, token_t, HashDouble> DoubleSet;
|
||||
00126 <span class="keyword">typedef</span> hash_map<Sym, token_t, HashSym> LambdaSet;
|
||||
00127 <span class="preprocessor">#endif</span>
|
||||
00128 <span class="preprocessor"></span>
|
||||
00129 <span class="keyword">static</span> DoubleSet doubleSet; <span class="comment">// for quick checking if a constant already exists</span>
|
||||
00130 <span class="keyword">static</span> vector<double> token_value;
|
||||
00131
|
||||
00132 <span class="keyword">static</span> LambdaSet lambdaSet;
|
||||
00133 <span class="keyword">static</span> vector<Sym> token_lambda;
|
||||
00134
|
||||
00135 <span class="keyword">static</span> std::vector<token_t> free_list;
|
||||
00136
|
||||
00137 <span class="keywordtype">void</span> delete_val(token_t token) { <span class="comment">// clean up the information about this value</span>
|
||||
00138
|
||||
00139 <span class="keywordflow">if</span> (is_constant(token)) {
|
||||
00140 <span class="comment">//cout << "Deleting constant token " << token << endl;</span>
|
||||
00141 <span class="keywordtype">double</span> value = token_value[token];
|
||||
00142 doubleSet.erase(value);
|
||||
00143
|
||||
00144 <span class="keyword">delete</span> language[token];
|
||||
00145 language[token] = 0;
|
||||
00146 free_list.push_back(token);
|
||||
00147 }
|
||||
00148 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (is_lambda(token)) {
|
||||
00149 <span class="comment">//cout << "Deleting lambda token " << token << endl;</span>
|
||||
00150
|
||||
00151 Sym expression = token_lambda[token];
|
||||
00152 lambdaSet.erase(expression);
|
||||
00153
|
||||
00154 <span class="keyword">delete</span> language[token];
|
||||
00155 language[token] = 0;
|
||||
00156 free_list.push_back(token);
|
||||
00157 }
|
||||
00158 }
|
||||
00159
|
||||
00160
|
||||
00161 FunDef* make_const(<span class="keywordtype">double</span> value);
|
||||
00162
|
||||
00163 <span class="keywordtype">void</span> extend_free_list();
|
||||
00164
|
||||
00165 Sym SymConst(<span class="keywordtype">double</span> value) {
|
||||
00166
|
||||
00167 DoubleSet::iterator it = doubleSet.find(value);
|
||||
00168
|
||||
00169 <span class="keywordflow">if</span> (it != doubleSet.end()) {
|
||||
00170 <span class="keywordflow">return</span> Sym(it->second); <span class="comment">// already exists</span>
|
||||
00171 }
|
||||
00172
|
||||
00173
|
||||
00174 <span class="keywordflow">if</span> (free_list.empty()) { <span class="comment">// make space for tokens;</span>
|
||||
00175 extend_free_list();
|
||||
00176 }
|
||||
00177
|
||||
00178 token_t token = free_list.back();
|
||||
00179 free_list.pop_back();
|
||||
00180 <span class="comment">//cout << "Creating constant with token " << token << endl; </span>
|
||||
00181 assert(language[token] == 0);
|
||||
00182
|
||||
00183 language[token] = make_const(value);
|
||||
00184
|
||||
00185 doubleSet[value] = token;
|
||||
00186 <span class="keywordflow">if</span> (token_value.size() < token) token_value.resize(token+1);
|
||||
00187 token_value[token] = value;
|
||||
00188
|
||||
00189 <span class="keywordflow">return</span> Sym(token);
|
||||
00190 }
|
||||
00191
|
||||
00192 <span class="comment">/* LanguageTable depends on this one, XXX move somewhere safe.*/</span>
|
||||
00193 <span class="preprocessor">#include <utils/eoRNG.h></span>
|
||||
00194 <span class="keyword">extern</span> Sym default_const() { <span class="keywordflow">return</span> SymConst(rng.<a class="code" href="classeo_rng.html#a7">normal</a>()); }
|
||||
00195
|
||||
00196 <span class="comment">/* The functions */</span>
|
||||
00197 <span class="keyword">namespace </span>{
|
||||
00198
|
||||
00199 <span class="keyword">class </span>Var : <span class="keyword">public</span> FunDef {
|
||||
00200 <span class="keyword">public</span> :
|
||||
00201 <span class="keywordtype">unsigned</span> idx;
|
||||
00202 string default_str;
|
||||
00203
|
||||
00204 Var(<span class="keywordtype">unsigned</span> _idx) : idx(_idx) {
|
||||
00205 ostringstream os;
|
||||
00206 os << <span class="stringliteral">"x["</span> << idx << <span class="charliteral">']'</span>; <span class="comment">// CompiledCode expects this form</span>
|
||||
00207 default_str = os.str();
|
||||
00208 }
|
||||
00209
|
||||
00210 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& _, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> inputs[idx]; }
|
||||
00211 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> SymVec& _, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> inputs[idx]; }
|
||||
00212 string c_print(<span class="keyword">const</span> vector<string>& _, <span class="keyword">const</span> vector<string>& names)<span class="keyword"> const </span>{
|
||||
00213 <span class="keywordflow">if</span> (names.empty()) {
|
||||
00214 <span class="keywordflow">return</span> default_str;
|
||||
00215 }
|
||||
00216 <span class="keywordflow">return</span> names[idx];
|
||||
00217 }
|
||||
00218
|
||||
00219 Interval eval(<span class="keyword">const</span> vector<Interval>& _, <span class="keyword">const</span> vector<Interval>& inputs)<span class="keyword"> const </span>{
|
||||
00220 <span class="keywordflow">return</span> inputs[idx];
|
||||
00221 }
|
||||
00222
|
||||
00223 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 0; }
|
||||
00224
|
||||
00225 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"var"</span>; }
|
||||
00226
|
||||
00227 };
|
||||
00228
|
||||
00229 <span class="keyword">class </span>Const : <span class="keyword">public</span> FunDef {
|
||||
00230 <span class="keyword">public</span>:
|
||||
00231 <span class="keywordtype">double</span> value;
|
||||
00232 string value_str;
|
||||
00233
|
||||
00234 Const(<span class="keywordtype">double</span> _value) : value(_value) {
|
||||
00235 ostringstream os;
|
||||
00236 os.precision(17);
|
||||
00237 os.setf(ios::showpoint);
|
||||
00238 os << <span class="charliteral">'('</span> << value << <span class="charliteral">')'</span>;
|
||||
00239 value_str = os.str();
|
||||
00240 }
|
||||
00241
|
||||
00242
|
||||
00243 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& _, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> value; }
|
||||
00244 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> SymVec& _, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> value; }
|
||||
00245 string c_print(<span class="keyword">const</span> vector<string>& _, <span class="keyword">const</span> vector<string>& names)<span class="keyword"> const </span>{
|
||||
00246 <span class="keywordflow">return</span> value_str;
|
||||
00247 }
|
||||
00248
|
||||
00249 Interval eval(<span class="keyword">const</span> vector<Interval>& _, <span class="keyword">const</span> vector<Interval>& inputs)<span class="keyword"> const </span>{
|
||||
00250 <span class="comment">// Profil/Bias seems to have a problem with 0 * inf when the Interval is exact zero (fpe)</span>
|
||||
00251 <span class="comment">//if (value == 0.0) return Interval(-BiasEpsilon,BiasEpsilon);</span>
|
||||
00252 <span class="keywordflow">return</span> Interval(value);
|
||||
00253 }
|
||||
00254
|
||||
00255 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 0; }
|
||||
00256
|
||||
00257 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"parameter"</span>; }
|
||||
00258 };
|
||||
00259
|
||||
00260 } <span class="comment">// namespace </span>
|
||||
00261
|
||||
00262 <span class="keywordtype">void</span> get_constants(Sym sym, vector<double>& ret) {
|
||||
00263 token_t token = sym.token();
|
||||
00264 <span class="keywordflow">if</span> (is_constant(token)) {
|
||||
00265 <span class="keywordtype">double</span> val = static_cast<const Const*>(language[token])->value;
|
||||
00266 ret.push_back(val);
|
||||
00267 }
|
||||
00268
|
||||
00269 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00270 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00271 get_constants(args[i], ret);
|
||||
00272 }
|
||||
00273
|
||||
00274 }
|
||||
00275
|
||||
00276 <span class="keywordtype">double</span> get_constant_value(token_t token) {
|
||||
00277 <span class="keywordflow">return</span> static_cast<const Const*>(language[token])->value;
|
||||
00278 }
|
||||
00279
|
||||
00281 vector<double> get_constants(Sym sym) {
|
||||
00282 vector<double> retval;
|
||||
00283 get_constants(sym, retval);
|
||||
00284 <span class="keywordflow">return</span> retval;
|
||||
00285 }
|
||||
00286
|
||||
00289 Sym set_constants(Sym sym, vector<double>::const_iterator& it) {
|
||||
00290
|
||||
00291 token_t token = sym.token();
|
||||
00292 <span class="keywordflow">if</span> (is_constant(token)) {
|
||||
00293 <span class="keywordflow">return</span> SymConst(*it++);
|
||||
00294 }
|
||||
00295
|
||||
00296 SymVec args = sym.args();
|
||||
00297 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00298 args[i] = set_constants(args[i], it);
|
||||
00299 }
|
||||
00300
|
||||
00301 <span class="keywordflow">return</span> Sym(token, args);
|
||||
00302 }
|
||||
00303
|
||||
00304 Sym set_constants(Sym sym, <span class="keyword">const</span> vector<double>& constants) {
|
||||
00305 vector<double>::const_iterator it = constants.begin();
|
||||
00306 <span class="keywordflow">return</span> set_constants(sym, it);
|
||||
00307 }
|
||||
00308
|
||||
00309 <span class="comment">// Get functions out, excluding Const and Var</span>
|
||||
00310 vector<const FunDef*> get_defined_functions() {
|
||||
00311 vector<const FunDef*> res;
|
||||
00312 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < language.size(); ++i) {
|
||||
00313 res.push_back(language[i]);
|
||||
00314
|
||||
00315 <span class="keywordflow">if</span> (is_constant(i) || is_variable(i)) {
|
||||
00316 res.back() = 0; <span class="comment">// erase</span>
|
||||
00317 }
|
||||
00318 }
|
||||
00319
|
||||
00320 <span class="keywordflow">return</span> res;
|
||||
00321 }
|
||||
00322
|
||||
00323 FunDef* make_var(<span class="keywordtype">int</span> idx) { <span class="keywordflow">return</span> <span class="keyword">new</span> Var(idx); }
|
||||
00324 FunDef* make_const(<span class="keywordtype">double</span> value) { <span class="keywordflow">return</span> <span class="keyword">new</span> Const(value); }
|
||||
00325
|
||||
00326 <span class="keywordtype">bool</span> is_constant(token_t token) {
|
||||
00327 <span class="keyword">const</span> Const* cnst = dynamic_cast<const Const*>( language[token] );
|
||||
00328 <span class="keywordflow">return</span> cnst != 0;
|
||||
00329 }
|
||||
00330
|
||||
00331 <span class="keywordtype">bool</span> is_variable(token_t token) {
|
||||
00332 <span class="keyword">const</span> Var* var = dynamic_cast<const Var*>( language[token] );
|
||||
00333 <span class="keywordflow">return</span> var != 0;
|
||||
00334 }
|
||||
00335
|
||||
00336 <span class="keywordtype">unsigned</span> get_variable_index(token_t token) {
|
||||
00337 <span class="keyword">const</span> Var* var = static_cast<const Var*>( language[token] );
|
||||
00338 <span class="keywordflow">return</span> var->idx;
|
||||
00339 }
|
||||
00340
|
||||
00341 <span class="keyword">namespace </span>{
|
||||
00342 <span class="keyword">class </span>Lambda : <span class="keyword">public</span> FunDef {
|
||||
00343 <span class="keyword">public</span>:
|
||||
00344 Sym expression;
|
||||
00345 <span class="keywordtype">int</span> arity;
|
||||
00346
|
||||
00347 Lambda(Sym expr, <span class="keywordtype">int</span> arity_) : expression(expr), arity(arity_) {}
|
||||
00348
|
||||
00349 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00350 return ::eval(expression, vals);
|
||||
00351 }
|
||||
00352
|
||||
00353 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00354 <span class="keywordflow">return</span> string(<span class="stringliteral">"/*f*/"</span>) + ::c_print(expression, args) + string(<span class="stringliteral">"/*eof*/"</span>);
|
||||
00355 }
|
||||
00356
|
||||
00357 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& _)<span class="keyword"> const </span>{
|
||||
00358 return ::eval(expression, args);
|
||||
00359 }
|
||||
00360
|
||||
00361 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> arity; }
|
||||
00362 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"F"</span>; }
|
||||
00363
|
||||
00364 };
|
||||
00365 Sym normalize(Sym sym, SymVec& args) {
|
||||
00366 <span class="comment">// check if it's a variable</span>
|
||||
00367 token_t token = sym.token();
|
||||
00368 <span class="keyword">const</span> Var* var = dynamic_cast< const Var*>(language[token]);
|
||||
00369
|
||||
00370 <span class="keywordflow">if</span> (var != 0) {
|
||||
00371 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00372 <span class="keywordflow">if</span> (sym == args[i]) {
|
||||
00373 <span class="keywordflow">return</span> SymVar(i); <span class="comment">// replace with reference to arg</span>
|
||||
00374 }
|
||||
00375 }
|
||||
00376
|
||||
00377 <span class="comment">// not replaced, add it</span>
|
||||
00378 args.push_back(sym);
|
||||
00379 <span class="keywordflow">return</span> SymVar(args.size()-1);
|
||||
00380
|
||||
00381 }
|
||||
00382
|
||||
00383 SymVec a = sym.args();
|
||||
00384 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < a.size(); ++i) {
|
||||
00385 a[i] = normalize(a[i], args);
|
||||
00386 }
|
||||
00387
|
||||
00388 <span class="keywordflow">return</span> Sym(token, a);
|
||||
00389 }
|
||||
00390 }
|
||||
00391
|
||||
00392 <span class="keywordtype">bool</span> is_lambda(token_t token) {
|
||||
00393 <span class="keyword">const</span> Lambda* lambda = dynamic_cast<const Lambda*>( language[token]);
|
||||
00394 <span class="keywordflow">return</span> lambda != 0;
|
||||
00395 }
|
||||
00396
|
||||
00397 std::ostream& print_list(Sym sym, ostream& os) {
|
||||
00398 os << sym.token() << <span class="charliteral">' '</span>;
|
||||
00399
|
||||
00400 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00401 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00402 print_list(args[i], os);
|
||||
00403 }
|
||||
00404 <span class="keywordflow">return</span> os;
|
||||
00405 }
|
||||
00406
|
||||
00407 token_t new_lambda(Sym sym, <span class="keywordtype">int</span> arity) {
|
||||
00408 <span class="comment">// check if already present</span>
|
||||
00409
|
||||
00410 LambdaSet::iterator it = lambdaSet.find(sym);
|
||||
00411 <span class="keywordflow">if</span> (it != lambdaSet.end()) {
|
||||
00412 <span class="keywordflow">return</span> it->second;
|
||||
00413 }
|
||||
00414
|
||||
00415
|
||||
00416 <span class="comment">// new, insert</span>
|
||||
00417 Lambda* lambda = <span class="keyword">new</span> Lambda(sym, arity);
|
||||
00418
|
||||
00419 <span class="keywordflow">if</span> (free_list.empty()) {
|
||||
00420 extend_free_list();
|
||||
00421 }
|
||||
00422
|
||||
00423 token_t token = free_list.back();
|
||||
00424 free_list.pop_back();
|
||||
00425 language[token] = lambda;
|
||||
00426
|
||||
00427 lambdaSet[sym] = token;
|
||||
00428 <span class="keywordflow">if</span> (token_lambda.size() <= token) token_lambda.resize(token+1);
|
||||
00429 token_lambda[token] = sym;
|
||||
00430
|
||||
00431 <span class="keywordflow">return</span> token;
|
||||
00432 }
|
||||
00433
|
||||
00434 <span class="comment">/* Compression */</span>
|
||||
00435 <span class="keyword">typedef</span> hash_map<Sym, unsigned, HashSym> OccMap;
|
||||
00436
|
||||
00437 <span class="keywordtype">void</span> count_occurances(Sym sym, OccMap& occ) {
|
||||
00438 occ[sym]++;
|
||||
00439 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00440 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00441 count_occurances(args[i], occ);
|
||||
00442 }
|
||||
00443 }
|
||||
00444
|
||||
00445 Sym create_lambda(Sym sym, OccMap& occ, <span class="keywordtype">unsigned</span> nvars, vector<Sym>& args) {
|
||||
00446 <span class="keywordtype">unsigned</span> o = occ[sym];
|
||||
00447 <span class="keywordtype">unsigned</span> sz = sym.size();
|
||||
00448
|
||||
00449 <span class="keywordflow">if</span> (o * sz > o + sz + nvars || is_variable(sym.token()) ) {
|
||||
00450 <span class="comment">// check if it's already present</span>
|
||||
00451 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00452 <span class="keywordflow">if</span> (args[i] == sym) {
|
||||
00453 <span class="keywordflow">return</span> SymVar(i);
|
||||
00454 }
|
||||
00455 }
|
||||
00456 <span class="comment">// push_back</span>
|
||||
00457 args.push_back(sym);
|
||||
00458 <span class="keywordflow">return</span> SymVar(args.size()-1);
|
||||
00459 }
|
||||
00460
|
||||
00461 SymVec sym_args = sym.args();
|
||||
00462 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < sym_args.size(); ++i) {
|
||||
00463 sym_args[i] = create_lambda(sym_args[i], occ, nvars, args);
|
||||
00464 }
|
||||
00465
|
||||
00466 <span class="keywordflow">return</span> Sym(sym.token(), sym_args);
|
||||
00467
|
||||
00468 }
|
||||
00469
|
||||
00470 Sym compress(Sym sym) {
|
||||
00471 OccMap occ(sym.size());
|
||||
00472 count_occurances(sym, occ);
|
||||
00473
|
||||
00474 <span class="keywordtype">unsigned</span> nvars = 0;
|
||||
00475 <span class="keywordflow">for</span> (OccMap::iterator it = occ.begin(); it != occ.end(); ++it) {
|
||||
00476 <span class="keywordflow">if</span> (is_variable(it->first.token())) nvars++;
|
||||
00477 }
|
||||
00478
|
||||
00479 SymVec args;
|
||||
00480 Sym body = create_lambda(sym, occ, nvars, args);
|
||||
00481
|
||||
00482
|
||||
00483 <span class="keywordflow">if</span> (body.size() < sym.size()) {
|
||||
00484 <span class="comment">// see if the body can be compressed some more</span>
|
||||
00485 body = compress(body);
|
||||
00486
|
||||
00487 token_t token = new_lambda(body, args.size());
|
||||
00488
|
||||
00489 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00490 args[i] = compress(args[i]);
|
||||
00491 }
|
||||
00492
|
||||
00493 Sym result = Sym(token, args);
|
||||
00494 <span class="keywordflow">return</span> compress(result); <span class="comment">// see if it can be compressed some more</span>
|
||||
00495 }
|
||||
00496
|
||||
00497 <span class="keywordflow">return</span> sym;
|
||||
00498 }
|
||||
00499
|
||||
00500 Sym SymLambda(Sym expr) { <span class="keywordflow">return</span> compress(expr); }
|
||||
00501
|
||||
00502 Sym expand(Sym expr, <span class="keyword">const</span> SymVec& args) {
|
||||
00503
|
||||
00504 <span class="keyword">const</span> Var* var = dynamic_cast<const Var*>( language[expr.token()] );
|
||||
00505 <span class="keywordflow">if</span> (var != 0) {
|
||||
00506 <span class="keywordflow">return</span> args[var->idx];
|
||||
00507 }
|
||||
00508
|
||||
00509 SymVec expr_args = expr.args();
|
||||
00510 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < expr_args.size(); ++i) {
|
||||
00511 expr_args[i] = expand(expr_args[i], args);
|
||||
00512 }
|
||||
00513
|
||||
00514 <span class="keywordflow">return</span> Sym(expr.token(), expr_args);
|
||||
00515 }
|
||||
00516
|
||||
00517 Sym SymUnlambda(Sym sym) {
|
||||
00518 Sym retval = sym;
|
||||
00519 <span class="keyword">const</span> Lambda* lambda = dynamic_cast<const Lambda*>( language[sym.token()] );
|
||||
00520 <span class="keywordflow">if</span> (lambda != 0) {
|
||||
00521 retval = expand(lambda->expression, sym.args());
|
||||
00522 }
|
||||
00523
|
||||
00524 <span class="keywordflow">return</span> retval;
|
||||
00525 }
|
||||
00526
|
||||
00527 Sym expand_all(Sym sym) {
|
||||
00528 SymVec args = sym.args();
|
||||
00529 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00530 args[i] = expand_all(args[i]);
|
||||
00531 }
|
||||
00532
|
||||
00533 Sym nw = SymUnlambda( Sym(sym.token(), args) );
|
||||
00534
|
||||
00535 <span class="keywordflow">if</span> (nw != sym) {
|
||||
00536 nw = expand_all(nw);
|
||||
00537 }
|
||||
00538
|
||||
00539 <span class="keywordflow">return</span> nw;
|
||||
00540 }
|
||||
00541
|
||||
00542 <span class="keyword">namespace </span>{
|
||||
00543
|
||||
00544 <span class="keyword">class </span>Sum : <span class="keyword">public</span> FunDef {
|
||||
00545
|
||||
00546 <span class="keyword">public</span> :
|
||||
00547
|
||||
00548 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00549 <span class="keywordtype">double</span> res = 0;
|
||||
00550 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < vals.size(); ++i) res += vals[i];
|
||||
00551 <span class="keywordflow">return</span> res;
|
||||
00552 }
|
||||
00553
|
||||
00554 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00555 <span class="keywordflow">if</span> (args.empty()) { <span class="keywordflow">return</span> <span class="stringliteral">"0.0"</span>; }
|
||||
00556
|
||||
00557 ostringstream os;
|
||||
00558 os << <span class="stringliteral">"("</span> << args[0];
|
||||
00559 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 1; i < args.size(); ++i) {
|
||||
00560 os << <span class="stringliteral">"+"</span> << args[i];
|
||||
00561 }
|
||||
00562 os << <span class="stringliteral">")"</span>;
|
||||
00563 <span class="keywordflow">return</span> os.str();
|
||||
00564 }
|
||||
00565
|
||||
00566 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& inputs)<span class="keyword"> const </span>{
|
||||
00567 Interval interv(0.0);
|
||||
00568 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00569 interv += args[i];
|
||||
00570 }
|
||||
00571 <span class="keywordflow">return</span> interv;
|
||||
00572 }
|
||||
00573
|
||||
00574 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 0; }
|
||||
00575 <span class="keywordtype">bool</span> has_varargs()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="keyword">true</span>; }
|
||||
00576
|
||||
00577 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"sum"</span>; }
|
||||
00578 };
|
||||
00579
|
||||
00580
|
||||
00581 <span class="keyword">class </span>Prod : <span class="keyword">public</span> FunDef {
|
||||
00582
|
||||
00583 <span class="keyword">public</span> :
|
||||
00584
|
||||
00585 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00586 <span class="keywordtype">double</span> res = 1;
|
||||
00587 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < vals.size(); ++i) res *= vals[i];
|
||||
00588 <span class="keywordflow">return</span> res;
|
||||
00589 }
|
||||
00590
|
||||
00591 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00592 <span class="keywordflow">if</span> (args.empty()) { <span class="keywordflow">return</span> <span class="stringliteral">"1.0"</span>; }
|
||||
00593
|
||||
00594 ostringstream os;
|
||||
00595 os << <span class="stringliteral">"("</span> << args[0];
|
||||
00596 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 1; i < args.size(); ++i) {
|
||||
00597 os << <span class="stringliteral">"*"</span> << args[i];
|
||||
00598 }
|
||||
00599 os << <span class="stringliteral">")"</span>;
|
||||
00600
|
||||
00601 <span class="keywordflow">return</span> os.str();
|
||||
00602 }
|
||||
00603
|
||||
00604 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& inputs)<span class="keyword"> const </span>{
|
||||
00605 Interval interv(1.0);
|
||||
00606 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00607 interv *= args[i];
|
||||
00608 }
|
||||
00609 <span class="keywordflow">return</span> interv;
|
||||
00610 }
|
||||
00611
|
||||
00612 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 0; }
|
||||
00613 <span class="keywordtype">bool</span> has_varargs()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="keyword">true</span>; }
|
||||
00614
|
||||
00615 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"prod"</span>; }
|
||||
00616 };
|
||||
00617
|
||||
00618
|
||||
00619 <span class="keyword">class </span>Power : <span class="keyword">public</span> FunDef {
|
||||
00620 <span class="keyword">public</span> :
|
||||
00621 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00622 <span class="keywordflow">return</span> pow(vals[0], vals[1]);
|
||||
00623 }
|
||||
00624
|
||||
00625 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00626 <span class="keywordflow">return</span> <span class="stringliteral">"pow("</span> + args[0] + <span class="charliteral">','</span> + args[1] + <span class="charliteral">')'</span>;
|
||||
00627 }
|
||||
00628
|
||||
00629 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& _)<span class="keyword"> const </span>{
|
||||
00630 Interval first = args[0];
|
||||
00631 Interval second = args[1];
|
||||
00632 Interval lg = log(first);
|
||||
00633 <span class="keywordflow">if</span> (!valid(lg)) <span class="keywordflow">throw</span> interval_error();
|
||||
00634 <span class="keywordflow">return</span> exp(second * lg);
|
||||
00635 }
|
||||
00636
|
||||
00637 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 2; }
|
||||
00638
|
||||
00639 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"pow"</span>; }
|
||||
00640 };
|
||||
00641
|
||||
00642 <span class="keyword">class </span>IsNeg : <span class="keyword">public</span> FunDef {
|
||||
00643
|
||||
00644 <span class="keyword">public</span>:
|
||||
00645 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00646 <span class="keywordflow">if</span> (vals[0] < 0.0) <span class="keywordflow">return</span> vals[1];
|
||||
00647 <span class="keywordflow">return</span> vals[2];
|
||||
00648 }
|
||||
00649
|
||||
00650 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> Sym& sym, <span class="keyword">const</span> vector<double>& inputs)<span class="keyword"> const </span>{
|
||||
00651 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00652 <span class="keywordtype">double</span> arg0 = ::eval(args[0], inputs);
|
||||
00653 <span class="keywordflow">if</span> (arg0 < 0.0) {
|
||||
00654 return ::eval(args[1], inputs);
|
||||
00655 }
|
||||
00656 return ::eval(args[2], inputs);
|
||||
00657 }
|
||||
00658
|
||||
00659 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00660 <span class="keywordflow">return</span> <span class="stringliteral">"(("</span> + args[0] + <span class="stringliteral">"<0.0)?"</span> + args[1] + <span class="stringliteral">":"</span> + args[2]+<span class="stringliteral">")"</span>;
|
||||
00661 }
|
||||
00662
|
||||
00663 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& _)<span class="keyword"> const </span>{
|
||||
00664 Interval a0 = args[0];
|
||||
00665 <span class="keywordflow">if</span> (a0.upper() < 0.0) <span class="keywordflow">return</span> args[1];
|
||||
00666 <span class="keywordflow">if</span> (a0.lower() >= 0.0) <span class="keywordflow">return</span> args[2];
|
||||
00667
|
||||
00668 <span class="keywordflow">return</span> Interval( std::min(args[1].lower(), args[2].lower()), std::max(args[1].upper(), args[2].upper()));
|
||||
00669 }
|
||||
00670
|
||||
00671 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 3; }
|
||||
00672
|
||||
00673 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"ifltz"</span>; }
|
||||
00674 };
|
||||
00675
|
||||
00676 <span class="keyword">template</span> <<span class="keyword">typename</span> Func>
|
||||
00677 <span class="keyword">class </span>Unary : <span class="keyword">public</span> FunDef {
|
||||
00678
|
||||
00679 Func un;
|
||||
00680
|
||||
00681 <span class="keywordtype">double</span> eval(<span class="keyword">const</span> vector<double>& vals, <span class="keyword">const</span> vector<double>& _)<span class="keyword"> const </span>{
|
||||
00682 <span class="keywordflow">return</span> un(vals[0]);
|
||||
00683 }
|
||||
00684
|
||||
00685 string c_print(<span class="keyword">const</span> vector<string>& args, <span class="keyword">const</span> vector<string>& _)<span class="keyword"> const </span>{
|
||||
00686 <span class="keywordflow">return</span> un(args[0]);
|
||||
00687 }
|
||||
00688
|
||||
00689 Interval eval(<span class="keyword">const</span> vector<Interval>& args, <span class="keyword">const</span> vector<Interval>& _)<span class="keyword"> const </span>{
|
||||
00690 <span class="keywordflow">return</span> un(args[0]);
|
||||
00691 }
|
||||
00692
|
||||
00693 <span class="keywordtype">unsigned</span> min_arity()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 1; }
|
||||
00694
|
||||
00695 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> un.name(); }
|
||||
00696
|
||||
00697 };
|
||||
00698
|
||||
00699 <span class="keyword">struct </span>Inv {
|
||||
00700 <span class="keywordtype">double</span> operator()(<span class="keywordtype">double</span> val)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 1.0 / val; }
|
||||
00701 string operator()(string v)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"(1./"</span> + v + <span class="stringliteral">")"</span>; }
|
||||
00702 Interval operator()(Interval v)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> 1.0 / v; }
|
||||
00703
|
||||
00704 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"inv"</span>; }
|
||||
00705 };
|
||||
00706
|
||||
00707 <span class="keyword">struct </span>Min {
|
||||
00708 <span class="keywordtype">double</span> operator()(<span class="keywordtype">double</span> val)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> -val; }
|
||||
00709 string operator()(string v)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"(-"</span> + v + <span class="stringliteral">")"</span>; }
|
||||
00710 Interval operator()(Interval v)<span class="keyword"> const </span>{ <span class="keywordflow">return</span> -v; }
|
||||
00711
|
||||
00712 string name()<span class="keyword"> const </span>{ <span class="keywordflow">return</span> <span class="stringliteral">"min"</span>; }
|
||||
00713 };
|
||||
00714
|
||||
00715 } <span class="comment">// namespace</span>
|
||||
00716
|
||||
00717 string prototypes = <span class="stringliteral">"double pow(double, double);"</span>;
|
||||
00718 string get_prototypes() { <span class="keywordflow">return</span> prototypes; }
|
||||
00719 <span class="keywordtype">unsigned</span> add_prototype(string str) { prototypes += string(<span class="stringliteral">"double "</span>) + str + <span class="stringliteral">"(double);"</span>; <span class="keywordflow">return</span> prototypes.size(); }
|
||||
00720
|
||||
00721 token_t add_function(FunDef* function, token_t where) {
|
||||
00722 <span class="keywordflow">if</span> (language.size() <= where) language.resize(where+1);
|
||||
00723 language[where] = function;
|
||||
00724 <span class="keywordflow">return</span> 0;
|
||||
00725 }
|
||||
00726
|
||||
00727 <span class="keyword">namespace </span>{
|
||||
00728
|
||||
00729 <span class="preprocessor">#define FUNCDEF(funcname) struct funcname##_struct { \</span>
|
||||
00730 <span class="preprocessor"> double operator()(double val) const { return funcname(val); }\</span>
|
||||
00731 <span class="preprocessor"> string operator()(string val) const { return string(#funcname) + '(' + val + ')'; }\</span>
|
||||
00732 <span class="preprocessor"> Interval operator()(Interval val) const { return funcname(val); }\</span>
|
||||
00733 <span class="preprocessor"> string name() const { return string(#funcname); }\</span>
|
||||
00734 <span class="preprocessor">};\</span>
|
||||
00735 <span class="preprocessor">static const token_t funcname##_token_static = add_function( new Unary<funcname##_struct>, funcname##_token);\</span>
|
||||
00736 <span class="preprocessor">unsigned funcname##_size = add_prototype(#funcname);</span>
|
||||
00737 <span class="preprocessor"></span>
|
||||
00738 <span class="keyword">static</span> token_t ssum_token = add_function( <span class="keyword">new</span> Sum , sum_token);
|
||||
00739 <span class="keyword">static</span> token_t sprod_token = add_function( <span class="keyword">new</span> Prod, prod_token);
|
||||
00740 <span class="keyword">static</span> token_t sinv_token = add_function( <span class="keyword">new</span> Unary<Inv>, inv_token);
|
||||
00741 <span class="keyword">static</span> token_t smin_token = add_function( <span class="keyword">new</span> Unary<Min>, min_token);
|
||||
00742 <span class="keyword">static</span> token_t spow_token = add_function( <span class="keyword">new</span> Power, pow_token);
|
||||
00743 <span class="keyword">static</span> token_t sifltz_token = add_function( <span class="keyword">new</span> IsNeg, ifltz_token);
|
||||
00744
|
||||
00745 FUNCDEF(sin);
|
||||
00746 FUNCDEF(cos);
|
||||
00747 FUNCDEF(tan);
|
||||
00748 FUNCDEF(asin);
|
||||
00749 FUNCDEF(acos);
|
||||
00750 FUNCDEF(atan);
|
||||
00751
|
||||
00752 FUNCDEF(sinh);
|
||||
00753 FUNCDEF(cosh);
|
||||
00754 FUNCDEF(tanh);
|
||||
00755 FUNCDEF(asinh);
|
||||
00756 FUNCDEF(acosh);
|
||||
00757 FUNCDEF(atanh);
|
||||
00758
|
||||
00759 FUNCDEF(exp);
|
||||
00760 FUNCDEF(log);
|
||||
00761 } <span class="comment">// namespace</span>
|
||||
00762
|
||||
00763 <span class="keywordtype">double</span> sqr(<span class="keywordtype">double</span> x) { <span class="keywordflow">return</span> x*x; }
|
||||
00764
|
||||
00765 <span class="keyword">namespace </span>{
|
||||
00766 FUNCDEF(sqr);
|
||||
00767 FUNCDEF(sqrt);
|
||||
00768
|
||||
00769 <span class="keyword">const</span> <span class="keywordtype">int</span> buildInFunctionOffset = language.size();
|
||||
00770 } <span class="comment">// namespace </span>
|
||||
00771
|
||||
00772 <span class="keywordtype">void</span> add_tokens() {
|
||||
00773 <span class="keywordtype">unsigned</span> sz = language.size();
|
||||
00774 language.resize(sz + sz+1); <span class="comment">// double</span>
|
||||
00775
|
||||
00776 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = sz; i < language.size(); ++i) {
|
||||
00777 free_list.push_back(i);
|
||||
00778 }
|
||||
00779 }
|
||||
00780
|
||||
00781 <span class="keywordtype">void</span> extend_free_list() {
|
||||
00782 <span class="comment">// first check if we can clean up unused tokens;</span>
|
||||
00783 <span class="keyword">const</span> vector<unsigned>& refcount = Sym::token_refcount();
|
||||
00784 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = buildInFunctionOffset; i < refcount.size(); ++i) {
|
||||
00785 <span class="keywordflow">if</span> (language[i] == 0) <span class="keywordflow">continue</span>;
|
||||
00786
|
||||
00787 <span class="keywordtype">bool</span> c = is_constant(i);
|
||||
00788 <span class="keywordtype">bool</span> l = is_lambda(i);
|
||||
00789
|
||||
00790 <span class="keywordflow">if</span> (refcount[i] == 0 && (c || l)) {
|
||||
00791
|
||||
00792 <span class="keywordflow">if</span> (c) {
|
||||
00793 doubleSet.erase(token_value[i]);
|
||||
00794 }
|
||||
00795
|
||||
00796 <span class="keywordflow">if</span> (l) {
|
||||
00797 lambdaSet.erase(token_lambda[i]);
|
||||
00798 }
|
||||
00799
|
||||
00800 <span class="keyword">delete</span> language[i];
|
||||
00801 language[i] = 0;
|
||||
00802 free_list.push_back(i);
|
||||
00803 }
|
||||
00804 }
|
||||
00805
|
||||
00806 <span class="comment">// if still empty, add new tokens</span>
|
||||
00807 <span class="keywordflow">if</span> (free_list.empty()) {
|
||||
00808 add_tokens();
|
||||
00809 }
|
||||
00810 }
|
||||
00811
|
||||
00812
|
||||
00813 <span class="comment">/* Serialization */</span>
|
||||
00814 <span class="keywordtype">void</span> write_raw(ostream& os, <span class="keyword">const</span> Sym& sym) {
|
||||
00815 token_t token = sym.token();
|
||||
00816 <span class="keyword">const</span> SymVec& args = sym.args();
|
||||
00817
|
||||
00818 <span class="keywordflow">if</span> (is_constant(token)) {
|
||||
00819 os << <span class="stringliteral">"c"</span> << language[token]->c_print(vector<string>(), vector<string>());
|
||||
00820 } <span class="keywordflow">else</span> {
|
||||
00821
|
||||
00822 <span class="keyword">const</span> Var* var = dynamic_cast<const Var*>( language[token] );
|
||||
00823
|
||||
00824 <span class="keywordflow">if</span> (var != 0) {
|
||||
00825 os << <span class="stringliteral">"v"</span> << var->idx;
|
||||
00826 } <span class="keywordflow">else</span> {
|
||||
00827 os << <span class="stringliteral">"f"</span> << token << <span class="charliteral">' '</span> << args.size();
|
||||
00828 }
|
||||
00829 }
|
||||
00830
|
||||
00831 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < args.size(); ++i) {
|
||||
00832 write_raw(os, args[i]);
|
||||
00833 }
|
||||
00834 }
|
||||
00835
|
||||
00836 string write_raw(<span class="keyword">const</span> Sym& sym) {
|
||||
00837
|
||||
00838 ostringstream os;
|
||||
00839 write_raw(os, sym);
|
||||
00840
|
||||
00841 <span class="keywordflow">return</span> os.str();
|
||||
00842 }
|
||||
00843
|
||||
00844 Sym read_raw(istream& is) {
|
||||
00845 <span class="keywordtype">char</span> <span class="keywordtype">id</span> = is.get();
|
||||
00846
|
||||
00847 <span class="keywordflow">switch</span> (id) {
|
||||
00848 <span class="keywordflow">case</span> <span class="charliteral">'c'</span> :
|
||||
00849 {
|
||||
00850 <span class="keywordtype">double</span> val;
|
||||
00851 is.get(); <span class="comment">// skip '('</span>
|
||||
00852 is >> val;
|
||||
00853 is.get(); <span class="comment">// skip ')'</span>
|
||||
00854 <span class="keywordflow">return</span> SymConst(val);
|
||||
00855 }
|
||||
00856 <span class="keywordflow">case</span> <span class="charliteral">'v'</span> :
|
||||
00857 {
|
||||
00858 <span class="keywordtype">unsigned</span> idx;
|
||||
00859 is >> idx;
|
||||
00860 <span class="keywordflow">return</span> SymVar(idx);
|
||||
00861 }
|
||||
00862 <span class="keywordflow">case</span> <span class="charliteral">'f'</span> :
|
||||
00863 {
|
||||
00864 token_t token;
|
||||
00865 <span class="keywordtype">unsigned</span> arity;
|
||||
00866 is >> token;
|
||||
00867 is >> arity;
|
||||
00868 SymVec args(arity);
|
||||
00869 <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> i = 0; i < arity; ++i) {
|
||||
00870 args[i] = read_raw(is);
|
||||
00871 }
|
||||
00872
|
||||
00873 <span class="keywordflow">return</span> Sym(token, args);
|
||||
00874 }
|
||||
00875 <span class="keywordflow">default</span> : {
|
||||
00876 cerr << <span class="stringliteral">"Character = "</span> << <span class="keywordtype">id</span> << <span class="stringliteral">" Could not read formula from stream"</span> << endl;
|
||||
00877 exit(1);
|
||||
00878 }
|
||||
00879
|
||||
00880 }
|
||||
00881
|
||||
00882 <span class="keywordflow">return</span> Sym();
|
||||
00883 }
|
||||
00884
|
||||
00885 Sym read_raw(string str) {
|
||||
00886 istringstream is(str);
|
||||
00887 <span class="keywordflow">return</span> read_raw(is);
|
||||
00888 }
|
||||
00889
|
||||
00890 <span class="keywordtype">void</span> read_raw(istream& is, Sym& sym) {
|
||||
00891 sym = read_raw(is);
|
||||
00892 }
|
||||
00893
|
||||
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Thu Oct 19 05:06:40 2006 for EO by
|
||||
<a href="http://www.doxygen.org/index.html">
|
||||
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.3.9.1 </small></address>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue