26#ifndef quantlib_array_hpp
27#define quantlib_array_hpp
37#include <initializer_list>
69 template <typename
T, typename =
std::enable_if_t<
std::is_convertible_v<
T,
Real>>>
72 template <class ForwardIterator>
79 bool operator==(const
Array&) const;
80 bool operator!=(const
Array&) const;
262 std::ostream& operator<<(
std::ostream&, const
Array&);
276 : data_(size != 0U ? new
Real[size] : (
Real*)nullptr), n_(size) {
282 : data_(from.n_ != 0U ? new
Real[from.n_] : (
Real*)nullptr), n_(from.n_) {
288 : data_((
Real*)
nullptr), n_(0) {
296 std::unique_ptr<
Real[]>& data_,
299 const std::true_type&) {
306 data_.reset(
n ?
new Real[
n] : (
Real*)
nullptr);
313 std::unique_ptr<
Real[]>& data_,
315 const I& begin,
const I& end,
316 const std::false_type&) {
318 Size n = std::distance(begin, end);
319 data_.reset(
n ?
new Real[
n] : (
Real*)
nullptr);
321 #if defined(QL_PATCH_MSVC) && defined(QL_DEBUG)
324 std::copy(begin, end, a.
begin());
334 template <
class ForwardIterator>
339 std::is_integral<ForwardIterator>());
342 template <
typename T,
typename>
369 "arrays with different sizes (" <<
n_ <<
", "
370 <<
v.n_ <<
") cannot be added");
383 "arrays with different sizes (" <<
n_ <<
", "
384 <<
v.n_ <<
") cannot be subtracted");
385 std::transform(
begin(),
end(),
v.begin(),
begin(), std::minus<>());
396 "arrays with different sizes (" <<
n_ <<
", "
397 <<
v.n_ <<
") cannot be multiplied");
398 std::transform(
begin(),
end(),
v.begin(),
begin(), std::multiplies<>());
409 "arrays with different sizes (" <<
n_ <<
", "
410 <<
v.n_ <<
") cannot be divided");
411 std::transform(
begin(),
end(),
v.begin(),
begin(), std::divides<>());
416 #if defined(QL_EXTRA_SAFETY_CHECKS)
424 #if defined(QL_EXTRA_SAFETY_CHECKS)
426 "index (" << i <<
") must be less than " <<
n_ <<
427 ": array access out of range");
429 return data_.get()[i];
434 "index (" << i <<
") must be less than " <<
n_ <<
435 ": array access out of range");
436 return data_.get()[i];
440 #if defined(QL_EXTRA_SAFETY_CHECKS)
441 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
443 return data_.get()[0];
447 #if defined(QL_EXTRA_SAFETY_CHECKS)
448 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
454 #if defined(QL_EXTRA_SAFETY_CHECKS)
456 "index (" << i <<
") must be less than " <<
n_ <<
457 ": array access out of range");
459 return data_.get()[i];
464 "index (" << i <<
") must be less than " <<
n_ <<
465 ": array access out of range");
466 return data_.get()[i];
470 #if defined(QL_EXTRA_SAFETY_CHECKS)
471 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
473 return data_.get()[0];
477 #if defined(QL_EXTRA_SAFETY_CHECKS)
478 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
535 data_.swap(from.data_);
536 std::swap(n_, from.n_);
543 "arrays with different sizes (" << v1.
size() <<
", "
544 << v2.
size() <<
") cannot be multiplied");
567 std::transform(
v.begin(),
v.end(), result.
begin(), std::negate<>());
572 Array result = std::move(
v);
573 std::transform(result.
begin(), result.
end(), result.
begin(), std::negate<>());
581 "arrays with different sizes (" << v1.
size() <<
", "
582 << v2.
size() <<
") cannot be added");
590 "arrays with different sizes (" << v1.
size() <<
", "
591 << v2.size() <<
") cannot be added");
592 Array result = std::move(v2);
599 "arrays with different sizes (" << v1.size() <<
", "
600 << v2.
size() <<
") cannot be added");
601 Array result = std::move(v1);
602 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::plus<>());
608 "arrays with different sizes (" << v1.size() <<
", "
609 << v2.size() <<
") cannot be added");
610 Array result = std::move(v2);
611 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::plus<>());
622 Array result = std::move(v1);
634 Array result = std::move(v2);
641 "arrays with different sizes (" << v1.
size() <<
", "
642 << v2.
size() <<
") cannot be subtracted");
650 "arrays with different sizes (" << v1.
size() <<
", "
651 << v2.size() <<
") cannot be subtracted");
652 Array result = std::move(v2);
659 "arrays with different sizes (" << v1.size() <<
", "
660 << v2.
size() <<
") cannot be subtracted");
661 Array result = std::move(v1);
662 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::minus<>());
668 "arrays with different sizes (" << v1.size() <<
", "
669 << v2.size() <<
") cannot be subtracted");
670 Array result = std::move(v2);
671 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::minus<>());
682 Array result = std::move(v1);
694 Array result = std::move(v2);
701 "arrays with different sizes (" << v1.
size() <<
", "
702 << v2.
size() <<
") cannot be multiplied");
704 std::transform(v1.
begin(), v1.
end(), v2.
begin(), result.
begin(), std::multiplies<>());
710 "arrays with different sizes (" << v1.
size() <<
", "
711 << v2.size() <<
") cannot be multiplied");
712 Array result = std::move(v2);
713 std::transform(v1.
begin(), v1.
end(), result.
begin(), result.
begin(), std::multiplies<>());
719 "arrays with different sizes (" << v1.size() <<
", "
720 << v2.
size() <<
") cannot be multiplied");
721 Array result = std::move(v1);
722 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::multiplies<>());
728 "arrays with different sizes (" << v1.size() <<
", "
729 << v2.size() <<
") cannot be multiplied");
730 Array result = std::move(v2);
731 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::multiplies<>());
742 Array result = std::move(v1);
754 Array result = std::move(v2);
761 "arrays with different sizes (" << v1.
size() <<
", "
762 << v2.
size() <<
") cannot be divided");
770 "arrays with different sizes (" << v1.
size() <<
", "
771 << v2.size() <<
") cannot be divided");
772 Array result = std::move(v2);
773 std::transform(v1.
begin(), v1.
end(), result.
begin(), result.
begin(), std::divides<>());
779 "arrays with different sizes (" << v1.size() <<
", "
780 << v2.
size() <<
") cannot be divided");
781 Array result = std::move(v1);
782 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::divides<>());
788 "arrays with different sizes (" << v1.size() <<
", "
789 << v2.size() <<
") cannot be divided");
790 Array result = std::move(v2);
791 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::divides<>());
802 Array result = std::move(v1);
814 Array result = std::move(v2);
823 std::transform(
v.begin(),
v.end(), result.
begin(),
824 [](
Real x) ->
Real { return std::fabs(x); });
829 Array result = std::move(
v);
831 [](
Real x) ->
Real { return std::fabs(x); });
837 std::transform(
v.begin(),
v.end(),result.
begin(),
838 [](
Real x) ->
Real { return std::sqrt(x); });
843 Array result = std::move(
v);
845 [](
Real x) ->
Real { return std::sqrt(x); });
851 std::transform(
v.begin(),
v.end(),result.
begin(),
852 [](
Real x) ->
Real { return std::log(x); });
857 Array result = std::move(
v);
859 [](
Real x) ->
Real { return std::log(x); });
865 std::transform(
v.begin(),
v.end(), result.
begin(),
866 [](
Real x) ->
Real { return std::exp(x); });
871 Array result = std::move(
v);
873 [](
Real x) ->
Real { return std::exp(x); });
879 std::transform(
v.begin(),
v.end(), result.
begin(),
880 [=](
Real x) ->
Real { return std::pow(x, alpha); });
885 Array result = std::move(
v);
887 [=](
Real x) ->
Real { return std::pow(x, alpha); });
896 std::streamsize width = out.width();
900 out << std::setw(
int(width)) << a[
n] <<
"; ";
901 out << std::setw(
int(width)) << a.
back();
1-D array used in linear algebra.
const Real * const_iterator
const Array & operator*=(const Array &)
std::unique_ptr< Real[]> data_
bool operator!=(const Array &) const
bool operator==(const Array &) const
Array & operator=(const Array &)
Array Pow(const Array &, Real)
std::reverse_iterator< const_iterator > const_reverse_iterator
Real operator[](Size) const
read-only
bool empty() const
whether the array is empty
const_reverse_iterator rend() const
const Array & operator/=(const Array &)
const Array & operator-=(const Array &)
const Array & operator+=(const Array &)
const_reverse_iterator rbegin() const
void swap(Array &) noexcept
Array Sqrt(const Array &)
const_iterator end() const
std::reverse_iterator< iterator > reverse_iterator
Real Norm2(const Array &)
Size size() const
dimension of the array
const_iterator begin() const
Array()
creates the array with size 0
Real DotProduct(const Array &, const Array &)
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
std::size_t Size
size of a container
void _fill_array_(Array &a, std::unique_ptr< Real[]> &data_, Size &n_, I begin, I end, const std::true_type &)
Quantity operator-(const Quantity &m1, const Quantity &m2)
Quantity operator*(const Quantity &m, Real x)
Array Pow(const Array &v, Real alpha)
Array Log(const Array &v)
std::ostream & operator<<(std::ostream &out, GFunctionFactory::YieldCurveModel type)
Quantity operator+(const Quantity &m1, const Quantity &m2)
void swap(Array &v, Array &w) noexcept
Array Abs(const Array &v)
Array Exp(const Array &v)
Array Sqrt(const Array &v)
Real Norm2(const Array &v)
Real DotProduct(const Array &v1, const Array &v2)
Real operator/(const Quantity &m1, const Quantity &m2)
ext::shared_ptr< BlackVolTermStructure > v