QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
array.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
5 Copyright (C) 2003, 2004, 2005, 2006, 2009 StatPro Italia srl
6 Copyright (C) 2004 Ferdinando Ametrano
7
8 This file is part of QuantLib, a free-software/open-source library
9 for financial quantitative analysts and developers - http://quantlib.org/
10
11 QuantLib is free software: you can redistribute it and/or modify it
12 under the terms of the QuantLib license. You should have received a
13 copy of the license along with this program; if not, please email
14 <quantlib-dev@lists.sf.net>. The license is also available online at
15 <http://quantlib.org/license.shtml>.
16
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the license for more details.
20*/
21
22/*! \file array.hpp
23 \brief 1-D array used in linear algebra.
24*/
25
26#ifndef quantlib_array_hpp
27#define quantlib_array_hpp
28
29#include <ql/types.hpp>
30#include <ql/errors.hpp>
31#include <ql/utilities/null.hpp>
32#include <iterator>
33#include <functional>
34#include <algorithm>
35#include <numeric>
36#include <vector>
37#include <initializer_list>
38#include <iomanip>
39#include <memory>
40#include <type_traits>
41
42namespace QuantLib {
43
44 //! 1-D array used in linear algebra.
45 /*! This class implements the concept of vector as used in linear
46 algebra.
47 As such, it is <b>not</b> meant to be used as a container -
48 <tt>std::vector</tt> should be used instead.
49
50 \test construction of arrays is checked in a number of cases
51 */
52 class Array {
53 public:
54 //! \name Constructors, destructor, and assignment
55 //@{
56 //! creates the array with size 0
57 Array() : Array(static_cast<Size>(0)) {}
58 //! creates the array with the given dimension
59 explicit Array(Size size);
60 //! creates the array and fills it with <tt>value</tt>
61 Array(Size size, Real value);
62 /*! \brief creates the array and fills it according to
63 \f$ a_{0} = value, a_{i}=a_{i-1}+increment \f$
64 */
65 Array(Size size, Real value, Real increment);
66 Array(const Array&);
67 Array(Array&&) noexcept;
68 Array(std::initializer_list<Real>);
69 //! creates the array from an iterable sequence
70 template <class ForwardIterator>
71 Array(ForwardIterator begin, ForwardIterator end);
72 ~Array() = default;
73
74 Array& operator=(const Array&);
75 Array& operator=(Array&&) noexcept;
76
77 bool operator==(const Array&) const;
78 bool operator!=(const Array&) const;
79 //@}
80 /*! \name Vector algebra
81
82 <tt>v += x</tt> and similar operation involving a scalar value
83 are shortcuts for \f$ \forall i : v_i = v_i + x \f$
84
85 <tt>v *= w</tt> and similar operation involving two vectors are
86 shortcuts for \f$ \forall i : v_i = v_i \times w_i \f$
87
88 \pre all arrays involved in an algebraic expression must have
89 the same size.
90 */
91 //@{
92 const Array& operator+=(const Array&);
93 const Array& operator+=(Real);
94 const Array& operator-=(const Array&);
95 const Array& operator-=(Real);
96 const Array& operator*=(const Array&);
97 const Array& operator*=(Real);
98 const Array& operator/=(const Array&);
99 const Array& operator/=(Real);
100 //@}
101 //! \name Element access
102 //@{
103 //! read-only
104 Real operator[](Size) const;
105 Real at(Size) const;
106 Real front() const;
107 Real back() const;
108 //! read-write
109 Real& operator[](Size);
110 Real& at(Size);
111 Real& front();
112 Real& back();
113 //@}
114 //! \name Inspectors
115 //@{
116 //! dimension of the array
117 Size size() const;
118 //! whether the array is empty
119 bool empty() const;
120 //@}
123 typedef Real* iterator;
124 typedef const Real* const_iterator;
127 //! \name Iterator access
128 //@{
129 const_iterator begin() const;
130 iterator begin();
131 const_iterator end() const;
132 iterator end();
137 //@}
138 //! \name Utilities
139 //@{
140 void resize(Size n);
141 void swap(Array&) noexcept;
142 //@}
143
144 private:
145 std::unique_ptr<Real[]> data_;
147 };
148
149 #ifdef QL_NULL_AS_FUNCTIONS
150
151 //! specialization of null template for this class
152 template <>
153 inline Array Null<Array>() {
154 return {};
155 }
156
157 #else
158
159 //! specialization of null template for this class
160 template <>
161 class Null<Array> {
162 public:
163 Null() = default;
164 operator Array() const { return Array(); }
165 };
166
167 #endif
168
169 /*! \relates Array */
170 Real DotProduct(const Array&, const Array&);
171
172 /*! \relates Array */
173 Real Norm2(const Array&);
174
175 // unary operators
176 /*! \relates Array */
177 Array operator+(const Array& v);
178 /*! \relates Array */
180 /*! \relates Array */
181 Array operator-(const Array& v);
182 /*! \relates Array */
184
185 // binary operators
186 /*! \relates Array */
187 Array operator+(const Array&, const Array&);
188 /*! \relates Array */
189 Array operator+(const Array&, Array&&);
190 /*! \relates Array */
191 Array operator+(Array&&, const Array&);
192 /*! \relates Array */
194 /*! \relates Array */
195 Array operator+(const Array&, Real);
196 /*! \relates Array */
198 /*! \relates Array */
199 Array operator+(Real, const Array&);
200 /*! \relates Array */
202 /*! \relates Array */
203 Array operator-(const Array&, const Array&);
204 /*! \relates Array */
205 Array operator-(const Array&, Array&&);
206 /*! \relates Array */
207 Array operator-(Array&&, const Array&);
208 /*! \relates Array */
210 /*! \relates Array */
211 Array operator-(const Array&, Real);
212 /*! \relates Array */
213 Array operator-(Real, const Array&);
214 /*! \relates Array */
216 /*! \relates Array */
218 /*! \relates Array */
219 Array operator*(const Array&, const Array&);
220 /*! \relates Array */
221 Array operator*(const Array&, Array&&);
222 /*! \relates Array */
223 Array operator*(Array&&, const Array&);
224 /*! \relates Array */
226 /*! \relates Array */
227 Array operator*(const Array&, Real);
228 /*! \relates Array */
229 Array operator*(Real, const Array&);
230 /*! \relates Array */
232 /*! \relates Array */
234 /*! \relates Array */
235 Array operator/(const Array&, const Array&);
236 /*! \relates Array */
237 Array operator/(const Array&, Array&&);
238 /*! \relates Array */
239 Array operator/(Array&&, const Array&);
240 /*! \relates Array */
242 /*! \relates Array */
243 Array operator/(const Array&, Real);
244 /*! \relates Array */
245 Array operator/(Real, const Array&);
246 /*! \relates Array */
248 /*! \relates Array */
250
251 // math functions
252 /*! \relates Array */
253 Array Abs(const Array&);
254 /*! \relates Array */
255 Array Abs(Array&&);
256 /*! \relates Array */
257 Array Sqrt(const Array&);
258 /*! \relates Array */
259 Array Sqrt(Array&&);
260 /*! \relates Array */
261 Array Log(const Array&);
262 /*! \relates Array */
263 Array Log(Array&&);
264 /*! \relates Array */
265 Array Exp(const Array&);
266 /*! \relates Array */
267 Array Exp(Array&&);
268 /*! \relates Array */
269 Array Pow(const Array&, Real);
270 /*! \relates Array */
271 Array Pow(Array&&, Real);
272
273 // utilities
274 /*! \relates Array */
275 void swap(Array&, Array&) noexcept;
276
277 // format
278 /*! \relates Array */
279 std::ostream& operator<<(std::ostream&, const Array&);
280
281
282 // inline definitions
283
285 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {}
286
287 inline Array::Array(Size size, Real value)
288 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {
289 std::fill(begin(),end(),value);
290 }
291
292 inline Array::Array(Size size, Real value, Real increment)
293 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {
294 for (iterator i=begin(); i!=end(); ++i, value+=increment)
295 *i = value;
296 }
297
298 inline Array::Array(const Array& from)
299 : data_(from.n_ != 0U ? new Real[from.n_] : (Real*)nullptr), n_(from.n_) {
300 if (data_)
301 std::copy(from.begin(),from.end(),begin());
302 }
303
304 inline Array::Array(Array&& from) noexcept
305 : data_((Real*)nullptr), n_(0) {
306 swap(from);
307 }
308
309 namespace detail {
310
311 template <class I>
312 inline void _fill_array_(Array& a,
313 std::unique_ptr<Real[]>& data_,
314 Size& n_,
315 I begin, I end,
316 const std::true_type&) {
317 // we got redirected here from a call like Array(3, 4)
318 // because it matched the constructor below exactly with
319 // ForwardIterator = int. What we wanted was fill an
320 // Array with a given value, which we do here.
321 Size n = begin;
322 Real value = end;
323 data_.reset(n ? new Real[n] : (Real*)nullptr);
324 n_ = n;
325 std::fill(a.begin(),a.end(),value);
326 }
327
328 template <class I>
329 inline void _fill_array_(Array& a,
330 std::unique_ptr<Real[]>& data_,
331 Size& n_,
332 I begin, I end,
333 const std::false_type&) {
334 // true iterators
335 Size n = std::distance(begin, end);
336 data_.reset(n ? new Real[n] : (Real*)nullptr);
337 n_ = n;
338 #if defined(QL_PATCH_MSVC) && defined(QL_DEBUG)
339 if (n_)
340 #endif
341 std::copy(begin, end, a.begin());
342 }
343
344 }
345
346 inline Array::Array(std::initializer_list<Real> init) {
347 detail::_fill_array_(*this, data_, n_, init.begin(), init.end(),
348 std::false_type());
349 }
350
351 template <class ForwardIterator>
352 inline Array::Array(ForwardIterator begin, ForwardIterator end) {
353 // Unfortunately, calls such as Array(3, 4) match this constructor.
354 // We have to detect integral types and dispatch.
356 std::is_integral<ForwardIterator>());
357 }
358
359 inline Array& Array::operator=(const Array& from) {
360 // strong guarantee
361 Array temp(from);
362 swap(temp);
363 return *this;
364 }
365
366 inline Array& Array::operator=(Array&& from) noexcept {
367 swap(from);
368 return *this;
369 }
370
371 inline bool Array::operator==(const Array& to) const {
372 return (n_ == to.n_) && std::equal(begin(), end(), to.begin());
373 }
374
375 inline bool Array::operator!=(const Array& to) const {
376 return !(this->operator==(to));
377 }
378
379 inline const Array& Array::operator+=(const Array& v) {
380 QL_REQUIRE(n_ == v.n_,
381 "arrays with different sizes (" << n_ << ", "
382 << v.n_ << ") cannot be added");
383 std::transform(begin(),end(),v.begin(),begin(), std::plus<>());
384 return *this;
385 }
386
387
388 inline const Array& Array::operator+=(Real x) {
389 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y + x; });
390 return *this;
391 }
392
393 inline const Array& Array::operator-=(const Array& v) {
394 QL_REQUIRE(n_ == v.n_,
395 "arrays with different sizes (" << n_ << ", "
396 << v.n_ << ") cannot be subtracted");
397 std::transform(begin(), end(), v.begin(), begin(), std::minus<>());
398 return *this;
399 }
400
401 inline const Array& Array::operator-=(Real x) {
402 std::transform(begin(),end(),begin(), [=](Real y) -> Real { return y - x; });
403 return *this;
404 }
405
406 inline const Array& Array::operator*=(const Array& v) {
407 QL_REQUIRE(n_ == v.n_,
408 "arrays with different sizes (" << n_ << ", "
409 << v.n_ << ") cannot be multiplied");
410 std::transform(begin(), end(), v.begin(), begin(), std::multiplies<>());
411 return *this;
412 }
413
414 inline const Array& Array::operator*=(Real x) {
415 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y * x; });
416 return *this;
417 }
418
419 inline const Array& Array::operator/=(const Array& v) {
420 QL_REQUIRE(n_ == v.n_,
421 "arrays with different sizes (" << n_ << ", "
422 << v.n_ << ") cannot be divided");
423 std::transform(begin(), end(), v.begin(), begin(), std::divides<>());
424 return *this;
425 }
426
427 inline const Array& Array::operator/=(Real x) {
428 #if defined(QL_EXTRA_SAFETY_CHECKS)
429 QL_REQUIRE(x != 0.0, "division by zero");
430 #endif
431 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y / x; });
432 return *this;
433 }
434
435 inline Real Array::operator[](Size i) const {
436 #if defined(QL_EXTRA_SAFETY_CHECKS)
437 QL_REQUIRE(i<n_,
438 "index (" << i << ") must be less than " << n_ <<
439 ": array access out of range");
440 #endif
441 return data_.get()[i];
442 }
443
444 inline Real Array::at(Size i) const {
445 QL_REQUIRE(i<n_,
446 "index (" << i << ") must be less than " << n_ <<
447 ": array access out of range");
448 return data_.get()[i];
449 }
450
451 inline Real Array::front() const {
452 #if defined(QL_EXTRA_SAFETY_CHECKS)
453 QL_REQUIRE(n_>0, "null Array: array access out of range");
454 #endif
455 return data_.get()[0];
456 }
457
458 inline Real Array::back() const {
459 #if defined(QL_EXTRA_SAFETY_CHECKS)
460 QL_REQUIRE(n_>0, "null Array: array access out of range");
461 #endif
462 return data_.get()[n_-1];
463 }
464
466 #if defined(QL_EXTRA_SAFETY_CHECKS)
467 QL_REQUIRE(i<n_,
468 "index (" << i << ") must be less than " << n_ <<
469 ": array access out of range");
470 #endif
471 return data_.get()[i];
472 }
473
474 inline Real& Array::at(Size i) {
475 QL_REQUIRE(i<n_,
476 "index (" << i << ") must be less than " << n_ <<
477 ": array access out of range");
478 return data_.get()[i];
479 }
480
481 inline Real& Array::front() {
482 #if defined(QL_EXTRA_SAFETY_CHECKS)
483 QL_REQUIRE(n_>0, "null Array: array access out of range");
484 #endif
485 return data_.get()[0];
486 }
487
488 inline Real& Array::back() {
489 #if defined(QL_EXTRA_SAFETY_CHECKS)
490 QL_REQUIRE(n_>0, "null Array: array access out of range");
491 #endif
492 return data_.get()[n_-1];
493 }
494
495 inline Size Array::size() const {
496 return n_;
497 }
498
499 inline bool Array::empty() const {
500 return n_ == 0;
501 }
502
504 return data_.get();
505 }
506
508 return data_.get();
509 }
510
512 return data_.get()+n_;
513 }
514
516 return data_.get()+n_;
517 }
518
520 return const_reverse_iterator(end());
521 }
522
524 return reverse_iterator(end());
525 }
526
529 }
530
532 return reverse_iterator(begin());
533 }
534
535 inline void Array::resize(Size n) {
536 if (n > n_) {
537 Array swp(n);
538 std::copy(begin(), end(), swp.begin());
539 swap(swp);
540 }
541 else if (n < n_) {
542 n_ = n;
543 }
544 }
545
546 inline void Array::swap(Array& from) noexcept {
547 data_.swap(from.data_);
548 std::swap(n_, from.n_);
549 }
550
551 // dot product and norm
552
553 inline Real DotProduct(const Array& v1, const Array& v2) {
554 QL_REQUIRE(v1.size() == v2.size(),
555 "arrays with different sizes (" << v1.size() << ", "
556 << v2.size() << ") cannot be multiplied");
557 return std::inner_product(v1.begin(),v1.end(),v2.begin(),Real(0.0));
558 }
559
560 inline Real Norm2(const Array& v) {
561 return std::sqrt(DotProduct(v, v));
562 }
563
564 // overloaded operators
565
566 // unary
567
568 inline Array operator+(const Array& v) {
569 Array result = v;
570 return result;
571 }
572
573 inline Array operator+(Array&& v) {
574 return std::move(v);
575 }
576
577 inline Array operator-(const Array& v) {
578 Array result(v.size());
579 std::transform(v.begin(), v.end(), result.begin(), std::negate<>());
580 return result;
581 }
582
583 inline Array operator-(Array&& v) {
584 Array result = std::move(v);
585 std::transform(result.begin(), result.end(), result.begin(), std::negate<>());
586 return result;
587 }
588
589 // binary operators
590
591 inline Array operator+(const Array& v1, const Array& v2) {
592 QL_REQUIRE(v1.size() == v2.size(),
593 "arrays with different sizes (" << v1.size() << ", "
594 << v2.size() << ") cannot be added");
595 Array result(v1.size());
596 std::transform(v1.begin(),v1.end(),v2.begin(),result.begin(), std::plus<>());
597 return result;
598 }
599
600 inline Array operator+(const Array& v1, Array&& v2) {
601 QL_REQUIRE(v1.size() == v2.size(),
602 "arrays with different sizes (" << v1.size() << ", "
603 << v2.size() << ") cannot be added");
604 Array result = std::move(v2);
605 std::transform(v1.begin(), v1.end(), result.begin(), result.begin(), std::plus<>());
606 return result;
607 }
608
609 inline Array operator+(Array&& v1, const Array& v2) {
610 QL_REQUIRE(v1.size() == v2.size(),
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<>());
615 return result;
616 }
617
618 inline Array operator+(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
619 QL_REQUIRE(v1.size() == v2.size(),
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<>());
624 return result;
625 }
626
627 inline Array operator+(const Array& v1, Real a) {
628 Array result(v1.size());
629 std::transform(v1.begin(), v1.end(), result.begin(), [=](Real y) -> Real { return y + a; });
630 return result;
631 }
632
633 inline Array operator+(Array&& v1, Real a) {
634 Array result = std::move(v1);
635 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y + a; });
636 return result;
637 }
638
639 inline Array operator+(Real a, const Array& v2) {
640 Array result(v2.size());
641 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a + y; });
642 return result;
643 }
644
645 inline Array operator+(Real a, Array&& v2) {
646 Array result = std::move(v2);
647 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a + y; });
648 return result;
649 }
650
651 inline Array operator-(const Array& v1, const Array& v2) {
652 QL_REQUIRE(v1.size() == v2.size(),
653 "arrays with different sizes (" << v1.size() << ", "
654 << v2.size() << ") cannot be subtracted");
655 Array result(v1.size());
656 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::minus<>());
657 return result;
658 }
659
660 inline Array operator-(const Array& v1, Array&& v2) {
661 QL_REQUIRE(v1.size() == v2.size(),
662 "arrays with different sizes (" << v1.size() << ", "
663 << v2.size() << ") cannot be subtracted");
664 Array result = std::move(v2);
665 std::transform(v1.begin(), v1.end(), result.begin(), result.begin(), std::minus<>());
666 return result;
667 }
668
669 inline Array operator-(Array&& v1, const Array& v2) {
670 QL_REQUIRE(v1.size() == v2.size(),
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<>());
675 return result;
676 }
677
678 inline Array operator-(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
679 QL_REQUIRE(v1.size() == v2.size(),
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<>());
684 return result;
685 }
686
687 inline Array operator-(const Array& v1, Real a) {
688 Array result(v1.size());
689 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y - a; });
690 return result;
691 }
692
693 inline Array operator-(Array&& v1, Real a) {
694 Array result = std::move(v1);
695 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y - a; });
696 return result;
697 }
698
699 inline Array operator-(Real a, const Array& v2) {
700 Array result(v2.size());
701 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a - y; });
702 return result;
703 }
704
705 inline Array operator-(Real a, Array&& v2) {
706 Array result = std::move(v2);
707 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a - y; });
708 return result;
709 }
710
711 inline Array operator*(const Array& v1, const Array& v2) {
712 QL_REQUIRE(v1.size() == v2.size(),
713 "arrays with different sizes (" << v1.size() << ", "
714 << v2.size() << ") cannot be multiplied");
715 Array result(v1.size());
716 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::multiplies<>());
717 return result;
718 }
719
720 inline Array operator*(const Array& v1, Array&& v2) {
721 QL_REQUIRE(v1.size() == v2.size(),
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<>());
726 return result;
727 }
728
729 inline Array operator*(Array&& v1, const Array& v2) {
730 QL_REQUIRE(v1.size() == v2.size(),
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<>());
735 return result;
736 }
737
738 inline Array operator*(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
739 QL_REQUIRE(v1.size() == v2.size(),
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<>());
744 return result;
745 }
746
747 inline Array operator*(const Array& v1, Real a) {
748 Array result(v1.size());
749 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y * a; });
750 return result;
751 }
752
753 inline Array operator*(Array&& v1, Real a) {
754 Array result = std::move(v1);
755 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y * a; });
756 return result;
757 }
758
759 inline Array operator*(Real a, const Array& v2) {
760 Array result(v2.size());
761 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a * y; });
762 return result;
763 }
764
765 inline Array operator*(Real a, Array&& v2) {
766 Array result = std::move(v2);
767 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a * y; });
768 return result;
769 }
770
771 inline Array operator/(const Array& v1, const Array& v2) {
772 QL_REQUIRE(v1.size() == v2.size(),
773 "arrays with different sizes (" << v1.size() << ", "
774 << v2.size() << ") cannot be divided");
775 Array result(v1.size());
776 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::divides<>());
777 return result;
778 }
779
780 inline Array operator/(const Array& v1, Array&& v2) {
781 QL_REQUIRE(v1.size() == v2.size(),
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<>());
786 return result;
787 }
788
789 inline Array operator/(Array&& v1, const Array& v2) {
790 QL_REQUIRE(v1.size() == v2.size(),
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<>());
795 return result;
796 }
797
798 inline Array operator/(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
799 QL_REQUIRE(v1.size() == v2.size(),
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<>());
804 return result;
805 }
806
807 inline Array operator/(const Array& v1, Real a) {
808 Array result(v1.size());
809 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y / a; });
810 return result;
811 }
812
813 inline Array operator/(Array&& v1, Real a) {
814 Array result = std::move(v1);
815 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y / a; });
816 return result;
817 }
818
819 inline Array operator/(Real a, const Array& v2) {
820 Array result(v2.size());
821 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a / y; });
822 return result;
823 }
824
825 inline Array operator/(Real a, Array&& v2) {
826 Array result = std::move(v2);
827 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a / y; });
828 return result;
829 }
830
831 // functions
832
833 inline Array Abs(const Array& v) {
834 Array result(v.size());
835 std::transform(v.begin(), v.end(), result.begin(),
836 [](Real x) -> Real { return std::fabs(x); });
837 return result;
838 }
839
840 inline Array Abs(Array&& v) {
841 Array result = std::move(v);
842 std::transform(result.begin(), result.end(), result.begin(),
843 [](Real x) -> Real { return std::fabs(x); });
844 return result;
845 }
846
847 inline Array Sqrt(const Array& v) {
848 Array result(v.size());
849 std::transform(v.begin(),v.end(),result.begin(),
850 [](Real x) -> Real { return std::sqrt(x); });
851 return result;
852 }
853
854 inline Array Sqrt(Array&& v) {
855 Array result = std::move(v);
856 std::transform(result.begin(), result.end(), result.begin(),
857 [](Real x) -> Real { return std::sqrt(x); });
858 return result;
859 }
860
861 inline Array Log(const Array& v) {
862 Array result(v.size());
863 std::transform(v.begin(),v.end(),result.begin(),
864 [](Real x) -> Real { return std::log(x); });
865 return result;
866 }
867
868 inline Array Log(Array&& v) {
869 Array result = std::move(v);
870 std::transform(result.begin(), result.end(), result.begin(),
871 [](Real x) -> Real { return std::log(x); });
872 return result;
873 }
874
875 inline Array Exp(const Array& v) {
876 Array result(v.size());
877 std::transform(v.begin(), v.end(), result.begin(),
878 [](Real x) -> Real { return std::exp(x); });
879 return result;
880 }
881
882 inline Array Exp(Array&& v) {
883 Array result = std::move(v);
884 std::transform(result.begin(), result.end(), result.begin(),
885 [](Real x) -> Real { return std::exp(x); });
886 return result;
887 }
888
889 inline Array Pow(const Array& v, Real alpha) {
890 Array result(v.size());
891 std::transform(v.begin(), v.end(), result.begin(),
892 [=](Real x) -> Real { return std::pow(x, alpha); });
893 return result;
894 }
895
896 inline Array Pow(Array&& v, Real alpha) {
897 Array result = std::move(v);
898 std::transform(result.begin(), result.end(), result.begin(),
899 [=](Real x) -> Real { return std::pow(x, alpha); });
900 return result;
901 }
902
903 inline void swap(Array& v, Array& w) noexcept {
904 v.swap(w);
905 }
906
907 inline std::ostream& operator<<(std::ostream& out, const Array& a) {
908 std::streamsize width = out.width();
909 out << "[ ";
910 if (!a.empty()) {
911 for (Size n=0; n<a.size()-1; ++n)
912 out << std::setw(int(width)) << a[n] << "; ";
913 out << std::setw(int(width)) << a.back();
914 }
915 out << " ]";
916 return out;
917 }
918
919}
920
921
922#endif
1-D array used in linear algebra.
Definition: array.hpp:52
const Real * const_iterator
Definition: array.hpp:124
const Array & operator*=(const Array &)
Definition: array.hpp:406
Array Abs(const Array &)
Definition: array.hpp:833
std::unique_ptr< Real[]> data_
Definition: array.hpp:145
bool operator!=(const Array &) const
Definition: array.hpp:375
Size size_type
Definition: array.hpp:121
Array operator/(const Array &, const Array &)
Definition: array.hpp:771
bool operator==(const Array &) const
Definition: array.hpp:371
Array & operator=(const Array &)
Definition: array.hpp:359
Real * iterator
Definition: array.hpp:123
Array Pow(const Array &, Real)
Definition: array.hpp:889
std::ostream & operator<<(std::ostream &, const Array &)
Definition: array.hpp:907
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: array.hpp:126
Array operator-(const Array &v)
Definition: array.hpp:577
Real operator[](Size) const
read-only
Definition: array.hpp:435
bool empty() const
whether the array is empty
Definition: array.hpp:499
Real value_type
Definition: array.hpp:122
const_reverse_iterator rend() const
Definition: array.hpp:527
const Array & operator/=(const Array &)
Definition: array.hpp:419
const Array & operator-=(const Array &)
Definition: array.hpp:393
const Array & operator+=(const Array &)
Definition: array.hpp:379
Array Exp(const Array &)
Definition: array.hpp:875
const_reverse_iterator rbegin() const
Definition: array.hpp:519
void swap(Array &) noexcept
Definition: array.hpp:546
Array Sqrt(const Array &)
Definition: array.hpp:847
const_iterator end() const
Definition: array.hpp:511
Array Log(const Array &)
Definition: array.hpp:861
std::reverse_iterator< iterator > reverse_iterator
Definition: array.hpp:125
Array operator*(const Array &, const Array &)
Definition: array.hpp:711
void resize(Size n)
Definition: array.hpp:535
Real Norm2(const Array &)
Definition: array.hpp:560
Real at(Size) const
Definition: array.hpp:444
Real back() const
Definition: array.hpp:458
Array operator+(const Array &v)
Definition: array.hpp:568
Size size() const
dimension of the array
Definition: array.hpp:495
Real front() const
Definition: array.hpp:451
const_iterator begin() const
Definition: array.hpp:503
Array()
creates the array with size 0
Definition: array.hpp:57
Real DotProduct(const Array &, const Array &)
Definition: array.hpp:553
template class providing a null value for a given type.
Definition: null.hpp:76
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
QL_REAL Real
real number
Definition: types.hpp:50
std::size_t Size
size of a container
Definition: types.hpp:58
void _fill_array_(Array &a, std::unique_ptr< Real[]> &data_, Size &n_, I begin, I end, const std::true_type &)
Definition: array.hpp:312
Definition: any.hpp:35
Quantity operator-(const Quantity &m1, const Quantity &m2)
Definition: quantity.hpp:171
Quantity operator*(const Quantity &m, Real x)
Definition: quantity.hpp:177
Array Pow(const Array &v, Real alpha)
Definition: array.hpp:889
Array Log(const Array &v)
Definition: array.hpp:861
std::ostream & operator<<(std::ostream &out, GFunctionFactory::YieldCurveModel type)
Quantity operator+(const Quantity &m1, const Quantity &m2)
Definition: quantity.hpp:165
void swap(Array &v, Array &w) noexcept
Definition: array.hpp:903
Array Abs(const Array &v)
Definition: array.hpp:833
Array Exp(const Array &v)
Definition: array.hpp:875
Array Sqrt(const Array &v)
Definition: array.hpp:847
Real Norm2(const Array &v)
Definition: array.hpp:560
Real DotProduct(const Array &v1, const Array &v2)
Definition: array.hpp:553
Real operator/(const Quantity &m1, const Quantity &m2)
Definition: quantity.cpp:86
STL namespace.
null values
ext::shared_ptr< BlackVolTermStructure > v
Real alpha
Definition: sabr.cpp:200
Custom types.