#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"
#ifdef __cplusplus
}
#endif
#include "Expression.h"
#include "Evaluator.h"
MODULE = Math::SymbolicX::FastEvaluator PACKAGE = Math::SymbolicX::FastEvaluator
FastEval::Evaluator *
FastEval::Evaluator::new()
void
FastEval::Evaluator::DESTROY()
double
FastEval::Evaluator::Evaluate(expr, ...)
FastEval::Expression* expr
PREINIT:
SV* values=NULL;
unsigned int pnum, nvars;
bool isUndef = false;
int i;
double* cvalues;
SV **item;
AV* array;
INIT:
if( items > 2 )
values = ST(2);
else
isUndef = true;
if ( isUndef || !SvOK(values) )
isUndef = true;
else if ( !(SvRV(values) && SvTYPE(SvRV(values)) == SVt_PVAV) )
croak("Reference to an array expected as second argument");
nvars = expr->GetNVars();
if ( nvars != 0 && isUndef )
croak("No parameters (variable values) passed to Evaluate(expr, ...), but the expression contains variables!");
CODE:
if (isUndef)
RETVAL = THIS->Evaluate(expr, NULL); /* kinda asking for trouble, ain't I */
else {
array = (AV*) SvRV(values);
pnum = av_len(array)+1;
if ( pnum != nvars )
croak("Number of parameters passed to Evaluate(expr, ...) does not match the number of variables in the expressiom!");
cvalues = (double*)safemalloc( pnum * sizeof( double ) );
for (i = 0; i < pnum; ++i) {
if ((item = av_fetch(array, i, 0)) && SvOK(*item))
cvalues[i] = SvNV(*item);
else {
safefree((char*)cvalues);
croak("Value not defined or not a double");
}
}
RETVAL = THIS->Evaluate(expr, cvalues);
safefree((char*)cvalues);
}
OUTPUT:
RETVAL
MODULE = Math::SymbolicX::FastEvaluator PACKAGE = Math::SymbolicX::FastEvaluator::Expression
FastEval::Expression*
FastEval::Expression::new()
void
FastEval::Expression::DESTROY()
void
FastEval::Expression::AddOp(op)
FastEval::op_t* op
CODE:
THIS->AddOp(op);
void
FastEval::Expression::SetNVars(nvars)
int nvars
CODE:
THIS->SetNVars((unsigned int)nvars);
unsigned int
FastEval::Expression::GetNVars()
CODE:
RETVAL = THIS->GetNVars();
OUTPUT:
RETVAL
# void SetOps(const unsigned int nops, const op_t* ops);
# void SetOps(const std::vector<op_t>& ops) {fOps = ops;}
# unsigned int GetNOps() const {return fOps.size();}
# const op_t* GetOps() const {return &fOps.front();}
double
FastEval::Expression::Evaluate(...)
PREINIT:
/* FIXME this whole mess is a duplication of the Evaluator::Evaluate method. Not good */
SV* values=NULL;
unsigned int pnum, nvars;
bool isUndef = false;
int i;
double* cvalues;
SV **item;
AV* array;
FastEval::Evaluator eval;
INIT:
if( items > 1 )
values = ST(1);
else
isUndef = true;
if ( isUndef || !SvOK(values) )
isUndef = true;
else if ( !(SvRV(values) && SvTYPE(SvRV(values)) == SVt_PVAV) )
croak("Reference to an array expected as argument to Evaluate");
nvars = THIS->GetNVars();
if ( nvars != 0 && isUndef )
croak("No parameters (variable values) passed to Evaluate(...), but the expression contains variables!");
CODE:
if (isUndef)
RETVAL = eval.Evaluate(THIS, NULL); /* kinda asking for trouble, ain't I */
else {
array = (AV*) SvRV(values);
pnum = av_len(array)+1;
if ( pnum != nvars )
croak("Number of parameters passed to Evaluate(...) does not match the number of variables in the expressiom!");
cvalues = (double*)safemalloc( pnum * sizeof( double ) );
for (i = 0; i < pnum; ++i) {
if ((item = av_fetch(array, i, 0)) && SvOK(*item))
cvalues[i] = SvNV(*item);
else {
safefree((char*)cvalues);
croak("Value not defined or not a double");
}
}
RETVAL = eval.Evaluate(THIS, cvalues);
safefree((char*)cvalues);
}
OUTPUT:
RETVAL
MODULE = Math::SymbolicX::FastEvaluator PACKAGE = Math::SymbolicX::FastEvaluator::Op
FastEval::op_t *
new(CLASS)
char *CLASS
CODE:
RETVAL = (FastEval::op_t*)safemalloc( sizeof( FastEval::op_t) );
if( RETVAL == NULL ){
warn("unable to allocate FastEval::op_t");
XSRETURN_UNDEF;
}
OUTPUT:
RETVAL
void
DESTROY(self)
FastEval::op_t* self
CODE:
safefree( (char*)self );
void
SetValue(op,val)
FastEval::op_t *op
double val
CODE:
op->content = val;
void
SetOpType(op,type)
FastEval::op_t *op
unsigned char type
CODE:
op->type = type+2; /* +2 since Math::Symbolic doesn't have the number and var enums */
void
SetVariable(op)
FastEval::op_t *op
CODE:
op->type = FastEval::eVariable;
void
SetNumber(op)
FastEval::op_t *op
CODE:
op->type = FastEval::eNumber;