aboutsummaryrefslogtreecommitdiffstats
path: root/models/pow_model.hpp
blob: 2e3b18d58cf16d769a1f2e0aa615e5db53fec8dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef POW_MODEL_H_
#define POW_MODEL_H_
#define OPT_HEADER
#include <core/fitter.hpp>
#include <core/opt_traits.hpp>
#include <cmath>

namespace opt_utilities
{
  template <typename Ty,typename Tx,typename Tp,typename Tstr>
  class pow_model
    :public model<Ty,Tx,Tp,Tstr>
  {
  private:
    model<Ty,Tx,Tp,Tstr>* do_clone()const
    {
      return new pow_model<Ty,Tx,Tp,Tstr>(*this);
    }
  private:
    pow_model()
    {
    }

    const char* do_get_type_name()const
    {
      return "combine two models by power operation";
    }
  private:
    model<Ty,Tx,Tp,Tstr>* pm1;
    typename element_type_trait<Tp>::element_type idx;

  public:
    pow_model(const model<Ty,Tx,Tp,Tstr>& m1,
	      const typename element_type_trait<Tp>::element_type& index)
      :pm1(m1.clone()),idx(index)
    {
      int np1=m1.get_num_params();
      
      for(int i=0;i<np1;++i)
	{
	  param_info<Tp,Tstr> p(m1.get_param_info(i));
	  //param_info<Tp,Tstr> p1(p.get_name(),p.get_value());
	  this->push_param_info(p);
	}
    }

    pow_model(const pow_model& rhs)
      :pm1(NULL),idx(0)
    {
      int np1(0);
      if(rhs.pm1)
	{
	  pm1=rhs.pm1->clone();
	  np1=rhs.pm1->get_num_params();
	  for(int i=0;i<np1;++i)
	    {
	      param_info<Tp,Tstr> p(rhs.pm1->get_param_info(i));
	      param_info<Tp,Tstr> p1(p.get_name()+"1",p.get_value());
	      this->push_param_info(p1);
	    }
	}
      idx=rhs.idx;
    }

    pow_model& operator=(const pow_model& rhs)
    {
      if(this==&rhs)
	{
	  return *this;
	}
      if(!pm1)
	{
	  //delete pm1;
	  pm1->destroy();
	}

      int np1(0);
      if(rhs.pm1)
	{
	  pm1=rhs.pm1->clone();
	  np1=rhs.pm1->get_num_params();
	  for(int i=0;i<np1;++i)
	    {
	      param_info<Tp,Tstr> p(rhs.pm1->get_param_info(i));
	      // param_info<Tp,Tstr> p1(p.get_name()+"1",p.get_value());
	      this->push_param_info(p);
	    }
	}
      idx=rhs.idx;

      return *this;
    }

    ~pow_model()
    {
      if(!pm1)
	{
	  //delete pm1;
	  pm1->destroy();
	}
    }

  public:
    Ty do_eval(const Tx& x,const Tp& param)
    {
      if(!pm1)
	{
	  throw opt_exception("incomplete model!");
	}

      return std::pow(pm1->eval(x,param),idx);
    }
  };
  
  template <typename Ty,typename Tx,typename Tp,typename Tstr>
  pow_model<Ty,Tx,Tp,Tstr> pow(const model<Ty,Tx,Tp,Tstr>& m1,
			       const typename element_type_trait<Tp>::
			       element_type& idx)
  {
    return pow_model<Ty,Tx,Tp,Tstr>(m1,idx);
  }
}



#endif
//EOF