aboutsummaryrefslogtreecommitdiffstats
path: root/models/pow_model.hpp
blob: 43b93b72c94430a4c56d08f4c5b2511774eeb116 (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
128
129
130
131
132
133
134
135
/**
   \file pow_model.hpp
   \brief combing two model by power operation
   \author Junhua Gu
 */



#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