Alexandria  2.19
Please provide a description of the project.
multiplication.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2021 Euclid Science Ground Segment
3  *
4  * This library is free software; you can redistribute it and/or modify it under
5  * the terms of the GNU Lesser General Public License as published by the Free
6  * Software Foundation; either version 3.0 of the License, or (at your option)
7  * any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12  * details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
30 #include <memory>
31 #include <set>
32 #include <vector>
33 
34 namespace Euclid {
35 namespace MathUtils {
36 
39  const Polynomial& p1 = dynamic_cast<const Polynomial&>(f1);
40  const Polynomial& p2 = dynamic_cast<const Polynomial&>(f2);
43  std::vector<double> resultCoef(c1.size() + c2.size() - 1, 0.);
44  for (size_t i = 0; i < c1.size(); ++i)
45  for (size_t j = 0; j < c2.size(); ++j)
46  resultCoef[i + j] += c1[i] * c2[j];
47  return std::unique_ptr<Polynomial>(new Polynomial{resultCoef});
48 }
49 
53  const Piecewise& piecewise = dynamic_cast<const Piecewise&>(f1);
55  for (auto& original : piecewise.getFunctions()) {
56  functions.push_back(std::shared_ptr<Function>{Euclid::MathUtils::multiply(*original, f2).release()});
57  }
58  return std::unique_ptr<Function>(new Piecewise{piecewise.getKnots(), functions});
59 }
60 
63  std::set<double> knotSet{};
64  auto p1Iter = knots1.begin();
65  auto p2Iter = knots2.begin();
66  bool started = false;
67  while (p1Iter != knots1.end() && p2Iter != knots2.end()) {
68  if (!started) {
69  if (*p1Iter < *p2Iter) {
70  if (*(++p1Iter) > *p2Iter) {
71  started = true;
72  }
73  } else {
74  if (*p1Iter < *(++p2Iter)) {
75  started = true;
76  }
77  }
78  continue;
79  }
80  if (*p1Iter < *p2Iter) {
81  knotSet.insert(*p1Iter);
82  ++p1Iter;
83  } else {
84  knotSet.insert(*p2Iter);
85  ++p2Iter;
86  }
87  }
88  return std::vector<double>{knotSet.begin(), knotSet.end()};
89 }
90 
91 // Multiply two Piecewise Function%s by multiplying all their sub-functions
93  const Piecewise& p1 = dynamic_cast<const Piecewise&>(f1);
94  const Piecewise& p2 = dynamic_cast<const Piecewise&>(f2);
95 
96  auto knots = overlappingKnots(p1.getKnots(), p2.getKnots());
97 
98  if (knots.empty()) {
99  return std::unique_ptr<Function>{new Polynomial{{0.}}};
100  }
101 
103  auto& p1func = p1.getFunctions();
104  auto& p2func = p2.getFunctions();
105  int i1{};
106  int i2{};
107  for (double knot : knots) {
108  if (knot == knots.back()) {
109  break;
110  }
111  while (p1.getKnots()[i1 + 1] <= knot) {
112  ++i1;
113  }
114  while (p2.getKnots()[i2 + 1] <= knot) {
115  ++i2;
116  }
117  functions.push_back(std::shared_ptr<Function>{Euclid::MathUtils::multiply(*p1func[i1], *p2func[i2]).release()});
118  }
119 
120  return std::unique_ptr<Function>{new Piecewise{knots, functions}};
121 }
122 
126 
128 
129 } // namespace MathUtils
130 } // end of namespace Euclid
T begin(T... args)
Interface class representing a function.
Definition: Function.h:46
Represents a piecewise function.
Definition: Piecewise.h:48
const std::vector< double > & getKnots() const
Returns the knots of the piecewise function.
Definition: Piecewise.cpp:63
const std::vector< std::unique_ptr< Function > > & getFunctions() const
Returns the functions in the ranges between the knots.
Definition: Piecewise.cpp:67
Represents a polynomial function.
Definition: Polynomial.h:43
const std::vector< double > & getCoefficients() const
Returns the coefficients of the polynomial.
Definition: Polynomial.cpp:35
T end(T... args)
ELEMENTS_API std::map< std::pair< std::type_index, std::type_index >, MultiplyFunction > multiplySpecificSpecificMap
ELEMENTS_API std::map< std::type_index, MultiplyFunction > multiplySpecificGenericMap
std::unique_ptr< Function >(* MultiplyFunction)(const Function &, const Function &)
Alias of a function which multiplies Function objects.
std::unique_ptr< Function > multiplyPiecewiseWithGeneric(const Function &f1, const Function &f2)
std::vector< double > overlappingKnots(const std::vector< double > &knots1, const std::vector< double > &knots2)
Returns a vector of the overlapping knots from the given vectors.
std::unique_ptr< Function > multiplyPiecewises(const Function &f1, const Function &f2)
ELEMENTS_API std::unique_ptr< Function > multiply(const Function &f1, const Function &f2)
std::unique_ptr< Function > multiplyPolynomials(const Function &f1, const Function &f2)
Function for multiplying two Polynomials. It multiplies their coefficients.
T push_back(T... args)
T size(T... args)