Alexandria 2.25.0
SDC-CH common library for the Euclid 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
34namespace Euclid {
35namespace 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 ++p1Iter;
71 if (p1Iter != knots1.end() && *p1Iter > *p2Iter) {
72 started = true;
73 }
74 } else {
75 ++p2Iter;
76 if (p2Iter != knots2.end() && *p1Iter < *p2Iter) {
77 started = true;
78 }
79 }
80 continue;
81 }
82 if (*p1Iter < *p2Iter) {
83 knotSet.insert(*p1Iter);
84 ++p1Iter;
85 } else {
86 knotSet.insert(*p2Iter);
87 ++p2Iter;
88 }
89 }
90 return std::vector<double>{knotSet.begin(), knotSet.end()};
91}
92
93// Multiply two Piecewise Function%s by multiplying all their sub-functions
95 const Piecewise& p1 = dynamic_cast<const Piecewise&>(f1);
96 const Piecewise& p2 = dynamic_cast<const Piecewise&>(f2);
97
98 auto knots = overlappingKnots(p1.getKnots(), p2.getKnots());
99
100 if (knots.empty()) {
101 return std::unique_ptr<Function>{new Polynomial{{0.}}};
102 }
103
105 auto& p1func = p1.getFunctions();
106 auto& p2func = p2.getFunctions();
107 int i1{};
108 int i2{};
109 for (double knot : knots) {
110 if (knot == knots.back()) {
111 break;
112 }
113 while (p1.getKnots()[i1 + 1] <= knot) {
114 ++i1;
115 }
116 while (p2.getKnots()[i2 + 1] <= knot) {
117 ++i2;
118 }
119 functions.push_back(std::shared_ptr<Function>{Euclid::MathUtils::multiply(*p1func[i1], *p2func[i2]).release()});
120 }
121
122 return std::unique_ptr<Function>{new Piecewise{knots, functions}};
123}
124
128
131
132} // namespace MathUtils
133} // end of namespace Euclid
T begin(T... args)
Interface class representing a function with an arbitrary number of parameters.
Definition: Function.h:104
const std::vector< double > & getKnots() const
Returns the knots of the piecewise function.
Definition: Piecewise.h:53
Represents a piecewise function.
Definition: Piecewise.h:87
const std::vector< std::unique_ptr< Function > > & getFunctions() const
Returns the functions in the ranges between the knots.
Definition: Piecewise.cpp:66
Represents a polynomial function.
Definition: Polynomial.h:43
const std::vector< double > & getCoefficients() const
Returns the coefficients of the polynomial.
Definition: Polynomial.cpp:36
T end(T... args)
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.
ELEMENTS_API std::map< std::pair< std::type_index, std::type_index >, MultiplyFunction > multiplySpecificSpecificMap
std::unique_ptr< Function >(* MultiplyFunction)(const Function &, const Function &)
Alias of a function which multiplies Function objects.
ELEMENTS_API std::map< std::type_index, MultiplyFunction > multiplySpecificGenericMap
std::unique_ptr< Function > multiplyPolynomials(const Function &f1, const Function &f2)
Function for multiplying two Polynomials. It multiplies their coefficients.
std::unique_ptr< Function > multiplyPiecewiseWithGeneric(const Function &f1, const Function &f2)
std::unique_ptr< Function > multiplyPiecewises(const Function &f1, const Function &f2)
ELEMENTS_API std::unique_ptr< Function > multiply(const Function &f1, const Function &f2)
T push_back(T... args)
T size(T... args)