/*
* 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