bpp-phyl3  3.0.0
ExtendedFloatEigenTools.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #ifndef BPP_PHYL_LIKELIHOOD_DATAFLOW_EXTENDEDFLOATEIGENTOOLS_H
6 #define BPP_PHYL_LIKELIHOOD_DATAFLOW_EXTENDEDFLOATEIGENTOOLS_H
7 
8 
9 #include "ExtendedFloat.h"
10 
11 /*
12  * Class of tool operators ExtendedFloatMatrix objects, needed from Eigen tools.
13  *
14  * This code is strongly influenced from Eigen code.
15  */
16 
17 
18 namespace bpp
19 {
20 template<typename Derived> class ExtendedFloatEigenBase;
21 
22 template<int R, int C, template<int R2, int C2> class EigenType> class ExtendedFloatEigen;
23 
24 
25 /*
26  * Class of operators to perform columnwise & rowwise operations on ExtendedFloatMatrix objects.
27  *
28  * This code is strongly influenced from Eigen code.
29  */
30 
31 template<typename DerivedEF, typename MatType, int Direction>
33 {
34 private:
35  DerivedEF& efMat_;
36 
37  Eigen::VectorwiseOp<MatType, Direction> eigenVWiseOp_;
38 
39 public:
40  ExtendedFloatVectorwiseOp(DerivedEF& der) :
41  efMat_(der),
42  eigenVWiseOp_(der.float_part()) {}
43 
44  template<typename OtherDerived>
45  DerivedEF& operator=(const OtherDerived& otherDerived)
46  {
47  eigenVWiseOp_ = otherDerived.float_part();
48  efMat_.exponent_part() = otherDerived.exponent_part();
49 
50  return efMat_;
51  }
52 
53  DerivedEF sum() const
54  {
55  auto s = eigenVWiseOp_.sum();
56  return DerivedEF(s, efMat_.derived().exponent_part());
57  }
58 
59  DerivedEF mean() const
60  {
61  auto s = eigenVWiseOp_.mean();
62  return DerivedEF(s, efMat_.derived().exponent_part());
63  }
64 };
65 
66 
67 /*
68  * Manage NoAlias for Eigen::Matrix objects in ExtendedFloatMatrix;
69  *
70  */
71 
72 template<typename DerivedEF>
74 {
75 protected:
77 
78 public:
80  efMat_(der) {}
81 
82  template<typename Otherderived>
84  {
85  efMat_.derived().float_part().noalias() = other.derived().float_part();
86  efMat_.derived().exponent_part() = other.derived().exponent_part();
87  return efMat_;
88  }
89 
90  template<typename Otherderived>
92  {
93  auto& thisnoal(efMat_.derived().float_part().noalias());
94  const auto& rhs(other.derived());
95 
96  if (efMat_.derived().exponent_part () >= rhs.exponent_part ())
97  {
98  thisnoal += rhs.float_part () * constexpr_power<double>(ExtendedFloat::radix, rhs.exponent_part () - efMat_().derived().exponent_part ());
99  }
100  else
101  {
102  thisnoal = rhs.float_part () + efMat_.derived().float_part () * constexpr_power<double>(ExtendedFloat::radix, efMat_.derived().exponent_part () - rhs.exponent_part ());
103  efMat_.derived().exponent_part() = rhs.exponent_part ();
104  }
105  efMat_.derived().normalize ();
106  return efMat_;
107  }
108 
109  template<typename Otherderived>
111  {
112  auto& thisnoal(efMat_.derived().float_part().noalias());
113  const auto& rhs(other.derived());
114 
115  if (efMat_.derived().exponent_part () >= rhs.exponent_part ())
116  {
117  thisnoal -= rhs.float_part () * constexpr_power<double>(ExtendedFloat::radix, rhs.exponent_part () - efMat_().derived().exponent_part ());
118  }
119  else
120  {
121  thisnoal = rhs.float_part () - efMat_.derived().float_part () * constexpr_power<double>(ExtendedFloat::radix, efMat_.derived().exponent_part () - rhs.exponent_part ());
122  efMat_.derived().exponent_part() = rhs.exponent_part ();
123  }
124  efMat_.derived().normalize ();
125  return efMat_;
126  }
127 };
128 
129 
130 /*
131  * Manage Row in a ExtendedFloatMatrix;
132  *
133  */
134 
135 template< int R, int C, template< int R2, int C2> class EigenType>
137 {
138  using VecType = EigenType<1, C>;
139  using ExtType = int;
140 
141 protected:
143  Eigen::Index nrow_;
144 
145 private:
147 
148 public:
150  efMat_(der), nrow_(nrow), tmp_(efMat_.float_part().row(nrow_)) {}
151 
152  const ExtType& exponent_part () const { return efMat_.exponent_part(); }
153 
154  const VecType& float_part () const { return tmp_; }
155 
156  ExtType& exponent_part () { return efMat_.exponent_part(); }
157 
158  VecType& float_part () { return tmp_; }
159 
160  /*
161  * @brief Includes a row in an ExtendedFloatMatrix. Exponent parts
162  * of both are to be fit, as in denorm_add method.
163  *
164  */
166  {
167  efMat_.float_part().row(nrow_) = row.float_part() * constexpr_power<double>(ExtendedFloat::radix, row.exponent_part() - efMat_.exponent_part());
168  efMat_.normalize();
169  return *this;
170  }
171 };
172 
173 /*
174  * Manage Col in a ExtendedFloatMatrix;
175  *
176  */
177 
178 template< int R, int C, template< int R2, int C2> class EigenType>
179 class ExtendedFloatCol : public ExtendedFloatEigen<R, 1, EigenType>
180 {
181  using VecType = EigenType<R, 1>;
182  using ExtType = int;
183 
184 protected:
186  Eigen::Index ncol_;
187 
188 private:
190 
191 public:
193  efMat_(der), ncol_(ncol), tmp_(efMat_.float_part().col(ncol_)) {}
194 
195  /*
196  * @brief Includes a row in an ExtendedFloatMatrix. Exponent parts
197  * of both are to be fit, as in denorm_add method.
198  *
199  */
200  const ExtType& exponent_part () const
201  {
202  return efMat_.exponent_part();
203  }
204 
205  const VecType& float_part () const
206  {
207  return tmp_;
208  }
209 
211  {
212  return efMat_.exponent_part();
213  }
214 
216  {
217  return tmp_;
218  }
219 
221  {
222  efMat_.float_part().col(ncol_) = col.float_part() * constexpr_power<double>(ExtendedFloat::radix, col.exponent_part() - efMat_.exponent_part());
223  efMat_.normalize();
224  return *this;
225  }
226 
227  // std::ostream& operator<<(std::ostream& out, const Self& ef)
228  // {
229  // return out << "( " << efMat_.float_part() << " ) * 2^" << efMat_.exponent_part();
230  // }
231 
232  // const ExtendedFloat& sum() const
233  // {
234  // EFtmp_.set_float_part(float_part().sum());
235  // EFtmp_.set_exponent_part(exponent_part());
236  // return EFtmp_;
237  // }
238 };
239 }
240 
241 #endif // BPP_PHYL_LIKELIHOOD_DATAFLOW_EXTENDEDFLOATEIGENTOOLS_H
ExtendedFloatEigen< R, C, EigenType > & efMat_
const VecType & float_part() const
ExtendedFloatCol & operator=(const ExtendedFloatEigen< R, 1, EigenType > &col)
ExtendedFloatCol(ExtendedFloatEigen< R, C, EigenType > &der, Eigen::Index ncol)
const ExtType & exponent_part() const
virtual const ExtType & exponent_part() const
virtual const MatType & float_part() const
std::enable_if< std::is_same< M, EFMatrix< R, C > >::value, ExtendedFloatCol< R, C, EigenType > >::type col(Eigen::Index pos)
ExtendedFloatEigenBase< DerivedEF > & operator-=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatNoAlias(ExtendedFloatEigenBase< DerivedEF > &der)
ExtendedFloatEigenBase< DerivedEF > & operator=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatEigenBase< DerivedEF > & operator+=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatEigenBase< DerivedEF > & efMat_
const ExtType & exponent_part() const
ExtendedFloatEigen< R, C, EigenType > & efMat_
ExtendedFloatRow(ExtendedFloatEigen< R, C, EigenType > &der, Eigen::Index nrow)
const VecType & float_part() const
ExtendedFloatRow & operator=(const ExtendedFloatEigen< 1, C, EigenType > &row)
DerivedEF & operator=(const OtherDerived &otherDerived)
Eigen::VectorwiseOp< MatType, Direction > eigenVWiseOp_
static constexpr int radix
Definition: ExtendedFloat.h:49
Defines the basic types of data flow nodes.