Alexandria 2.31.2
SDC-CH common library for the Euclid project
Loading...
Searching...
No Matches
multiplication.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012-2022 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
24
31#include <memory>
32#include <set>
33#include <vector>
34
35namespace Euclid {
36namespace MathUtils {
37
40 const auto& p1 = dynamic_cast<const Polynomial&>(f1);
41 const auto& p2 = dynamic_cast<const Polynomial&>(f2);
42 std::vector<double> c1 = p1.getCoefficients();
43 std::vector<double> c2 = p2.getCoefficients();
44 std::vector<double> resultCoef(c1.size() + c2.size() - 1, 0.);
45 for (size_t i = 0; i < c1.size(); ++i)
46 for (size_t j = 0; j < c2.size(); ++j)
47 resultCoef[i + j] += c1[i] * c2[j];
48 return make_unique<Polynomial>(std::move(resultCoef));
49}
50
54 const auto& piecewise = dynamic_cast<const Piecewise&>(f1);
55 const auto& interval_functions = piecewise.getFunctions();
56
57 std::vector<std::shared_ptr<Function>> functions(interval_functions.size());
58 std::transform(interval_functions.begin(), interval_functions.end(), functions.begin(),
59 [&f2](const std::unique_ptr<Function>& original) { return multiply(*original, f2); });
60 return make_unique<Piecewise>(piecewise.getKnots(), functions);
61}
62
63template <typename Iter>
64static std::pair<Iter, Iter> overlappingStart(Iter start1, Iter end1, Iter start2, Iter end2) {
65 for (auto i1 = start1, i2 = start2; i1 != end1 && i2 != end2;) {
66 if (*i1 < *i2) {
67 ++i1;
68 if (i1 != end1 && *i1 > *i2) {
69 return {i1, i2};
70 }
71 } else {
72 ++i2;
73 if (i2 != end2 && *i1 < *i2) {
74 return {i1, i2};
75 }
76 }
77 }
78 return {end1, end2};
79}
80
83 std::set<double> knotSet{};
84 std::vector<double>::const_iterator p1Iter;
85 std::vector<double>::const_iterator p2Iter;
86 std::tie(p1Iter, p2Iter) = overlappingStart(knots1.begin(), knots1.end(), knots2.begin(), knots2.end());
87
88 while (p1Iter != knots1.end() && p2Iter != knots2.end()) {
89 if (*p1Iter < *p2Iter) {
90 knotSet.insert(*p1Iter);
91 ++p1Iter;
92 } else {
93 knotSet.insert(*p2Iter);
94 ++p2Iter;
95 }
96 }
97 return std::vector<double>{knotSet.begin(), knotSet.end()};
98}
99
100// Multiply two Piecewise Function%s by multiplying all their sub-functions
102 const auto& p1 = dynamic_cast<const Piecewise&>(f1);
103 const auto& p2 = dynamic_cast<const Piecewise&>(f2);
104
105 auto knots = overlappingKnots(p1.getKnots(), p2.getKnots());
106
107 if (knots.empty()) {
109 }
110
112 auto& p1func = p1.getFunctions();
113 auto& p2func = p2.getFunctions();
114 int i1{};
115 int i2{};
116 for (double knot : knots) {
117 if (knot == knots.back()) {
118 break;
119 }
120 while (p1.getKnots()[i1 + 1] <= knot) {
121 ++i1;
122 }
123 while (p2.getKnots()[i2 + 1] <= knot) {
124 ++i2;
125 }
126 functions.push_back(std::shared_ptr<Function>{Euclid::MathUtils::multiply(*p1func[i1], *p2func[i2]).release()});
127 }
128
129 return make_unique<Piecewise>(knots, std::move(functions));
130}
131
135
138
139} // namespace MathUtils
140} // end of namespace Euclid
T begin(T... args)
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:67
Represents a polynomial function.
Definition Polynomial.h:43
T end(T... args)
T move(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
static std::pair< Iter, Iter > overlappingStart(Iter start1, Iter end1, Iter start2, Iter end2)
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)
NAryFunction< 1 > Function
Alias for an unary function.
Definition Function.h:116
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< T > make_unique(Args &&... args)
Constructs an object of type T and wraps it in a std::unique_ptr using args as the parameter list for...
T size(T... args)
T tie(T... args)
T transform(T... args)