/* * Fatrop - A fast trajectory optimization solver * Copyright (C) 2022 - 2024 Lander Vanroye, KU Leuven. All rights reserved. * * This file is part of Fatrop. * * Fatrop 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. * * Fatrop 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 Fatrop. If not, see . */ #ifndef FATROP_VECTOR_INCLUDED #define FATROP_VECTOR_INCLUDED #include #include #include #include #include namespace fatrop { // static polymorphism using CRTP template class VecExpr { public: T get(const fatrop_int ai) const { return static_cast(*this).get(ai); }; fatrop_int size() const { return static_cast(*this).size(); }; }; template class VecSum : public VecExpr, T> { public: VecSum(const VecExpr &expr1, const VecExpr &expr2) : expr1_(expr1), expr2_(expr2) { assert(expr1.size() == expr2.size()); }; T get(const fatrop_int ai) const { return expr1_.get(ai) + expr2_.get(ai); }; fatrop_int size() const { return expr1_.size(); }; private: const VecExpr &expr1_; const VecExpr &expr2_; }; template class VecScalarSum : public VecExpr, T> { public: VecScalarSum(const VecExpr &expr, const fatrop_int scalar) : expr_(expr), scalar_(scalar){}; T get(const fatrop_int ai) const { return expr_.get(ai) + scalar_; }; fatrop_int size() const { return expr_.size(); }; public: const VecExpr &expr_; T scalar_; }; template class VecRotate : public VecExpr, T> { public: VecRotate(const VecExpr &expr, const fatrop_int shift) : expr_(expr), shift_(shift){}; T get(const fatrop_int ai) const { return expr_.get((ai + shift_ + (((ai + shift_) / size() + 1) * size())) % size()); }; fatrop_int size() const { return expr_.size(); }; public: const VecExpr &expr_; fatrop_int shift_; }; template class FatropVector : public std::vector, public VecExpr, T> { public: FatropVector() : std::vector(){}; FatropVector(const fatrop_int size) : std::vector(size){}; template FatropVector(const VecExpr &vecexpr) : std::vector(vecexpr.size()) { // todo: vector is first initialized, initialize with iterator for (fatrop_int i = 0; i < vecexpr.size(); i++) { std:: vector::at(i) = vecexpr.get(i); } } FatropVector(const std::vector &vec) : std::vector(vec){}; FatropVector(std::vector &&vec) : std::vector(std::move(vec)){}; T get(const fatrop_int ai) const { return std::vector::at(ai); }; fatrop_int size() const { return std::vector::size(); }; operator T *() { return this->data(); }; }; template VecSum operator+(const VecExpr &expr1, const VecExpr &expr2) { return VecSum(expr1, expr2); } template VecScalarSum operator+(const VecExpr &expr1, const fatrop_int scalar) { return VecScalarSum(expr1, scalar); } template VecScalarSum operator+(const fatrop_int scalar, const VecExpr &expr1) { return VecScalarSum(expr1, scalar); } template T sum(const VecExpr &expr) { T res = 0; for (fatrop_int i = 0; i < expr.size(); i++) { res += expr.get(i); } return res; } template VecRotate rotate(const VecExpr &expr, const fatrop_int shift) { return VecRotate(expr, shift); }; template std::vector TransformRange(const fatrop_int begin, const fatrop_int end, const std::function& func) { fatrop_int size = end - begin; std::vector res(size); for (fatrop_int i = 0; i < size; i++) { res.at(i) = func(begin + i); } return res; } } // namespace fatrop #endif // FATROP_VECTOR_INCLUDED