Program Listing for File pseudoConstructors.hpp#

Return to documentation for file (librapid/include/librapid/array/pseudoConstructors.hpp)

#ifndef LIBRAPID_ARRAY_PSEUDO_CONSTRUCTORS_HPP
#define LIBRAPID_ARRAY_PSEUDO_CONSTRUCTORS_HPP

namespace librapid {
    template<typename T>
    auto evaluated(const T &other) {
        return other;
    }

    template<typename ShapeType, typename StorageType>
    auto evaluated(const array::ArrayContainer<ShapeType, StorageType> &other) {
        return other;
    }

    template<typename descriptor, typename Functor, typename... Args>
    auto evaluated(const detail::Function<descriptor, Functor, Args...> &other) {
        return other.eval();
    }

    template<typename T>
    auto emptyLike(const T &other) {
        using Scalar  = typename typetraits::TypeInfo<T>::Scalar;
        using Backend = typename typetraits::TypeInfo<T>::Backend;
        return Array<Scalar, Backend>(other.shape());
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename ShapeType = Shape>
        requires(typetraits::IsSizeType<ShapeType>::value)
    Array<Scalar, Backend> zeros(const ShapeType &shape) {
        return Array<Scalar, Backend>(shape, Scalar(0));
    }

    template<typename T>
    auto zerosLike(const T &other) {
        using Scalar  = typename typetraits::TypeInfo<T>::Scalar;
        using Backend = typename typetraits::TypeInfo<T>::Backend;
        return zeros<Scalar, Backend>(other.shape());
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename ShapeType = Shape>
        requires(typetraits::IsSizeType<ShapeType>::value)
    Array<Scalar, Backend> ones(const ShapeType &shape) {
        return Array<Scalar, Backend>(shape, Scalar(1));
    }

    template<typename T>
    auto onesLike(const T &other) {
        using Scalar  = typename typetraits::TypeInfo<T>::Scalar;
        using Backend = typename typetraits::TypeInfo<T>::Backend;
        return ones<Scalar, Backend>(other.shape());
    }

    template<typename Scalar = int64_t, typename Backend = backend::CPU, typename ShapeType = Shape>
        requires(typetraits::IsSizeType<ShapeType>::value)
    Array<Scalar, Backend> ordered(const ShapeType &shape) {
        Array<Scalar, Backend> result(shape);
        for (size_t i = 0; i < result.size(); i++) { result.storage()[i] = Scalar(i); }
        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename Start,
             typename Stop, typename Step>
    Array<Scalar, Backend> arange(Start start, Stop stop, Step step) {
        LIBRAPID_ASSERT_WITH_EXCEPTION(
          std::invalid_argument, step != 0, "Step size cannot be zero");
        LIBRAPID_ASSERT_WITH_EXCEPTION(std::invalid_argument,
                                       (stop - start) / step > 0,
                                       "Step size is invalid for the specified range");

        Shape shape = {(int64_t)::librapid::abs((stop - start) / step)};
        Array<Scalar, Backend> result(shape);
        for (size_t i = 0; i < shape.size(); i++) {
            result.storage()[i] = Scalar(start + i * step);
        }
        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename T>
    Array<Scalar, Backend> arange(T start, T stop) {
        LIBRAPID_ASSERT_WITH_EXCEPTION(std::invalid_argument,
                                       (stop - start) > 0,
                                       "Step size is invalid for the specified range");

        Shape shape = {(int64_t)::librapid::abs(stop - start)};
        Array<Scalar, Backend> result(shape);
        for (size_t i = 0; i < shape.size(); i++) { result.storage()[i] = Scalar(start + i); }
        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename T>
    Array<Scalar, Backend> arange(T stop) {
        Shape shape = {(int64_t)::librapid::abs(stop)};
        Array<Scalar, Backend> result(shape);
        for (size_t i = 0; i < shape.size(); i++) { result.storage()[i] = Scalar(i); }
        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename Start,
             typename Stop>
    Array<Scalar, Backend> linspace(Start start, Stop stop, int64_t num, bool includeEnd = true) {
        LIBRAPID_ASSERT_WITH_EXCEPTION(
          std::invalid_argument, num > 0, "Number of samples must be greater than zero");

        auto startCast = static_cast<Scalar>(start);
        auto stopCast  = static_cast<Scalar>(stop);
        auto den       = static_cast<Scalar>(num - includeEnd);
        Shape shape    = {num};
        Array<Scalar, Backend> result(shape);
        for (size_t i = 0; i < shape.size(); i++) {
            result.storage()[i] = startCast + (stopCast - startCast) * static_cast<Scalar>(i) / den;
        }
        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename Start,
             typename Stop>
    Array<Scalar, Backend> logspace(Start start, Stop stop, int64_t num, bool includeEnd = true) {
        LIBRAPID_ASSERT_WITH_EXCEPTION(
          std::invalid_argument, num > 0, "Number of samples must be greater than zero");

        auto logLower = ::librapid::log(static_cast<Scalar>(start));
        auto logUpper = ::librapid::log(static_cast<Scalar>(stop));

        Shape shape = {num};
        Array<Scalar, Backend> result(shape);

        for (size_t i = 0; i < shape.size(); i++) {
            result.storage()[i] =
              ::librapid::exp(logLower + (logUpper - logLower) * static_cast<Scalar>(i) /
                                           static_cast<Scalar>(num - includeEnd));
        }

        return result;
    }

    template<typename Scalar = double, typename Backend = backend::CPU, typename Lower = double,
             typename Upper = double>
    Array<Scalar, Backend> random(const Shape &shape, Lower lower = 0, Upper upper = 1) {
        Array<Scalar, Backend> result(shape);
        fillRandom(result, static_cast<Scalar>(lower), static_cast<Upper>(upper));
        return result;
    }
} // namespace librapid

#endif // LIBRAPID_ARRAY_PSEUDO_CONSTRUCTORS_HPP