C ++使用类来推广exp

时间:2014-07-17 14:04:13

标签: c++ class math

我正在建立一个处理数学表达式的类系统,它将采用表达式并对其进行评估或区分它(这可能是大多数人在学习c ++时所做的基本练习)。

因此,有一个主要课程expression,以及子课程additionmultiplicationconstantvariablepower。每个函数都有2个函数evaluate()differentiate(),它们处理变量/指针的流程。

#include <memory>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <sstream>

namespace course {

class expression;
typedef shared_ptr<expression> exptr;
using std::pow;
static exptr pow(exptr b, double e);

class power: public expression {
public:
    power(exptr b, double e): m_b(b), m_e(e) {}
    double evaluate(double x) const final {
        return pow(m_b->evaluate(x), m_e);
    }
    exptr derivative() const final {
        return pow(m_b, m_e - 1) * m_b->derivative() * con(m_e);
    }
private:
    exptr m_b;
    double m_e;
};

static exptr pow(exptr b, double e) {
    auto c = dynamic_pointer_cast<constant>(b);
    if(c) return con(pow(c->value(), e));
    if(e == 0) return con(1);
    if(e == 1) return b;
    return make_shared<power>(b, e); }

.... etc
}

现在这个工作正常(和所有其他类一样)但是我想引入一个指数类和相应的函数,这看起来像是一个简单的幂化概括:

using std::exp;
static exptr exp(exptr e);

class epower: public expression {
public:
    epower(exptr e): m_e(e) {}
    double evaluate(double x) const final {
        return exp(m_e->evaluate(x));
    }
    exptr derivative() const final {
        return exp(m_e) * m_e->derivative();
    }
private:
    exptr m_e;
};

static exptr exp(exptr e) {
    auto c = dynamic_pointer_cast<constant>(e);
    if(c) return con(exp(c->value()));
    if(c->value() == 0) return con(1);
    return make_shared<epower>(e); 
}

所以这些类和函数都在命名空间课程中。但是,编译器会抱怨命名空间中不存在exptr exp(exptr),但exptr pow(exptr,double)会这样做。我在这里缺少的函数pow()exp()之间是否有一些基本的区别,或者我搞砸了命名空间? main中的相关代码如下:

int main() {

    using namespace std;
    using namespace course;

    exptr e1 = pow(con(3.0),2.0); //This is fine
    exptr e2 = exp(con(3.0)); //This is not fine

    return 0;
}

欢迎任何帮助!

编辑:所以看起来你们想要为自己编译一些代码。

#include "DFT.h"
int main() {
using namespace std;
using namespace course;

exptr e, de;
int nvf = 1;
double yy =2.0*M_PI/3.0;
double fv = pow(1.5,3);

if (nvf==1) {
e = con(1.0);
de = e->derivative();
};
if (nvf==2) {
e = con(1.0) + var() * con(-fv);
de = e->derivative();
};
if (nvf==3) {
e = pow(con(1.0) + var() * con(-fv), yy );
de = e->derivative();
};
if (nvf==4) {
//Here is the offending function
//            e = exp(con(3.0));
    de = e->derivative();
};
double x = 1.0;
cout << e->evaluate(x) << endl;
cout << de->evaluate(x) << endl;
return 0;
}

标题文件:

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <memory>
#include <cmath>
#include <stdlib.h>

namespace course
{
using std::pow;
using std::shared_ptr;
using std::make_shared;
using std::dynamic_pointer_cast;
using std::exp;

class expression;
typedef shared_ptr<expression> exptr;
static exptr operator+(exptr e1, exptr e2);
static exptr operator*(exptr e1, exptr e2);
static exptr pow(exptr b,double e);
static exptr exp(exptr e);

class expression {
public:
virtual ~expression() {};
virtual double evaluate(double x) const = 0;
virtual exptr derivative() const = 0;
};

class constant: public expression {
public:
constant (double c) : m_con(c) {}
double evaluate(double x) const final {return m_con;}
exptr derivative() const final {return make_shared<constant>(0);}  
double value() const { return m_con; }
private:
double m_con;
};

static inline exptr con(double c) {
return make_shared<constant>(c); }

class variable: public expression {
public:
double evaluate(double x) const final {return x;}
exptr derivative() const final {return con(1);}  
};

static inline exptr var() {
return make_shared<variable>(); }

class addition: public expression {
public:
addition(exptr e1,exptr e2) :m_e1(e1), m_e2(e2) {}
double evaluate(double x) const final {
return m_e1->evaluate(x)+m_e2->evaluate(x);}
exptr derivative() const final {
return m_e1->derivative() + m_e2->derivative();}
private:
exptr m_e1, m_e2;
};

static exptr operator+(exptr e1, exptr e2) {
auto c1 = dynamic_pointer_cast<constant>(e1);
auto c2 = dynamic_pointer_cast<constant>(e2);
if(c1) {
    if(c2) return con(c1->value() + c2->value());
    if(!c1->value()) return e2; }
if(c2 && !c2->value()) return e1;
return make_shared<addition>(e1, e2); }

class multiplication: public expression {
public:
multiplication(exptr e1,exptr e2) :m_e1(e1), m_e2(e2) {}
double evaluate(double x) const final {
return m_e1->evaluate(x)*m_e2->evaluate(x);}
exptr derivative() const final {
return m_e1->derivative()*m_e2 + m_e1*m_e2->derivative();}
private:
exptr m_e1, m_e2;
};   

static exptr operator*(exptr e1, exptr e2) {
auto c1 = dynamic_pointer_cast<constant>(e1);
auto c2 = dynamic_pointer_cast<constant>(e2);
if(c1) {
    if(c2) return con(c1->value() * c2->value());
    if(c1->value() == 0) return e1;
    if(c1->value() == 1) return e2; }
if(c2) {
    if(c2->value() == 0) return e2;
    if(c2->value() == 1) return e1; }
if(e1 == e2) return pow(e1, 2);
return make_shared<multiplication>(e1, e2); }

class power: public expression {
public:
    power(exptr b, double e): m_b(b), m_e(e) {}
double evaluate(double x) const final {
    return pow(m_b->evaluate(x), m_e);}
exptr derivative() const final {
    return pow(m_b, m_e - 1) * m_b->derivative() * con(m_e);}
private:
exptr m_b;
double m_e;
};

static exptr pow(exptr b, double e) {
auto c = dynamic_pointer_cast<constant>(b);
if(c) return con(pow(c->value(), e));
if(e == 0) return con(1);
if(e == 1) return b;
return make_shared<power>(b, e); }

class epower: public expression {
public:
    epower(exptr e): m_e(e) {}
double evaluate(double x) const final {
  return exp(m_e->evaluate(x));}
exptr derivative() const final {
    return exp(m_e) * m_e->derivative();}
private:
exptr m_e;
};

static exptr exp(exptr e) {
auto c = dynamic_pointer_cast<constant>(e);
if(c) return con(exp(c->value()));
if(c->value() == 0) return con(1);
return make_shared<epower>(e); }

}

因此,如果您编译并运行它,您将看到它正常工作。当您从main中删除评论时,它将开始抱怨exp函数。

0 个答案:

没有答案