Page MenuHomec4science

differentiation.hh
No OneTemporary

File Metadata

Created
Fri, Apr 26, 07:58

differentiation.hh

/**
* @file
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2018-2021 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Expolit is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Expolit is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Expolit. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef DIFFERENTIATION_HH
#define DIFFERENTIATION_HH
#include "exponential.hh"
#include "litteral.hh"
#include "operations.hh"
#include "polynomial.hh"
#include "types.hh"
#include <algorithm>
namespace expolit {
namespace detail {
template <std::size_t i>
struct for_diff {
template <typename CT, std::size_t n>
constexpr static void diff(std::array<CT, n - 1>& res,
const std::array<CT, n>& a) {
std::get<i>(res) = a[i + 1] * static_cast<CT>(i + 1);
for_diff<i - 1>::diff(res, a);
}
};
template <>
struct for_diff<0> {
template <typename CT, std::size_t n>
constexpr static void diff(std::array<CT, n - 1>& res,
const std::array<CT, n>& a) {
std::get<0>(res) = a[1] * static_cast<CT>(1);
}
};
} // namespace detail
/// Differentiate polynomial
template <typename CT, UInt order>
constexpr auto differentiate(const Polynomial<CT, order>& p) {
Polynomial<CT, order - 1> dp;
detail::for_diff<dp.terms - 1>::diff(dp.coeffs, p.coeffs);
return dp;
}
/// Differentiate constant
template <typename CT>
constexpr auto differentiate(const Constant<CT>& /*p*/) {
return Constant<CT>({0});
}
/// Differentiate litteral
template <typename Tag>
constexpr auto differentiate(const Litteral<Tag>& /*p*/) {
return 0;
}
/// Differentiate exponential
template <typename T>
constexpr auto differentiate(const Exponential<T>& e) {
return differentiate(e.expression) * e;
}
/// Differentiate generic product
template <typename T, typename U>
constexpr auto differentiate(const Product<T, U>& p) {
auto&& o = p.operands;
return differentiate(o.first) * o.second + o.first * differentiate(o.second);
}
/// Differentiate constant + expression
template <typename CT, typename U>
constexpr auto differentiate(const Sum<Constant<CT>, U>& p) {
return differentiate(p.operands.second);
}
/// Differentiate expression + constant
template <typename T, typename U, typename CT>
constexpr auto differentiate(const Sum<U, Constant<CT>>& p) {
return differentiate(p.commute());
}
/// Differentiate litteral + expression
template <typename Tag, typename U>
constexpr auto differentiate(const Sum<Litteral<Tag>, U>& p) {
return differentiate(p.operands.second);
}
/// Differentiate expression + litteral
template <typename Tag, typename U>
constexpr auto differentiate(const Sum<U, Litteral<Tag>>& p) {
return differentiate(p.commute());
}
/// Differentiate constant * expression
template <typename CT, typename U>
constexpr auto differentiate(const Product<Constant<CT>, U>& p) {
return p.operands.first * differentiate(p.operands.second);
}
/// Differentiate expression * constant
template <typename CT, typename U>
constexpr auto differentiate(const Product<U, Constant<CT>>& p) {
return differentiate(p.commute());
}
/// Differentiate litteral * expression
template <typename Tag, typename U>
constexpr auto differentiate(const Product<Litteral<Tag>, U>& p) {
return p.operands.first * differentiate(p.operands.second);
}
/// Differentiate expression * litteral
template <typename Tag, typename U>
constexpr auto differentiate(const Product<U, Litteral<Tag>>& p) {
return differentiate(p.commute());
}
} // namespace expolit
#endif

Event Timeline