Program Listing for File monomial.hpp¶
↰ Return to documentation for file (ellip/monomial.hpp)
#ifndef _MONOMIAL_HPP
#define _MONOMIAL_HPP
#include <cassert>
#include <initializer_list>
#include <valarray>
template <typename _Tp>
class monomial
{
using Vec = std::valarray<_Tp>;
using _Self = monomial<_Tp>;
public:
explicit monomial(size_t n)
: _b(_Tp(0))
, _a(_Tp(0), n)
{
}
monomial(const _Tp& c, const Vec& a)
: _b(log(c))
, _a(a)
{
}
monomial(const _Tp& c, std::initializer_list<_Tp> lst)
: _b(log(c))
, _a(lst)
{
}
monomial(size_t n, const _Tp& c)
: _b(log(c))
, _a(_Tp(0), n)
{
}
template <typename _Up, class Map>
monomial(const monomial<_Up>& mon, const Map& polarity);
monomial(size_t n, const _Tp ar[])
: _b(log(ar[0]))
, _a(_Tp(0), n)
{
for (auto i = 1; i <= n; ++i)
_a[i - 1] = ar[i];
}
~monomial() { }
_Self& operator*=(const _Self& M)
{
_a += M._a;
_b += M._b;
return *this;
}
_Self& operator/=(const _Self& M)
{
_a -= M._a;
_b -= M._b;
return *this;
}
_Self& operator*=(const _Tp& c)
{
_b += log(c);
return *this;
}
_Self& operator/=(const _Tp& c)
{
_b -= log(c);
return *this;
}
_Self operator*(const _Tp& c) const
{
return _Self(*this) *= c;
}
_Self operator/(const _Tp& c) const
{
return _Self(*this) /= c;
}
void sqrt()
{
_a /= 2.;
_b /= 2.;
}
template <typename _Up>
_Tp lse(const std::valarray<_Up>& y) const
{
_Tp res = _b;
for (auto i = 0; i != _a.size(); ++i)
{
if (_a[i] == _Tp(0))
continue;
res += _a[i] * y[i];
}
return res;
}
template <typename _Up>
Vec lse_gradient(const _Up&) const
{
return _a;
}
template <typename _Up>
_Tp log_exp_fvalue_with_gradient(const _Up& y, Vec& g) const
{
assert(_a.size() == y.size());
_Tp res = _b;
for (auto i = 0; i != _a.size(); ++i)
{
if (_a[i] == _Tp(0))
continue;
res += _a[i] * y[i];
}
g = _a; // gradient
return res;
}
template <typename _Up>
Vec lse_gradient(const _Up& y, _Tp& f) const
{
assert(_a.size() == y.size());
f = lse(y);
return _a;
}
void set_coeff(_Tp c)
{
// assert(c > 0);
_b = log(c);
}
public:
_Tp _b;
Vec _a;
};
// Non-member functions
template <typename _Tp>
inline monomial<_Tp> sqrt(monomial<_Tp> m)
{
m.sqrt();
return m;
}
template <typename _Tp, typename _Up>
inline monomial<_Tp> operator/(const _Up& c, const monomial<_Tp>& m)
{
return monomial<_Tp>(m._a.size(), _Tp(c)) / m;
}
template <typename _Tp, typename _Up>
inline monomial<_Tp> operator*(const _Up& c, const monomial<_Tp>& m)
{
return m * _Tp(c); // assume commutative
}
template <typename _Tp>
inline monomial<_Tp> operator*(monomial<_Tp> lhs, const monomial<_Tp>& rhs)
{
lhs *= rhs;
return lhs;
}
template <typename _Tp>
inline monomial<_Tp> operator/(monomial<_Tp> lhs, const monomial<_Tp>& rhs)
{
lhs /= rhs;
return lhs;
}
#endif