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
18namespace bpp
19{
20template<typename Derived> class ExtendedFloatEigenBase;
21
22template<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
31template<typename DerivedEF, typename MatType, int Direction>
33{
34private:
35 DerivedEF& efMat_;
36
37 Eigen::VectorwiseOp<MatType, Direction> eigenVWiseOp_;
38
39public:
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
72template<typename DerivedEF>
74{
75protected:
77
78public:
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
135template< int R, int C, template< int R2, int C2> class EigenType>
137{
138 using VecType = EigenType<1, C>;
139 using ExtType = int;
140
141protected:
143 Eigen::Index nrow_;
144
145private:
147
148public:
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
178template< int R, int C, template< int R2, int C2> class EigenType>
179class ExtendedFloatCol : public ExtendedFloatEigen<R, 1, EigenType>
180{
181 using VecType = EigenType<R, 1>;
182 using ExtType = int;
183
184protected:
186 Eigen::Index ncol_;
187
188private:
190
191public:
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)
const ExtType & exponent_part() const
ExtendedFloatCol(ExtendedFloatEigen< R, C, EigenType > &der, Eigen::Index ncol)
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)
virtual const ExtType & exponent_part() const
ExtendedFloatEigenBase< DerivedEF > & operator=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatEigenBase< DerivedEF > & operator+=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatNoAlias(ExtendedFloatEigenBase< DerivedEF > &der)
ExtendedFloatEigenBase< DerivedEF > & operator-=(const ExtendedFloatEigenBase< Otherderived > &other)
ExtendedFloatEigenBase< DerivedEF > & efMat_
ExtendedFloatEigen< R, C, EigenType > & efMat_
const VecType & float_part() const
ExtendedFloatRow(ExtendedFloatEigen< R, C, EigenType > &der, Eigen::Index nrow)
ExtendedFloatRow & operator=(const ExtendedFloatEigen< 1, C, EigenType > &row)
const ExtType & exponent_part() const
Eigen::VectorwiseOp< MatType, Direction > eigenVWiseOp_
DerivedEF & operator=(const OtherDerived &otherDerived)
static constexpr int radix
Definition: ExtendedFloat.h:49
Defines the basic types of data flow nodes.