/** Return operand/member at position i. */
ex basic::op(int i) const
{
- return (const_cast<basic *>(this))->let_op(i);
+ throw(std::runtime_error(std::string("op() not implemented by ") + class_name()));
}
/** Return modifyable operand/member at position i. */
ex & basic::let_op(int i)
{
+ ensure_if_modifiable();
throw(std::runtime_error(std::string("let_op() not implemented by ") + class_name()));
}
}
if ($let_op) {
- $LET_OP_IMPLEMENTATION=<<END_OF_LET_OP_IMPLEMENTATION
+ $LET_OP_DEFINITION=<<END_OF_LET_OP_DEFINITION;
+ ex & let_op(int i);
+END_OF_LET_OP_DEFINITION
+
+ $LET_OP_IMPLEMENTATION=<<END_OF_LET_OP_IMPLEMENTATION;
+ex ${CONTAINER}::op(int i) const
+{
+ GINAC_ASSERT(i>=0);
+ GINAC_ASSERT(i<nops());
+
+ ${STLT}::const_iterator it=seq.begin();
+ for (int j=0; j<i; j++) {
+ ++it;
+ }
+ return *it;
+}
+
ex & ${CONTAINER}::let_op(int i)
{
GINAC_ASSERT(i>=0);
GINAC_ASSERT(i<nops());
+ ensure_if_modifiable();
${STLT}::iterator it=seq.begin();
for (int j=0; j<i; j++) {
++it;
}
END_OF_LET_OP_IMPLEMENTATION
} else {
+ $LET_OP_DEFINITION="";
$LET_OP_IMPLEMENTATION="// ${CONTAINER}::let_op() will be implemented by user elsewhere";
}
unsigned precedence(void) const {return 10;}
bool info(unsigned inf) const;
unsigned nops() const;
- ex & let_op(int i);
+ ex op(int i) const;
+${LET_OP_DEFINITION}
ex map(map_function & f) const;
ex eval(int level=0) const;
ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
return overall_coeff;
}
-ex & expairseq::let_op(int i)
-{
- throw(std::logic_error("let_op not defined for expairseq and derived classes (add, mul, ...)"));
-}
-
ex expairseq::map(map_function &f) const
{
epvector *v = new epvector;
bool info(unsigned inf) const;
unsigned nops() const;
ex op(int i) const;
- ex & let_op(int i);
ex map(map_function & f) const;
ex eval(int level=0) const;
ex to_rational(lst &repl_lst) const;
return basic::info(inf);
}
-ex & exprseq::let_op(int i)
+ex exprseq::op(int i) const
{
GINAC_ASSERT(i>=0);
GINAC_ASSERT(i<nops());
-
+
return seq[i];
}
return 1;
}
-ex & idx::let_op(int i)
+ex idx::op(int i) const
{
GINAC_ASSERT(i == 0);
return value;
}
+ex idx::map(map_function & f) const
+{
+ idx *copy = static_cast<idx *>(duplicate());
+ copy->setflag(status_flags::dynallocated);
+ copy->clearflag(status_flags::hash_calculated);
+ copy->value = f(value);
+ return *copy;
+}
+
/** Returns order relation between two indices of the same type. The order
* must be such that dummy indices lie next to each other. */
int idx::compare_same_type(const basic & other) const
void print(const print_context & c, unsigned level = 0) const;
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 evalf(int level = 0) const;
ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
}
/** returns matrix entry at position (i/col, i%col). */
+ex matrix::op(int i) const
+{
+ GINAC_ASSERT(i>=0);
+ GINAC_ASSERT(i<nops());
+
+ return m[i];
+}
+
+/** returns writable matrix entry at position (i/col, i%col). */
ex & matrix::let_op(int i)
{
GINAC_ASSERT(i>=0);
GINAC_ASSERT(i<nops());
+ ensure_if_modifiable();
return m[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;}
{
if (i < 0 || unsigned(i) >= seq.size())
throw (std::out_of_range("op() out of range"));
- return seq[i].rest * power(var - point, seq[i].coeff);
-}
-ex & pseries::let_op(int i)
-{
- throw (std::logic_error("let_op() not defined for pseries"));
+ return seq[i].rest * power(var - point, seq[i].coeff);
}
/** 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);
int degree(const ex &s) const;
int ldegree(const ex &s) const;
ex coeff(const ex &s, int n = 1) const;