improved functors
This commit is contained in:
parent
45be8d1924
commit
f8df6e432f
7 changed files with 152 additions and 28 deletions
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
#include "Func1.h"
|
||||
#include "ctexceptions.h"
|
||||
|
||||
using namespace Cantera;
|
||||
|
||||
#include "Cabinet.h"
|
||||
|
|
@ -50,6 +51,9 @@ extern "C" {
|
|||
"exponent for pow must be supplied");
|
||||
r = new Pow1(params[0]);
|
||||
}
|
||||
else if (type == ConstFuncType) {
|
||||
r = new Const1(params[0]);
|
||||
}
|
||||
else if (type == FourierFuncType) {
|
||||
if (lenp < 2*n + 2)
|
||||
throw CanteraError("func_new",
|
||||
|
|
@ -79,28 +83,35 @@ extern "C" {
|
|||
r = new Periodic1(*_func(n), params[0]);
|
||||
}
|
||||
else if (type == SumFuncType) {
|
||||
r = new Sum1(*_func(n), *_func(m));
|
||||
r = &newSumFunction(_func(n)->duplicate(),
|
||||
_func(m)->duplicate());
|
||||
}
|
||||
else if (type == DiffFuncType) {
|
||||
r = new Diff1(*_func(n), *_func(m));
|
||||
r = &newDiffFunction(_func(n)->duplicate(),
|
||||
_func(m)->duplicate());
|
||||
}
|
||||
else if (type == ProdFuncType) {
|
||||
r = new Product1(*_func(n), *_func(m));
|
||||
r = &newProdFunction(_func(n)->duplicate(),
|
||||
_func(m)->duplicate());
|
||||
}
|
||||
else if (type == RatioFuncType) {
|
||||
r = new Ratio1(*_func(n), *_func(m));
|
||||
r = &newRatioFunction(_func(n)->duplicate(),
|
||||
_func(m)->duplicate());
|
||||
}
|
||||
else if (type == CompositeFuncType) {
|
||||
r = new Composite1(*_func(n), *_func(m));
|
||||
r = &newCompositeFunction(_func(n)->duplicate(),
|
||||
_func(m)->duplicate());
|
||||
}
|
||||
else if (type == TimesConstantFuncType) {
|
||||
r = new TimesConstant1(*_func(n), params[0]);
|
||||
r = &newTimesConstFunction(_func(n)->duplicate(), params[0]);
|
||||
}
|
||||
else if (type == PlusConstantFuncType) {
|
||||
r = new PlusConstant1(*_func(n), params[0]);
|
||||
r = &newPlusConstFunction(_func(n)->duplicate(), params[0]);
|
||||
}
|
||||
else
|
||||
else {
|
||||
throw CanteraError("func_new","unknown function type");
|
||||
r = new Func1();
|
||||
}
|
||||
return Cabinet<func_t>::cabinet()->add(r);
|
||||
}
|
||||
catch (CanteraError) {return -1;}
|
||||
|
|
@ -130,5 +141,23 @@ extern "C" {
|
|||
return Cabinet<func_t>::cabinet()->add(r);
|
||||
}
|
||||
|
||||
int DLL_EXPORT func_duplicate(int i) {
|
||||
func_t* r = 0;
|
||||
r = &_func(i)->duplicate();
|
||||
return Cabinet<func_t>::cabinet()->add(r);
|
||||
}
|
||||
|
||||
int DLL_EXPORT func_write(int i, int lennm, const char* arg, char* nm) {
|
||||
try {
|
||||
string a = string(arg);
|
||||
string w = _func(i)->write(a);
|
||||
int ws = w.size();
|
||||
int lout = (lennm > ws ? ws : lennm);
|
||||
copy(w.c_str(), w.c_str() + lout, nm);
|
||||
nm[lout] = '\0';
|
||||
return 0;
|
||||
}
|
||||
catch (CanteraError) { return -1; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ extern "C" {
|
|||
int DLL_IMPORT func_assign(int i, int j);
|
||||
double DLL_IMPORT func_value(int i, double t);
|
||||
int DLL_IMPORT func_derivative(int i);
|
||||
int DLL_IMPORT func_duplicate(int i);
|
||||
int DLL_EXPORT func_write(int i, int lennm, const char* arg, char* nm);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
"""
|
||||
|
||||
The classes in this module are designed to allow constructing
|
||||
|
|
@ -44,11 +45,14 @@ class Func1:
|
|||
self._typ = typ
|
||||
self.coeffs = asarray(coeffs,'d')
|
||||
self._func_id = _cantera.func_new(typ, n, self.coeffs)
|
||||
|
||||
|
||||
def __del__(self):
|
||||
if self._func_id and self._own:
|
||||
_cantera.func_del(self._func_id)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.write()
|
||||
|
||||
def __call__(self, t):
|
||||
"""Implements function syntax, so that F(t) is equivalent to
|
||||
F.value(t)."""
|
||||
|
|
@ -141,6 +145,10 @@ class Func1:
|
|||
kernel-level object."""
|
||||
return self._func_id
|
||||
|
||||
def write(self, arg = 'x', length = 1000):
|
||||
return _cantera.func_write(self._func_id, length, arg)
|
||||
|
||||
|
||||
class Sin(Func1):
|
||||
def __init__(self,omega=1.0):
|
||||
Func1.__init__(self,100,1,omega)
|
||||
|
|
@ -265,7 +273,7 @@ class Arrhenius(Func1):
|
|||
|
||||
|
||||
|
||||
def Const(value):
|
||||
class Const(Func1):
|
||||
"""Constant function.
|
||||
Objects created by function Const
|
||||
act as functions that have a constant value.
|
||||
|
|
@ -278,7 +286,9 @@ def Const(value):
|
|||
Function Const returns instances of class Polynomial that have
|
||||
degree zero, with the constant term set to the desired value.
|
||||
"""
|
||||
return Polynomial([value])
|
||||
def __init__(self, value):
|
||||
Func1.__init__(self,110,1,value)
|
||||
#return Polynomial([value])
|
||||
|
||||
|
||||
class PeriodicFunction(Func1):
|
||||
|
|
@ -301,6 +311,10 @@ class ComboFunc1(Func1):
|
|||
self._own = 1
|
||||
self._func_id = 0
|
||||
self._typ = typ
|
||||
if type(f1) == types.IntType:
|
||||
f1 = Const(f1)
|
||||
if type(f2) == types.IntType:
|
||||
f2 = Const(f2)
|
||||
self.f1 = f1
|
||||
self.f2 = f2
|
||||
self.f1._own = 0
|
||||
|
|
@ -424,5 +438,6 @@ class DerivativeFunction(Func1):
|
|||
def derivative(f):
|
||||
return DerivativeFunction(f)
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -58,3 +58,25 @@ py_func_value(PyObject *self, PyObject *args)
|
|||
return Py_BuildValue("d",r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static PyObject*
|
||||
py_func_write(PyObject *self, PyObject *args)
|
||||
{
|
||||
int n;
|
||||
char* arg;
|
||||
char* nm;
|
||||
int lennm;
|
||||
if (!PyArg_ParseTuple(args, "iis:func_write", &n, &lennm, &arg))
|
||||
return NULL;
|
||||
nm = new char[lennm+1];
|
||||
int iok = func_write(n, lennm, arg, nm);
|
||||
if (iok < 0) {
|
||||
delete[] nm;
|
||||
return reportError(iok);
|
||||
}
|
||||
PyObject* r = Py_BuildValue("s",nm);
|
||||
delete[] nm;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ static PyMethodDef ct_methods[] = {
|
|||
{"func_derivative", py_func_derivative, METH_VARARGS},
|
||||
{"func_del", py_func_del, METH_VARARGS},
|
||||
{"func_value", py_func_value, METH_VARARGS},
|
||||
{"func_write", py_func_write, METH_VARARGS},
|
||||
|
||||
{"mix_new", py_mix_new, METH_VARARGS},
|
||||
{"mix_del", py_mix_del, METH_VARARGS},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@ using namespace std;
|
|||
|
||||
namespace Cantera {
|
||||
|
||||
static Func1* checkDupl(Func1& f) {
|
||||
if (f.parent() != 0)
|
||||
return &f.duplicate();
|
||||
else
|
||||
return &f;
|
||||
}
|
||||
|
||||
Func1& Sin1::derivative() const {
|
||||
Func1* c = new Cos1(m_c);
|
||||
return *(new TimesConstant1(*c, m_c));
|
||||
|
|
@ -37,19 +44,42 @@ namespace Cantera {
|
|||
string Sin1::write(string arg) const {
|
||||
string c = "";
|
||||
if (m_c != 1.0) c = fp2str(m_c);
|
||||
return "\\sin{"+c+arg+"}";
|
||||
return "\\sin("+c+arg+")";
|
||||
}
|
||||
|
||||
string Cos1::write(string arg) const {
|
||||
string c = "";
|
||||
if (m_c != 1.0) c = fp2str(m_c);
|
||||
return "\\cos{"+c+arg+"}";
|
||||
return "\\cos("+c+arg+")";
|
||||
}
|
||||
|
||||
string Pow1::write(string arg) const {
|
||||
string c = "";
|
||||
if (m_c == 0.5) {
|
||||
return "\\sqrt{" + arg + "}";
|
||||
}
|
||||
if (m_c == -0.5) {
|
||||
return "\\frac{1}{\\sqrt{" + arg + "}}";
|
||||
}
|
||||
if (m_c != 1.0) {
|
||||
c = fp2str(m_c);
|
||||
return "\\left("+arg+"\\right)^{"+c+"}";
|
||||
}
|
||||
else {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
string Exp1::write(string arg) const {
|
||||
string c = "";
|
||||
if (m_c != 1.0) c = fp2str(m_c);
|
||||
return "\\exp{"+c+arg+"}";
|
||||
return "\\exp("+c+arg+")";
|
||||
}
|
||||
|
||||
string Const1::write(string arg) const {
|
||||
string c = "";
|
||||
c = fp2str(m_c);
|
||||
return c;
|
||||
}
|
||||
|
||||
string Ratio1::write(string arg) const {
|
||||
|
|
@ -59,9 +89,9 @@ namespace Cantera {
|
|||
|
||||
string Product1::write(string arg) const {
|
||||
string s = m_f1->write(arg);
|
||||
if (m_f1->order() < order()) s = "(" + s + ")";
|
||||
if (m_f1->order() < order()) s = "\\left(" + s + "\\right)";
|
||||
string s2 = m_f2->write(arg);
|
||||
if (m_f2->order() < order()) s2 = "(" + s2 + ")";
|
||||
if (m_f2->order() < order()) s2 = "\\left(" + s2 + "\\right)";
|
||||
return s + " " + s2;
|
||||
}
|
||||
|
||||
|
|
@ -86,9 +116,12 @@ namespace Cantera {
|
|||
|
||||
string TimesConstant1::write(string arg) const {
|
||||
string s = m_f1->write(arg);
|
||||
if (m_f1->order() < order()) s = "(" + s + ")";
|
||||
if (m_f1->order() < order()) s = "\\left(" + s + "\\right)";
|
||||
if (m_c == 1.0) return s;
|
||||
if (m_c == -1.0) return "-"+s;
|
||||
char n = s[0];
|
||||
if (n >= '0' && n <= '9')
|
||||
s = "\\left(" + s + "\\right)";
|
||||
return fp2str(m_c) + s;
|
||||
}
|
||||
|
||||
|
|
@ -128,6 +161,8 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
Func1& newSumFunction(Func1& f1, Func1& f2) {
|
||||
if (f1.isIdentical(f2))
|
||||
return newTimesConstFunction(f1, 2.0);
|
||||
if (isZero(f1)) {
|
||||
delete &f1;
|
||||
return f2;
|
||||
|
|
@ -138,8 +173,11 @@ namespace Cantera {
|
|||
}
|
||||
doublereal c = f1.isProportional(f2);
|
||||
if (c != 0) {
|
||||
if (c == -1.0) return *(new Const1(0.0));
|
||||
else return newTimesConstFunction(f1, c + 1.0);
|
||||
if (c == -1.0)
|
||||
return *(new Const1(0.0));
|
||||
else {
|
||||
return newTimesConstFunction(f1, c + 1.0);
|
||||
}
|
||||
}
|
||||
return *(new Sum1(f1, f2));
|
||||
}
|
||||
|
|
@ -189,7 +227,7 @@ namespace Cantera {
|
|||
}
|
||||
else ff2 = &f2;
|
||||
Func1& p = newProdFunction(*ff1, *ff2);
|
||||
cout << "p = " << p.write("t") << endl;
|
||||
//cout << "p = " << p.write("t") << endl;
|
||||
|
||||
if (c1*c2 != 1.0) {
|
||||
return newTimesConstFunction(p, c1*c2);
|
||||
|
|
@ -227,6 +265,10 @@ namespace Cantera {
|
|||
if (c == 1.0) {
|
||||
return f;
|
||||
}
|
||||
if (f.ID() == TimesConstantFuncType) {
|
||||
f.setC(f.c() * c);
|
||||
return f;
|
||||
}
|
||||
return *(new TimesConstant1(f, c));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ namespace Cantera {
|
|||
*/
|
||||
class Func1 {
|
||||
public:
|
||||
Func1() : m_c(0.0), m_f1(0), m_f2(0) {}
|
||||
Func1() : m_c(0.0), m_f1(0), m_f2(0), m_parent(0) {}
|
||||
virtual ~Func1() {}
|
||||
virtual int ID() const { return 0; }
|
||||
|
||||
|
|
@ -68,7 +68,8 @@ namespace Cantera {
|
|||
virtual doublereal eval(doublereal t) const { return 0.0; }
|
||||
|
||||
virtual Func1& derivative() const {
|
||||
cout << "ERR: ID = " << ID() << endl;
|
||||
cout << "derivative error... ERR: ID = " << ID() << endl;
|
||||
cout << write("x") << endl;
|
||||
return *(new Func1);
|
||||
}
|
||||
|
||||
|
|
@ -92,15 +93,20 @@ namespace Cantera {
|
|||
virtual std::string write(std::string arg) const;
|
||||
|
||||
doublereal c() const { return m_c; }
|
||||
void setC(doublereal c) { m_c = c; }
|
||||
Func1& func1() { return *m_f1; }
|
||||
Func1& func2() { return *m_f2; }
|
||||
virtual int order() const { return 3; }
|
||||
Func1& func1_dup() const { return m_f1->duplicate(); }
|
||||
Func1& func2_dup() const { return m_f2->duplicate(); }
|
||||
Func1* parent() { return m_parent; }
|
||||
void setParent(Func1* p) { m_parent = p; }
|
||||
|
||||
protected:
|
||||
doublereal m_c;
|
||||
Func1 *m_f1, *m_f2;
|
||||
Func1* m_parent;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
@ -173,6 +179,7 @@ namespace Cantera {
|
|||
public:
|
||||
Pow1(doublereal n) {m_c = n;}
|
||||
virtual ~Pow1() {}
|
||||
virtual std::string write(std::string arg) const;
|
||||
virtual int ID() const { return PowFuncType; }
|
||||
virtual Func1& duplicate() { return *(new Pow1(m_c)); }
|
||||
virtual doublereal eval(doublereal t) const {
|
||||
|
|
@ -193,11 +200,13 @@ namespace Cantera {
|
|||
m_c = A;
|
||||
}
|
||||
virtual ~Const1() {}
|
||||
virtual std::string write(std::string arg) const;
|
||||
virtual int ID() const { return ConstFuncType; }
|
||||
virtual doublereal eval(doublereal t) const {
|
||||
return m_c;
|
||||
}
|
||||
virtual Func1& derivative() {
|
||||
virtual Func1& duplicate() { return *(new Const1(m_c)); }
|
||||
virtual Func1& derivative() const {
|
||||
Func1* z = new Const1(0.0);
|
||||
return *z;
|
||||
}
|
||||
|
|
@ -215,6 +224,10 @@ namespace Cantera {
|
|||
Sum1(Func1& f1, Func1& f2) {
|
||||
m_f1 = &f1;
|
||||
m_f2 = &f2;
|
||||
if (m_f1 == m_f2)
|
||||
cout << "Same functions!" << endl;
|
||||
m_f1->setParent(this);
|
||||
m_f2->setParent(this);
|
||||
}
|
||||
virtual ~Sum1() {
|
||||
delete m_f1;
|
||||
|
|
@ -230,7 +243,7 @@ namespace Cantera {
|
|||
Func1& dup = newSumFunction(f1d, f2d);
|
||||
return dup;
|
||||
}
|
||||
virtual Func1& derivative() {
|
||||
virtual Func1& derivative() const {
|
||||
Func1& d1 = m_f1->derivative();
|
||||
Func1& d2 = m_f2->derivative();
|
||||
Func1& d = newSumFunction(d1, d2);
|
||||
|
|
@ -287,7 +300,7 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
virtual ~Product1() {
|
||||
cout << "In Product1 destructor, deleting" << m_f1 << " " << m_f2 << endl;
|
||||
//cout << "In Product1 destructor, deleting" << m_f1 << " " << m_f2 << endl;
|
||||
delete m_f1;
|
||||
delete m_f2;
|
||||
}
|
||||
|
|
@ -366,7 +379,7 @@ namespace Cantera {
|
|||
}
|
||||
|
||||
virtual ~PlusConstant1() {
|
||||
cout << "PlusConstant1: deleting " << m_f1 << endl;
|
||||
//cout << "PlusConstant1: deleting " << m_f1 << endl;
|
||||
delete m_f1;
|
||||
}
|
||||
virtual int ID() const { return PlusConstantFuncType; }
|
||||
|
|
@ -400,7 +413,7 @@ namespace Cantera {
|
|||
m_f2 = &f2;
|
||||
}
|
||||
virtual ~Ratio1() {
|
||||
cout << "Ratio1: deleting " << m_f1 << " " << m_f2 << endl;
|
||||
//cout << "Ratio1: deleting " << m_f1 << " " << m_f2 << endl;
|
||||
delete m_f1;
|
||||
delete m_f2;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue