diff --git a/pub/src/expr.cpp b/pub/src/expr.cpp index 31e6ffb78b28c8dc582ce77b9d21f95cc8370386..8c0c076911bd14be8ac83cf5f3aa29f528807c8b 100644 --- a/pub/src/expr.cpp +++ b/pub/src/expr.cpp @@ -27,7 +27,7 @@ extern bool allow_slow_conv; // TODO unify parameter treatment #define DEBUG 0 //***************************************************************************// -//* class CContext *// +//* CContext *// //***************************************************************************// //! Constructor. Set k,j,i, checking validity. Set other par's to default. @@ -111,7 +111,7 @@ string CContext::context_info() const //***************************************************************************// -//* class CResult *// +//* CResult *// //***************************************************************************// //! Introspection, for debugging. @@ -127,20 +127,20 @@ string CResult::result_info() const //***************************************************************************// -//* class CRef (references like y[k,j,0] or p3[2] or ...) *// +//* CRef (references like y[k,j,0] or p3[2] or ...) *// //***************************************************************************// //! Description of reference (for use in ??) void CRef::set_coord( CCoord& ret, uint k_in ) const { - if ( typ == _K ) { + if ( var.typ == CVariable::_K ) { ret = CCoord("k",""); return; - } else if ( typ == _J ) { + } else if ( var.typ == CVariable::_J ) { ret = CCoord("j",""); return; - } else if ( typ == _I ) { + } else if ( var.typ == CVariable::_I ) { ret = CCoord("i",""); return; } @@ -161,56 +161,77 @@ void CRef::set_coord( CCoord& ret, uint k_in ) const if (!f) throw "set_coord: ref where not refering to a file"; - if ( typ == _Z ) { - if (num>=f->ZCo.size()) - throw "set_coord: z" + strg(num) + " undefined"; - ret = f->ZCo[num]; - } else if ( typ == _R ) { - if (num>=f->RPar.size()) - throw "set_coord: r" + strg(num) + " undefined"; - ret = f->RPar[num].Co; - } else if ( typ == _NJ ) { + if ( var.typ == CVariable::_Z ) { + if (var.num>=f->ZCo.size()) + throw "set_coord: z" + strg(var.num) + " undefined"; + ret = f->ZCo[var.num]; + } else if ( var.typ == CVariable::_R ) { + if (var.num>=f->RPar.size()) + throw "set_coord: r" + strg(var.num) + " undefined"; + ret = f->RPar[var.num].Co; + } else if ( var.typ == CVariable::_NJ ) { ret = CCoord("#spectra", ""); } else { POld fd = P2D( f ); POlc fc = P2C( f ); if ( fd ) { - if ( typ == _X ) + if ( var.typ == CVariable::_X ) ret = fd->xco; - else if ( typ == _Y ) + else if ( var.typ == CVariable::_Y ) ret = fd->yco; - else if ( typ == _DY ) + else if ( var.typ == CVariable::_DY ) ret = CCoord( "d"+fd->yco.name, fd->yco.unit ); - else if ( typ == _NI ) + else if ( var.typ == CVariable::_NI ) ret = CCoord("#points", ""); else - throw "reference " + var_info() + " not allowed in data file"; + throw "reference " + var.var_info() + + " not allowed in data file"; } else if ( fc ) { - if ( typ == _CP ) { - if( num>=fc->nPar() ) - throw "invalid reference p" + strg(num); - ret = fc->PCo[num]; - } else if ( typ == _CQ ) - ret = CCoord("cq"+strg(num), ""); // fit quality indicator - else if ( typ == _C ) + if ( var.typ == CVariable::_CP ) { + if( var.num>=fc->nPar() ) + throw "invalid reference p" + strg(var.num); + ret = fc->PCo[var.num]; + } else if ( var.typ == CVariable::_CQ ) + ret = CCoord("cq"+strg(var.num), ""); // fit quality indicator + else if ( var.typ == CVariable::_C ) ret = CCoord(fc->expr,""); else - throw "reference " + var_info() + " not allowed in curve file"; + throw "reference " + var.var_info() + + " not allowed in curve file"; } else throw "BUG: ref->set_coord unexpected else"; } } +string CRef::ref_info() const +{ + string out = "ref: "; + if ( tk ) + out += "tk[" + tk->tree_info() + "], "; + else + out += "tk=0, "; + if ( tj ) + out += "tj[" + tj->tree_info() + "], "; + else + out += "tj=0, "; + if ( ti ) + out += "ti[" + ti->tree_info() + "]"; + else + out += "ti=0"; + return out; +} + //***************************************************************************// -//* CRef / evaluation *// +//* CRef: evaluation *// //***************************************************************************// //! Evaluate reference in given context. Result returned in ret. void CRef::ref_val( CResult& ret, const CContext& ctx ) const { - if ( (typ==_I || typ==_J || typ==_K) && ( ti || tj || tk ) ) + if ( (var.typ == CVariable::_I || var.typ == CVariable::_J || + var.typ == CVariable::_K) && ( ti || tj || tk ) ) throw "invalid cross reference: index cannot be indexed"; // Get k from context: @@ -219,7 +240,7 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const if ( tk ) { tk->tree_val( tmp, ctx ); if ( tmp.vectorial ) { - if ( typ==_K ) { + if ( var.typ == CVariable::_K ) { ret.preset_v( ctx.nv ); for( uint i=0; i<ctx.nv; ++i ) ret.v[i] = tmp.v[i]; @@ -237,7 +258,7 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const throw "index k=" + strg(k) + " out of bounds"; // Return k-dependent reference (unless already done above): - if ( typ == _K ) { + if ( var.typ == CVariable::_K ) { ret.set_r( k ); return; } @@ -245,13 +266,13 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const // Proceed with file reference f[k]: POlo f = NOlm::MOM[k]; - if ( typ==_NJ ) { + if ( var.typ == CVariable::_NJ ) { ret.set_r( f->nJ() ); return; - } else if ( typ==_R ) { - if ( num>= f->RPar.size() ) - throw "invalid reference " + var_info(); - ret.set_r( f->RPar[num].val ); + } else if ( var.typ == CVariable::_R ) { + if ( var.num>= f->RPar.size() ) + throw "invalid reference " + var.var_info(); + ret.set_r( f->RPar[var.num].val ); return; } @@ -260,20 +281,20 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const if ( tj ) { tj->tree_val( tmp, ctx ); if ( tmp.vectorial ) { - if ( typ==_J ) { + if ( var.typ == CVariable::_J ) { ret.preset_v( ctx.nv ); for( uint i=0; i<ctx.nv; ++i ) ret.v[i] = tmp.v[i]; return; - } else if ( typ==_Z ) { - if ( num>= f->nZ() ) - throw "invalid reference " + var_info(); + } else if ( var.typ == CVariable::_Z ) { + if ( var.num>= f->nZ() ) + throw "invalid reference " + var.var_info(); ret.preset_v( ctx.nv ); for( uint i=0; i<ctx.nv; ++i ) { j = (uint)( tmp.v[i]+0.5 ); if( j>=f->V.size() ) throw "j out of bounds"; - ret.v[i] = f->V[j]->z[num]; + ret.v[i] = f->V[j]->z[var.num]; } return; } else @@ -289,13 +310,13 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const throw "index j=" + strg(j) + " out of bounds"; // Return k-j-dependent reference (unless done above): - if ( typ == _J ) { + if ( var.typ == CVariable::_J ) { ret.set_r( ctx.j ); return; - } else if ( typ == _Z ) { - if ( num>= f->nZ() ) - throw "invalid reference " + var_info(); - ret.set_r( f->V[j]->z[num] ); + } else if ( var.typ == CVariable::_Z ) { + if ( var.num>= f->nZ() ) + throw "invalid reference " + var.var_info(); + ret.set_r( f->V[j]->z[var.num] ); return; } @@ -303,8 +324,8 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const POld fd = P2D( f ); if ( fd ) { PSpec sj = fd->VS(j); - if ( typ==_I || typ == _X || typ == _Y || typ == _DY ) { - if ( typ==_DY && !sj->dy.size() ) + if ( var.pointwise() ) { + if ( var.typ == CVariable::_DY && !sj->dy.size() ) throw string( "dy not set" ); if ( ctx.dim==CContext::_1 ) { uint i; @@ -318,15 +339,15 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const if( i>= sj->size() ) throw "i=" + strg(i) + " exceeds scan size" + strg(sj->size()); - if ( typ == _I ) { + if ( var.typ == CVariable::_I ) { ret.set_r( i ); - } else if ( typ == _X ) { + } else if ( var.typ == CVariable::_X ) { ret.set_r( sj->x[i] ); - } else if ( typ == _Y ) { + } else if ( var.typ == CVariable::_Y ) { ret.set_r( sj->y[i] ); if ( ctx.want_error && sj->dy.size() ) ret.dr = sj->dy[i]; - } else if ( typ == _DY ) { + } else if ( var.typ == CVariable::_DY ) { ret.set_r( sj->dy[i] ); } } else if ( ctx.dim==CContext::_VI ) { @@ -334,7 +355,8 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const CContext myctx = ctx; myctx.dim = CContext::_1; ret.preset_v( ctx.nv ); - if ( typ==_Y && ctx.want_error && sj->dy.size() ) + if ( var.typ == CVariable::_Y && ctx.want_error && + sj->dy.size() ) ret.dv.resize( ctx.nv ); for( uint ii=0; ii<ctx.nv; ++ii ){ myctx.i = ii; @@ -343,43 +365,43 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const if( i >= sj->size() ) throw "i=" + strg(i) + " exceeds scan size" + strg(sj->size()); - if ( typ == _I ) { + if ( var.typ == CVariable::_I ) { ret.v[ii] = i; - } else if ( typ == _X ) { + } else if ( var.typ == CVariable::_X ) { ret.v[ii] = sj->x[i]; - } else if ( typ == _Y ) { + } else if ( var.typ == CVariable::_Y ) { ret.v[ii] = sj->y[i]; if ( ret.dv.size() ) ret.dv[ii] = sj->dy[i]; - } else if ( typ == _DY ) { + } else if ( var.typ == CVariable::_DY ) { ret.v[ii] = sj->dy[i]; } } } else { if ( ctx.nv != sj->size() ) - throw "ref_val " + var_info() + ": requested vec(" + + throw "ref_val " + var.var_info() + ": requested vec(" + strg(ctx.nv) + "), found vec(" + strg( sj->size() ); - if ( typ == _I ) { + if ( var.typ == CVariable::_I ) { ret.preset_v( ctx.nv ); for( uint i=0; i<ctx.nv; ++i ) ret.v[i] = i; - } else if ( typ == _X ) { + } else if ( var.typ == CVariable::_X ) { ret.set_v( sj->x ); - } else if ( typ == _Y ) { + } else if ( var.typ == CVariable::_Y ) { ret.set_v( sj->y ); if ( ctx.want_error ) ret.dv = sj->dy; - } else if ( typ == _DY ) { + } else if ( var.typ == CVariable::_DY ) { ret.set_v( sj->dy ); } } } else throw string( "BUG: invalid context::dim" ); - } else if ( typ == _NI ) { + } else if ( var.typ == CVariable::_NI ) { ret.set_r( sj->size() ); } else - throw "invalid ref(" + var_info() + ") in data file"; + throw "invalid ref(" + var.var_info() + ") in data file"; return; } @@ -387,38 +409,20 @@ void CRef::ref_val( CResult& ret, const CContext& ctx ) const POlc fc = P2C( f ); if ( fc ) { PCurve cj = fc->VC(j); - if ( typ == _CP ) { - if ( num>= fc->nPar() ) - throw "invalid p ref(" + var_info() + ") in curve file"; - ret.set_r( cj->P[num] ); - } else if ( typ == _CQ ) { - if ( num >= CCurve::mQuality ) - throw "invalid fm ref(" + var_info() + ") in curve file"; - ret.set_r( cj->Quality[num] ); + if ( var.typ == CVariable::_CP ) { + if ( var.num>= fc->nPar() ) + throw "invalid p ref(" + var.var_info() + ") in curve file"; + ret.set_r( cj->P[var.num] ); + } else if ( var.typ == CVariable::_CQ ) { + if ( var.num >= CCurve::mQuality ) + throw "invalid fm ref(" + var.var_info() + ") in curve file"; + ret.set_r( cj->Quality[var.num] ); } else - throw "invalid ref(" + var_info() + ") in curve file"; + throw "invalid ref(" + var.var_info() + ") in curve file"; return; } } -string CRef::ref_info() const -{ - string out = "ref: "; - if ( tk ) - out += "tk[" + tk->tree_info() + "], "; - else - out += "tk=0, "; - if ( tj ) - out += "tj[" + tj->tree_info() + "], "; - else - out += "tj=0, "; - if ( ti ) - out += "ti[" + ti->tree_info() + "]"; - else - out += "ti=0"; - return out; -} - //***************************************************************************// //* CTree: status requests *// @@ -433,7 +437,6 @@ uint CTree::npar() const return np; } - //! Does the result depend on k? bool CTree::k_dependent() const @@ -733,8 +736,8 @@ CNodeIva::CNodeIva( PRef& _ref ) void CNodeIva::npar_exec( uint *np ) const { - if ( ref->typ==CRef::_CP ) - *np = max( *np, ref->num+1 ); + if ( ref->var.typ == CVariable::_CP ) + *np = max( *np, ref->var.num+1 ); } //***************************************************************************// diff --git a/pub/src/expr.h b/pub/src/expr.h index 5afe5caf106f47f256d93199816c4a3395cdf32f..e233d33fc56e3f65aa7b71c0cc9ec00e9e401994 100644 --- a/pub/src/expr.h +++ b/pub/src/expr.h @@ -64,13 +64,14 @@ class CResult { //! References to data points, indices, ...; used as endpoints of CTree's. -class CRef: public CVariable { +class CRef { public: + CVariable var; PTree tk; PTree tj; PTree ti; - CRef( const string s="" ) : CVariable(s) {}; + CRef( const string s="" ) : var(s) {}; void ref_val( CResult& ret, const CContext& ctx ) const; void set_coord( CCoord& ret, uint k ) const; diff --git a/pub/src/node.h b/pub/src/node.h index 918c5df1f785ca2a23d1e3ebd6ac3832e6a02aec..4cfda5225b96421e7592fc92862fdad525b83c72 100644 --- a/pub/src/node.h +++ b/pub/src/node.h @@ -57,7 +57,7 @@ class CNodeIva: public CTree { void kdep_exec( bool *kd ) const { *kd = true; } void set_coord( CCoord& ret, uint k ) const { ref->set_coord( ret, k ); } - string tree_info() const { return "ref[" + ref->var_info() + "]"; } + string tree_info() const { return "ref[" + ref->var.var_info() + "]"; } }; @@ -105,7 +105,7 @@ class CNodeCev: public CTree { void tree_val( CResult& ret, const CContext& ctx ) const; bool has_dummy() const { return arg->has_dummy(); } void set_coord( CCoord& ret, uint k ) const; - string tree_info() const { return "c[" + ref->var_info() + "]"; } + string tree_info() const { return "c[" + ref->var.var_info() + "]"; } };