/** Return modifyable operand/member at position i. */
ex & basic::let_op(int i)
{
- throw(std::out_of_range("op() out of range"));
+ throw(std::runtime_error(std::string("let_op() not implemented by ") + class_name()));
}
ex basic::operator[](const ex & index) const
return op(i);
}
+ex & basic::operator[](const ex & index)
+{
+ if (is_exactly_a<numeric>(index))
+ return let_op(ex_to<numeric>(index).to_int());
+
+ throw(std::invalid_argument("non-numeric indices not supported by this type"));
+}
+
+ex & basic::operator[](int i)
+{
+ return let_op(i);
+}
+
/** Test for occurrence of a pattern. An object 'has' a pattern if it matches
* the pattern itself or one of the children 'has' it. As a consequence
* (according to the definition of children) given e=x+y+z, e.has(x) is true
virtual bool info(unsigned inf) const;
virtual unsigned nops() const;
virtual ex op(int i) const;
- virtual ex & let_op(int i);
virtual ex operator[](const ex & index) const;
virtual ex operator[](int i) const;
+ virtual ex & let_op(int i);
+ virtual ex & operator[](const ex & index);
+ virtual ex & operator[](int i);
virtual ex expand(unsigned options = 0) const;
virtual bool has(const ex & other) const;
virtual ex map(map_function & f) const;
// Expand product, if necessary
ex rhs_expanded = rhs.expand();
if (!is_a<ncmul>(rhs_expanded)) {
- srl.let_op(i) = (lhs == canonicalize_clifford(rhs_expanded));
+ srl[i] = (lhs == canonicalize_clifford(rhs_expanded));
continue;
} else if (!is_a<clifford>(rhs.op(0)))
it[0] = save1;
it[1] = save0;
sum -= ncmul(v, true);
- srl.let_op(i) = (lhs == canonicalize_clifford(sum));
+ srl[i] = (lhs == canonicalize_clifford(sum));
goto next_sym;
}
++it;
return any_found;
}
-ex ex::operator[](const ex & index) const
+/** Return modifyable operand/member at position i. */
+ex & ex::let_op(int i)
{
+ makewriteable();
GINAC_ASSERT(bp!=0);
- return (*bp)[index];
+ return bp->let_op(i);
}
-ex ex::operator[](int i) const
+ex & ex::operator[](const ex & index)
{
+ makewriteable();
GINAC_ASSERT(bp!=0);
- return (*bp)[i];
+ return (*bp)[index];
}
-/** Return modifyable operand/member at position i. */
-ex & ex::let_op(int i)
+ex & ex::operator[](int i)
{
makewriteable();
GINAC_ASSERT(bp!=0);
- return bp->let_op(i);
+ return (*bp)[i];
}
/** Left hand side of relational expression. */
ex symmetrize_cyclic(void) const;
ex symmetrize_cyclic(const lst & l) const;
ex eval_ncmul(const exvector & v) const { return bp->eval_ncmul(v); }
- ex operator[](const ex & index) const;
- ex operator[](int i) const;
ex op(int i) const { return bp->op(i); }
+ ex operator[](const ex & index) const { return (*bp)[index]; }
+ ex operator[](int i) const { return (*bp)[i]; }
ex & let_op(int i);
+ ex & operator[](const ex & index);
+ ex & operator[](int i);
ex lhs(void) const;
ex rhs(void) const;
int compare(const ex & other) const;
return overall_coeff;
}
-ex &expairseq::let_op(int i)
+ex & expairseq::let_op(int i)
{
- throw(std::logic_error("let_op not defined for expairseq and derived classes (add,mul,...)"));
+ throw(std::logic_error("let_op not defined for expairseq and derived classes (add, mul, ...)"));
}
ex expairseq::map(map_function &f) const
return row*col;
}
-/** returns matrix entry at position (i/col, i%col). */
-ex matrix::op(int i) const
-{
- return m[i];
-}
-
/** returns matrix entry at position (i/col, i%col). */
ex & matrix::let_op(int i)
{
public:
void print(const print_context & c, unsigned level = 0) const;
unsigned nops() const;
- ex op(int i) const;
ex & let_op(int i);
ex eval(int level=0) const;
ex evalm(void) const {return *this;}
return 2;
}
-ex & power::let_op(int i)
+ex power::op(int i) const
{
GINAC_ASSERT(i>=0);
GINAC_ASSERT(i<2);
unsigned precedence(void) const {return 60;}
bool info(unsigned inf) const;
unsigned nops() const;
- ex & let_op(int i);
+ ex op(int i) const;
ex map(map_function & f) const;
int degree(const ex & s) const;
int ldegree(const ex & s) const;
return seq[i].rest * power(var - point, seq[i].coeff);
}
-ex &pseries::let_op(int i)
+ex & pseries::let_op(int i)
{
- throw (std::logic_error("let_op not defined for pseries"));
+ throw (std::logic_error("let_op() not defined for pseries"));
}
/** Return degree of highest power of the series. This is usually the exponent
unsigned precedence(void) const {return 38;} // for clarity just below add::precedence
unsigned nops(void) const;
ex op(int i) const;
- ex &let_op(int i);
+ ex & let_op(int i);
int degree(const ex &s) const;
int ldegree(const ex &s) const;
ex coeff(const ex &s, int n = 1) const;
return 2;
}
-ex & relational::let_op(int i)
+ex relational::op(int i) const
{
GINAC_ASSERT(i>=0);
GINAC_ASSERT(i<2);
return i==0 ? lh : rh;
}
+ex relational::map(map_function & f) const
+{
+ return (new relational(f(lh), f(rh), o))->setflag(status_flags::dynallocated);
+}
+
ex relational::eval(int level) const
{
if (level==1)
unsigned precedence(void) const {return 20;}
bool info(unsigned inf) const;
unsigned nops() const;
- ex & let_op(int i);
+ ex op(int i) const;
+ ex map(map_function & f) const;
ex eval(int level=0) const;
protected: