26#ifndef quantlib_array_hpp
27#define quantlib_array_hpp
37#include <initializer_list>
70 template <class ForwardIterator>
77 bool operator==(const
Array&) const;
78 bool operator!=(const
Array&) const;
149 #ifdef QL_NULL_AS_FUNCTIONS
288 : data_(size != 0U ? new
Real[size] : (
Real*)nullptr), n_(size) {
293 : data_(size != 0U ? new
Real[size] : (
Real*)nullptr), n_(size) {
299 : data_(from.n_ != 0U ? new
Real[from.n_] : (
Real*)nullptr), n_(from.n_) {
305 : data_((
Real*)
nullptr), n_(0) {
313 std::unique_ptr<
Real[]>& data_,
316 const std::true_type&) {
323 data_.reset(
n ?
new Real[
n] : (
Real*)
nullptr);
330 std::unique_ptr<
Real[]>& data_,
333 const std::false_type&) {
335 Size n = std::distance(begin, end);
336 data_.reset(
n ?
new Real[
n] : (
Real*)
nullptr);
338 #if defined(QL_PATCH_MSVC) && defined(QL_DEBUG)
341 std::copy(begin, end, a.
begin());
351 template <
class ForwardIterator>
356 std::is_integral<ForwardIterator>());
381 "arrays with different sizes (" <<
n_ <<
", "
382 <<
v.n_ <<
") cannot be added");
395 "arrays with different sizes (" <<
n_ <<
", "
396 <<
v.n_ <<
") cannot be subtracted");
397 std::transform(
begin(),
end(),
v.begin(),
begin(), std::minus<>());
408 "arrays with different sizes (" <<
n_ <<
", "
409 <<
v.n_ <<
") cannot be multiplied");
410 std::transform(
begin(),
end(),
v.begin(),
begin(), std::multiplies<>());
421 "arrays with different sizes (" <<
n_ <<
", "
422 <<
v.n_ <<
") cannot be divided");
423 std::transform(
begin(),
end(),
v.begin(),
begin(), std::divides<>());
428 #if defined(QL_EXTRA_SAFETY_CHECKS)
436 #if defined(QL_EXTRA_SAFETY_CHECKS)
438 "index (" << i <<
") must be less than " <<
n_ <<
439 ": array access out of range");
441 return data_.get()[i];
446 "index (" << i <<
") must be less than " <<
n_ <<
447 ": array access out of range");
448 return data_.get()[i];
452 #if defined(QL_EXTRA_SAFETY_CHECKS)
453 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
455 return data_.get()[0];
459 #if defined(QL_EXTRA_SAFETY_CHECKS)
460 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
466 #if defined(QL_EXTRA_SAFETY_CHECKS)
468 "index (" << i <<
") must be less than " <<
n_ <<
469 ": array access out of range");
471 return data_.get()[i];
476 "index (" << i <<
") must be less than " <<
n_ <<
477 ": array access out of range");
478 return data_.get()[i];
482 #if defined(QL_EXTRA_SAFETY_CHECKS)
483 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
485 return data_.get()[0];
489 #if defined(QL_EXTRA_SAFETY_CHECKS)
490 QL_REQUIRE(
n_>0,
"null Array: array access out of range");
547 data_.swap(from.data_);
548 std::swap(n_, from.n_);
555 "arrays with different sizes (" << v1.
size() <<
", "
556 << v2.
size() <<
") cannot be multiplied");
579 std::transform(
v.begin(),
v.end(), result.
begin(), std::negate<>());
584 Array result = std::move(
v);
585 std::transform(result.
begin(), result.
end(), result.
begin(), std::negate<>());
593 "arrays with different sizes (" << v1.
size() <<
", "
594 << v2.
size() <<
") cannot be added");
602 "arrays with different sizes (" << v1.
size() <<
", "
603 << v2.size() <<
") cannot be added");
604 Array result = std::move(v2);
611 "arrays with different sizes (" << v1.size() <<
", "
612 << v2.
size() <<
") cannot be added");
613 Array result = std::move(v1);
614 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::plus<>());
620 "arrays with different sizes (" << v1.size() <<
", "
621 << v2.size() <<
") cannot be added");
622 Array result = std::move(v2);
623 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::plus<>());
634 Array result = std::move(v1);
646 Array result = std::move(v2);
653 "arrays with different sizes (" << v1.
size() <<
", "
654 << v2.
size() <<
") cannot be subtracted");
662 "arrays with different sizes (" << v1.
size() <<
", "
663 << v2.size() <<
") cannot be subtracted");
664 Array result = std::move(v2);
671 "arrays with different sizes (" << v1.size() <<
", "
672 << v2.
size() <<
") cannot be subtracted");
673 Array result = std::move(v1);
674 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::minus<>());
680 "arrays with different sizes (" << v1.size() <<
", "
681 << v2.size() <<
") cannot be subtracted");
682 Array result = std::move(v2);
683 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::minus<>());
694 Array result = std::move(v1);
706 Array result = std::move(v2);
713 "arrays with different sizes (" << v1.
size() <<
", "
714 << v2.
size() <<
") cannot be multiplied");
716 std::transform(v1.
begin(), v1.
end(), v2.
begin(), result.
begin(), std::multiplies<>());
722 "arrays with different sizes (" << v1.
size() <<
", "
723 << v2.size() <<
") cannot be multiplied");
724 Array result = std::move(v2);
725 std::transform(v1.
begin(), v1.
end(), result.
begin(), result.
begin(), std::multiplies<>());
731 "arrays with different sizes (" << v1.size() <<
", "
732 << v2.
size() <<
") cannot be multiplied");
733 Array result = std::move(v1);
734 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::multiplies<>());
740 "arrays with different sizes (" << v1.size() <<
", "
741 << v2.size() <<
") cannot be multiplied");
742 Array result = std::move(v2);
743 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::multiplies<>());
754 Array result = std::move(v1);
766 Array result = std::move(v2);
773 "arrays with different sizes (" << v1.
size() <<
", "
774 << v2.
size() <<
") cannot be divided");
782 "arrays with different sizes (" << v1.
size() <<
", "
783 << v2.size() <<
") cannot be divided");
784 Array result = std::move(v2);
785 std::transform(v1.
begin(), v1.
end(), result.
begin(), result.
begin(), std::divides<>());
791 "arrays with different sizes (" << v1.size() <<
", "
792 << v2.
size() <<
") cannot be divided");
793 Array result = std::move(v1);
794 std::transform(result.
begin(), result.
end(), v2.
begin(), result.
begin(), std::divides<>());
800 "arrays with different sizes (" << v1.size() <<
", "
801 << v2.size() <<
") cannot be divided");
802 Array result = std::move(v2);
803 std::transform(v1.begin(), v1.end(), result.
begin(), result.
begin(), std::divides<>());
814 Array result = std::move(v1);
826 Array result = std::move(v2);
835 std::transform(
v.begin(),
v.end(), result.
begin(),
836 [](
Real x) ->
Real { return std::fabs(x); });
841 Array result = std::move(
v);
843 [](
Real x) ->
Real { return std::fabs(x); });
849 std::transform(
v.begin(),
v.end(),result.
begin(),
850 [](
Real x) ->
Real { return std::sqrt(x); });
855 Array result = std::move(
v);
857 [](
Real x) ->
Real { return std::sqrt(x); });
863 std::transform(
v.begin(),
v.end(),result.
begin(),
864 [](
Real x) ->
Real { return std::log(x); });
869 Array result = std::move(
v);
871 [](
Real x) ->
Real { return std::log(x); });
877 std::transform(
v.begin(),
v.end(), result.
begin(),
878 [](
Real x) ->
Real { return std::exp(x); });
883 Array result = std::move(
v);
885 [](
Real x) ->
Real { return std::exp(x); });
891 std::transform(
v.begin(),
v.end(), result.
begin(),
892 [=](
Real x) ->
Real { return std::pow(x, alpha); });
897 Array result = std::move(
v);
899 [=](
Real x) ->
Real { return std::pow(x, alpha); });
908 std::streamsize width = out.width();
912 out << std::setw(
int(width)) << a[
n] <<
"; ";
913 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
Array operator/(const Array &, const Array &)
bool operator==(const Array &) const
Array & operator=(const Array &)
Array Pow(const Array &, Real)
std::ostream & operator<<(std::ostream &, const Array &)
std::reverse_iterator< const_iterator > const_reverse_iterator
Array operator-(const Array &v)
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
Array operator*(const Array &, const Array &)
Real Norm2(const Array &)
Array operator+(const Array &v)
Size size() const
dimension of the array
const_iterator begin() const
Array()
creates the array with size 0
Real DotProduct(const Array &, const Array &)
template class providing a null value for a given type.
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