QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
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 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T, Real>>>
70 Array(std::initializer_list<T> init);
71 //! creates the array from an iterable sequence
72 template <class ForwardIterator>
73 Array(ForwardIterator begin, ForwardIterator end);
74 ~Array() = default;
75
76 Array& operator=(const Array&);
77 Array& operator=(Array&&) noexcept;
78
79 bool operator==(const Array&) const;
80 bool operator!=(const Array&) const;
81 //@}
82 /*! \name Vector algebra
83
84 <tt>v += x</tt> and similar operation involving a scalar value
85 are shortcuts for \f$ \forall i : v_i = v_i + x \f$
86
87 <tt>v *= w</tt> and similar operation involving two vectors are
88 shortcuts for \f$ \forall i : v_i = v_i \times w_i \f$
89
90 \pre all arrays involved in an algebraic expression must have
91 the same size.
92 */
93 //@{
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 const Array& operator/=(const Array&);
101 const Array& operator/=(Real);
102 //@}
103 //! \name Element access
104 //@{
105 //! read-only
106 Real operator[](Size) const;
107 Real at(Size) const;
108 Real front() const;
109 Real back() const;
110 //! read-write
111 Real& operator[](Size);
112 Real& at(Size);
113 Real& front();
114 Real& back();
115 //@}
116 //! \name Inspectors
117 //@{
118 //! dimension of the array
119 Size size() const;
120 //! whether the array is empty
121 bool empty() const;
122 //@}
125 typedef Real* iterator;
126 typedef const Real* const_iterator;
129 //! \name Iterator access
130 //@{
131 const_iterator begin() const;
132 iterator begin();
133 const_iterator end() const;
134 iterator end();
139 //@}
140 //! \name Utilities
141 //@{
142 void resize(Size n);
143 void swap(Array&) noexcept;
144 //@}
145
146 private:
147 std::unique_ptr<Real[]> data_;
149 };
150
151
152 /*! \relates Array */
153 Real DotProduct(const Array&, const Array&);
154
155 /*! \relates Array */
156 Real Norm2(const Array&);
157
158 // unary operators
159 /*! \relates Array */
160 Array operator+(const Array& v);
161 /*! \relates Array */
162 Array operator+(Array&& v);
163 /*! \relates Array */
164 Array operator-(const Array& v);
165 /*! \relates Array */
166 Array operator-(Array&& v);
167
168 // binary operators
169 /*! \relates Array */
170 Array operator+(const Array&, const Array&);
171 /*! \relates Array */
172 Array operator+(const Array&, Array&&);
173 /*! \relates Array */
174 Array operator+(Array&&, const Array&);
175 /*! \relates Array */
176 Array operator+(Array&&, Array&&);
177 /*! \relates Array */
178 Array operator+(const Array&, Real);
179 /*! \relates Array */
180 Array operator+(Array&&, Real);
181 /*! \relates Array */
182 Array operator+(Real, const Array&);
183 /*! \relates Array */
184 Array operator+(Real, Array&&);
185 /*! \relates Array */
186 Array operator-(const Array&, const Array&);
187 /*! \relates Array */
188 Array operator-(const Array&, Array&&);
189 /*! \relates Array */
190 Array operator-(Array&&, const Array&);
191 /*! \relates Array */
192 Array operator-(Array&&, Array&&);
193 /*! \relates Array */
194 Array operator-(const Array&, Real);
195 /*! \relates Array */
196 Array operator-(Real, const Array&);
197 /*! \relates Array */
198 Array operator-(Array&&, Real);
199 /*! \relates Array */
200 Array operator-(Real, Array&&);
201 /*! \relates Array */
202 Array operator*(const Array&, const Array&);
203 /*! \relates Array */
204 Array operator*(const Array&, Array&&);
205 /*! \relates Array */
206 Array operator*(Array&&, const Array&);
207 /*! \relates Array */
208 Array operator*(Array&&, Array&&);
209 /*! \relates Array */
210 Array operator*(const Array&, Real);
211 /*! \relates Array */
212 Array operator*(Real, const Array&);
213 /*! \relates Array */
214 Array operator*(Array&&, Real);
215 /*! \relates Array */
216 Array operator*(Real, Array&&);
217 /*! \relates Array */
218 Array operator/(const Array&, const Array&);
219 /*! \relates Array */
220 Array operator/(const Array&, Array&&);
221 /*! \relates Array */
222 Array operator/(Array&&, const Array&);
223 /*! \relates Array */
224 Array operator/(Array&&, Array&&);
225 /*! \relates Array */
226 Array operator/(const Array&, Real);
227 /*! \relates Array */
228 Array operator/(Real, const Array&);
229 /*! \relates Array */
230 Array operator/(Array&&, Real);
231 /*! \relates Array */
232 Array operator/(Real, Array&&);
233
234 // math functions
235 /*! \relates Array */
236 Array Abs(const Array&);
237 /*! \relates Array */
238 Array Abs(Array&&);
239 /*! \relates Array */
240 Array Sqrt(const Array&);
241 /*! \relates Array */
242 Array Sqrt(Array&&);
243 /*! \relates Array */
244 Array Log(const Array&);
245 /*! \relates Array */
246 Array Log(Array&&);
247 /*! \relates Array */
248 Array Exp(const Array&);
249 /*! \relates Array */
250 Array Exp(Array&&);
251 /*! \relates Array */
252 Array Pow(const Array&, Real);
253 /*! \relates Array */
254 Array Pow(Array&&, Real);
255
256 // utilities
257 /*! \relates Array */
258 void swap(Array&, Array&) noexcept;
259
260 // format
261 /*! \relates Array */
262 std::ostream& operator<<(std::ostream&, const Array&);
263
264
265 // inline definitions
266
268 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {}
269
270 inline Array::Array(Size size, Real value)
271 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {
272 std::fill(begin(),end(),value);
273 }
274
275 inline Array::Array(Size size, Real value, Real increment)
276 : data_(size != 0U ? new Real[size] : (Real*)nullptr), n_(size) {
277 for (iterator i=begin(); i!=end(); ++i, value+=increment)
278 *i = value;
279 }
280
281 inline Array::Array(const Array& from)
282 : data_(from.n_ != 0U ? new Real[from.n_] : (Real*)nullptr), n_(from.n_) {
283 if (data_)
284 std::copy(from.begin(),from.end(),begin());
285 }
286
287 inline Array::Array(Array&& from) noexcept
288 : data_((Real*)nullptr), n_(0) {
289 swap(from);
290 }
291
292 namespace detail {
293
294 template <class I>
295 inline void _fill_array_(Array& a,
296 std::unique_ptr<Real[]>& data_,
297 Size& n_,
298 I begin, I end,
299 const std::true_type&) {
300 // we got redirected here from a call like Array(3, 4)
301 // because it matched the constructor below exactly with
302 // ForwardIterator = int. What we wanted was fill an
303 // Array with a given value, which we do here.
304 Size n = begin;
305 Real value = end;
306 data_.reset(n ? new Real[n] : (Real*)nullptr);
307 n_ = n;
308 std::fill(a.begin(),a.end(),value);
309 }
310
311 template <class I>
312 inline void _fill_array_(Array& a,
313 std::unique_ptr<Real[]>& data_,
314 Size& n_,
315 const I& begin, const I& end,
316 const std::false_type&) {
317 // true iterators
318 Size n = std::distance(begin, end);
319 data_.reset(n ? new Real[n] : (Real*)nullptr);
320 n_ = n;
321 #if defined(QL_PATCH_MSVC) && defined(QL_DEBUG)
322 if (n_)
323 #endif
324 std::copy(begin, end, a.begin());
325 }
326
327 }
328
329 inline Array::Array(std::initializer_list<Real> init) {
330 detail::_fill_array_(*this, data_, n_, init.begin(), init.end(),
331 std::false_type());
332 }
333
334 template <class ForwardIterator>
335 inline Array::Array(ForwardIterator begin, ForwardIterator end) { // NOLINT(performance-unnecessary-value-param)
336 // Unfortunately, calls such as Array(3, 4) match this constructor.
337 // We have to detect integral types and dispatch.
339 std::is_integral<ForwardIterator>());
340 }
341
342 template <typename T, typename>
343 Array::Array(std::initializer_list<T> init) {
344 detail::_fill_array_(*this, data_, n_, init.begin(), init.end(), std::false_type());
345 }
346
347 inline Array& Array::operator=(const Array& from) {
348 // strong guarantee
349 Array temp(from);
350 swap(temp);
351 return *this;
352 }
353
354 inline Array& Array::operator=(Array&& from) noexcept {
355 swap(from);
356 return *this;
357 }
358
359 inline bool Array::operator==(const Array& to) const {
360 return (n_ == to.n_) && std::equal(begin(), end(), to.begin());
361 }
362
363 inline bool Array::operator!=(const Array& to) const {
364 return !(this->operator==(to));
365 }
366
367 inline const Array& Array::operator+=(const Array& v) {
368 QL_REQUIRE(n_ == v.n_,
369 "arrays with different sizes (" << n_ << ", "
370 << v.n_ << ") cannot be added");
371 std::transform(begin(),end(),v.begin(),begin(), std::plus<>());
372 return *this;
373 }
374
375
376 inline const Array& Array::operator+=(Real x) {
377 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y + x; });
378 return *this;
379 }
380
381 inline const Array& Array::operator-=(const Array& v) {
382 QL_REQUIRE(n_ == v.n_,
383 "arrays with different sizes (" << n_ << ", "
384 << v.n_ << ") cannot be subtracted");
385 std::transform(begin(), end(), v.begin(), begin(), std::minus<>());
386 return *this;
387 }
388
389 inline const Array& Array::operator-=(Real x) {
390 std::transform(begin(),end(),begin(), [=](Real y) -> Real { return y - x; });
391 return *this;
392 }
393
394 inline const Array& Array::operator*=(const Array& v) {
395 QL_REQUIRE(n_ == v.n_,
396 "arrays with different sizes (" << n_ << ", "
397 << v.n_ << ") cannot be multiplied");
398 std::transform(begin(), end(), v.begin(), begin(), std::multiplies<>());
399 return *this;
400 }
401
402 inline const Array& Array::operator*=(Real x) {
403 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y * x; });
404 return *this;
405 }
406
407 inline const Array& Array::operator/=(const Array& v) {
408 QL_REQUIRE(n_ == v.n_,
409 "arrays with different sizes (" << n_ << ", "
410 << v.n_ << ") cannot be divided");
411 std::transform(begin(), end(), v.begin(), begin(), std::divides<>());
412 return *this;
413 }
414
415 inline const Array& Array::operator/=(Real x) {
416 #if defined(QL_EXTRA_SAFETY_CHECKS)
417 QL_REQUIRE(x != 0.0, "division by zero");
418 #endif
419 std::transform(begin(), end(), begin(), [=](Real y) -> Real { return y / x; });
420 return *this;
421 }
422
423 inline Real Array::operator[](Size i) const {
424 #if defined(QL_EXTRA_SAFETY_CHECKS)
425 QL_REQUIRE(i<n_,
426 "index (" << i << ") must be less than " << n_ <<
427 ": array access out of range");
428 #endif
429 return data_.get()[i];
430 }
431
432 inline Real Array::at(Size i) const {
433 QL_REQUIRE(i<n_,
434 "index (" << i << ") must be less than " << n_ <<
435 ": array access out of range");
436 return data_.get()[i];
437 }
438
439 inline Real Array::front() const {
440 #if defined(QL_EXTRA_SAFETY_CHECKS)
441 QL_REQUIRE(n_>0, "null Array: array access out of range");
442 #endif
443 return data_.get()[0];
444 }
445
446 inline Real Array::back() const {
447 #if defined(QL_EXTRA_SAFETY_CHECKS)
448 QL_REQUIRE(n_>0, "null Array: array access out of range");
449 #endif
450 return data_.get()[n_-1];
451 }
452
454 #if defined(QL_EXTRA_SAFETY_CHECKS)
455 QL_REQUIRE(i<n_,
456 "index (" << i << ") must be less than " << n_ <<
457 ": array access out of range");
458 #endif
459 return data_.get()[i];
460 }
461
462 inline Real& Array::at(Size i) {
463 QL_REQUIRE(i<n_,
464 "index (" << i << ") must be less than " << n_ <<
465 ": array access out of range");
466 return data_.get()[i];
467 }
468
469 inline Real& Array::front() {
470 #if defined(QL_EXTRA_SAFETY_CHECKS)
471 QL_REQUIRE(n_>0, "null Array: array access out of range");
472 #endif
473 return data_.get()[0];
474 }
475
476 inline Real& Array::back() {
477 #if defined(QL_EXTRA_SAFETY_CHECKS)
478 QL_REQUIRE(n_>0, "null Array: array access out of range");
479 #endif
480 return data_.get()[n_-1];
481 }
482
483 inline Size Array::size() const {
484 return n_;
485 }
486
487 inline bool Array::empty() const {
488 return n_ == 0;
489 }
490
492 return data_.get();
493 }
494
496 return data_.get();
497 }
498
500 return data_.get()+n_;
501 }
502
504 return data_.get()+n_;
505 }
506
508 return const_reverse_iterator(end());
509 }
510
512 return reverse_iterator(end());
513 }
514
517 }
518
520 return reverse_iterator(begin());
521 }
522
523 inline void Array::resize(Size n) {
524 if (n > n_) {
525 Array swp(n);
526 std::copy(begin(), end(), swp.begin());
527 swap(swp);
528 }
529 else if (n < n_) {
530 n_ = n;
531 }
532 }
533
534 inline void Array::swap(Array& from) noexcept {
535 data_.swap(from.data_);
536 std::swap(n_, from.n_);
537 }
538
539 // dot product and norm
540
541 inline Real DotProduct(const Array& v1, const Array& v2) {
542 QL_REQUIRE(v1.size() == v2.size(),
543 "arrays with different sizes (" << v1.size() << ", "
544 << v2.size() << ") cannot be multiplied");
545 return std::inner_product(v1.begin(),v1.end(),v2.begin(),Real(0.0));
546 }
547
548 inline Real Norm2(const Array& v) {
549 return std::sqrt(DotProduct(v, v));
550 }
551
552 // overloaded operators
553
554 // unary
555
556 inline Array operator+(const Array& v) {
557 Array result = v;
558 return result;
559 }
560
561 inline Array operator+(Array&& v) {
562 return std::move(v);
563 }
564
565 inline Array operator-(const Array& v) {
566 Array result(v.size());
567 std::transform(v.begin(), v.end(), result.begin(), std::negate<>());
568 return result;
569 }
570
571 inline Array operator-(Array&& v) {
572 Array result = std::move(v);
573 std::transform(result.begin(), result.end(), result.begin(), std::negate<>());
574 return result;
575 }
576
577 // binary operators
578
579 inline Array operator+(const Array& v1, const Array& v2) {
580 QL_REQUIRE(v1.size() == v2.size(),
581 "arrays with different sizes (" << v1.size() << ", "
582 << v2.size() << ") cannot be added");
583 Array result(v1.size());
584 std::transform(v1.begin(),v1.end(),v2.begin(),result.begin(), std::plus<>());
585 return result;
586 }
587
588 inline Array operator+(const Array& v1, Array&& v2) {
589 QL_REQUIRE(v1.size() == v2.size(),
590 "arrays with different sizes (" << v1.size() << ", "
591 << v2.size() << ") cannot be added");
592 Array result = std::move(v2);
593 std::transform(v1.begin(), v1.end(), result.begin(), result.begin(), std::plus<>());
594 return result;
595 }
596
597 inline Array operator+(Array&& v1, const Array& v2) {
598 QL_REQUIRE(v1.size() == v2.size(),
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<>());
603 return result;
604 }
605
606 inline Array operator+(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
607 QL_REQUIRE(v1.size() == v2.size(),
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<>());
612 return result;
613 }
614
615 inline Array operator+(const Array& v1, Real a) {
616 Array result(v1.size());
617 std::transform(v1.begin(), v1.end(), result.begin(), [=](Real y) -> Real { return y + a; });
618 return result;
619 }
620
621 inline Array operator+(Array&& v1, Real a) {
622 Array result = std::move(v1);
623 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y + a; });
624 return result;
625 }
626
627 inline Array operator+(Real a, const Array& v2) {
628 Array result(v2.size());
629 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a + y; });
630 return result;
631 }
632
633 inline Array operator+(Real a, Array&& v2) {
634 Array result = std::move(v2);
635 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a + y; });
636 return result;
637 }
638
639 inline Array operator-(const Array& v1, const Array& v2) {
640 QL_REQUIRE(v1.size() == v2.size(),
641 "arrays with different sizes (" << v1.size() << ", "
642 << v2.size() << ") cannot be subtracted");
643 Array result(v1.size());
644 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::minus<>());
645 return result;
646 }
647
648 inline Array operator-(const Array& v1, Array&& v2) {
649 QL_REQUIRE(v1.size() == v2.size(),
650 "arrays with different sizes (" << v1.size() << ", "
651 << v2.size() << ") cannot be subtracted");
652 Array result = std::move(v2);
653 std::transform(v1.begin(), v1.end(), result.begin(), result.begin(), std::minus<>());
654 return result;
655 }
656
657 inline Array operator-(Array&& v1, const Array& v2) {
658 QL_REQUIRE(v1.size() == v2.size(),
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<>());
663 return result;
664 }
665
666 inline Array operator-(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
667 QL_REQUIRE(v1.size() == v2.size(),
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<>());
672 return result;
673 }
674
675 inline Array operator-(const Array& v1, Real a) {
676 Array result(v1.size());
677 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y - a; });
678 return result;
679 }
680
681 inline Array operator-(Array&& v1, Real a) {
682 Array result = std::move(v1);
683 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y - a; });
684 return result;
685 }
686
687 inline Array operator-(Real a, const Array& v2) {
688 Array result(v2.size());
689 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a - y; });
690 return result;
691 }
692
693 inline Array operator-(Real a, Array&& v2) {
694 Array result = std::move(v2);
695 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a - y; });
696 return result;
697 }
698
699 inline Array operator*(const Array& v1, const Array& v2) {
700 QL_REQUIRE(v1.size() == v2.size(),
701 "arrays with different sizes (" << v1.size() << ", "
702 << v2.size() << ") cannot be multiplied");
703 Array result(v1.size());
704 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::multiplies<>());
705 return result;
706 }
707
708 inline Array operator*(const Array& v1, Array&& v2) {
709 QL_REQUIRE(v1.size() == v2.size(),
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<>());
714 return result;
715 }
716
717 inline Array operator*(Array&& v1, const Array& v2) {
718 QL_REQUIRE(v1.size() == v2.size(),
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<>());
723 return result;
724 }
725
726 inline Array operator*(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
727 QL_REQUIRE(v1.size() == v2.size(),
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<>());
732 return result;
733 }
734
735 inline Array operator*(const Array& v1, Real a) {
736 Array result(v1.size());
737 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y * a; });
738 return result;
739 }
740
741 inline Array operator*(Array&& v1, Real a) {
742 Array result = std::move(v1);
743 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y * a; });
744 return result;
745 }
746
747 inline Array operator*(Real a, const Array& v2) {
748 Array result(v2.size());
749 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a * y; });
750 return result;
751 }
752
753 inline Array operator*(Real a, Array&& v2) {
754 Array result = std::move(v2);
755 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a * y; });
756 return result;
757 }
758
759 inline Array operator/(const Array& v1, const Array& v2) {
760 QL_REQUIRE(v1.size() == v2.size(),
761 "arrays with different sizes (" << v1.size() << ", "
762 << v2.size() << ") cannot be divided");
763 Array result(v1.size());
764 std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(), std::divides<>());
765 return result;
766 }
767
768 inline Array operator/(const Array& v1, Array&& v2) {
769 QL_REQUIRE(v1.size() == v2.size(),
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<>());
774 return result;
775 }
776
777 inline Array operator/(Array&& v1, const Array& v2) {
778 QL_REQUIRE(v1.size() == v2.size(),
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<>());
783 return result;
784 }
785
786 inline Array operator/(Array&& v1, Array&& v2) { // NOLINT(cppcoreguidelines-rvalue-reference-param-not-moved)
787 QL_REQUIRE(v1.size() == v2.size(),
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<>());
792 return result;
793 }
794
795 inline Array operator/(const Array& v1, Real a) {
796 Array result(v1.size());
797 std::transform(v1.begin(),v1.end(),result.begin(), [=](Real y) -> Real { return y / a; });
798 return result;
799 }
800
801 inline Array operator/(Array&& v1, Real a) {
802 Array result = std::move(v1);
803 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return y / a; });
804 return result;
805 }
806
807 inline Array operator/(Real a, const Array& v2) {
808 Array result(v2.size());
809 std::transform(v2.begin(),v2.end(),result.begin(), [=](Real y) -> Real { return a / y; });
810 return result;
811 }
812
813 inline Array operator/(Real a, Array&& v2) {
814 Array result = std::move(v2);
815 std::transform(result.begin(), result.end(), result.begin(), [=](Real y) -> Real { return a / y; });
816 return result;
817 }
818
819 // functions
820
821 inline Array Abs(const Array& v) {
822 Array result(v.size());
823 std::transform(v.begin(), v.end(), result.begin(),
824 [](Real x) -> Real { return std::fabs(x); });
825 return result;
826 }
827
828 inline Array Abs(Array&& v) {
829 Array result = std::move(v);
830 std::transform(result.begin(), result.end(), result.begin(),
831 [](Real x) -> Real { return std::fabs(x); });
832 return result;
833 }
834
835 inline Array Sqrt(const Array& v) {
836 Array result(v.size());
837 std::transform(v.begin(),v.end(),result.begin(),
838 [](Real x) -> Real { return std::sqrt(x); });
839 return result;
840 }
841
842 inline Array Sqrt(Array&& v) {
843 Array result = std::move(v);
844 std::transform(result.begin(), result.end(), result.begin(),
845 [](Real x) -> Real { return std::sqrt(x); });
846 return result;
847 }
848
849 inline Array Log(const Array& v) {
850 Array result(v.size());
851 std::transform(v.begin(),v.end(),result.begin(),
852 [](Real x) -> Real { return std::log(x); });
853 return result;
854 }
855
856 inline Array Log(Array&& v) {
857 Array result = std::move(v);
858 std::transform(result.begin(), result.end(), result.begin(),
859 [](Real x) -> Real { return std::log(x); });
860 return result;
861 }
862
863 inline Array Exp(const Array& v) {
864 Array result(v.size());
865 std::transform(v.begin(), v.end(), result.begin(),
866 [](Real x) -> Real { return std::exp(x); });
867 return result;
868 }
869
870 inline Array Exp(Array&& v) {
871 Array result = std::move(v);
872 std::transform(result.begin(), result.end(), result.begin(),
873 [](Real x) -> Real { return std::exp(x); });
874 return result;
875 }
876
877 inline Array Pow(const Array& v, Real alpha) {
878 Array result(v.size());
879 std::transform(v.begin(), v.end(), result.begin(),
880 [=](Real x) -> Real { return std::pow(x, alpha); });
881 return result;
882 }
883
884 inline Array Pow(Array&& v, Real alpha) {
885 Array result = std::move(v);
886 std::transform(result.begin(), result.end(), result.begin(),
887 [=](Real x) -> Real { return std::pow(x, alpha); });
888 return result;
889 }
890
891 inline void swap(Array& v, Array& w) noexcept {
892 v.swap(w);
893 }
894
895 inline std::ostream& operator<<(std::ostream& out, const Array& a) {
896 std::streamsize width = out.width();
897 out << "[ ";
898 if (!a.empty()) {
899 for (Size n=0; n<a.size()-1; ++n)
900 out << std::setw(int(width)) << a[n] << "; ";
901 out << std::setw(int(width)) << a.back();
902 }
903 out << " ]";
904 return out;
905 }
906
907}
908
909
910#endif
1-D array used in linear algebra.
Definition: array.hpp:52
const Real * const_iterator
Definition: array.hpp:126
const Array & operator*=(const Array &)
Definition: array.hpp:394
Array Abs(const Array &)
Definition: array.hpp:821
std::unique_ptr< Real[]> data_
Definition: array.hpp:147
bool operator!=(const Array &) const
Definition: array.hpp:363
Size size_type
Definition: array.hpp:123
bool operator==(const Array &) const
Definition: array.hpp:359
Array & operator=(const Array &)
Definition: array.hpp:347
Real * iterator
Definition: array.hpp:125
Array Pow(const Array &, Real)
Definition: array.hpp:877
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: array.hpp:128
Real operator[](Size) const
read-only
Definition: array.hpp:423
bool empty() const
whether the array is empty
Definition: array.hpp:487
Real value_type
Definition: array.hpp:124
const_reverse_iterator rend() const
Definition: array.hpp:515
const Array & operator/=(const Array &)
Definition: array.hpp:407
const Array & operator-=(const Array &)
Definition: array.hpp:381
const Array & operator+=(const Array &)
Definition: array.hpp:367
Array Exp(const Array &)
Definition: array.hpp:863
const_reverse_iterator rbegin() const
Definition: array.hpp:507
void swap(Array &) noexcept
Definition: array.hpp:534
Array Sqrt(const Array &)
Definition: array.hpp:835
const_iterator end() const
Definition: array.hpp:499
Array Log(const Array &)
Definition: array.hpp:849
std::reverse_iterator< iterator > reverse_iterator
Definition: array.hpp:127
void resize(Size n)
Definition: array.hpp:523
Real Norm2(const Array &)
Definition: array.hpp:548
Real at(Size) const
Definition: array.hpp:432
Real back() const
Definition: array.hpp:446
Size size() const
dimension of the array
Definition: array.hpp:483
Real front() const
Definition: array.hpp:439
const_iterator begin() const
Definition: array.hpp:491
Array()
creates the array with size 0
Definition: array.hpp:57
Real DotProduct(const Array &, const Array &)
Definition: array.hpp:541
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:295
Definition: any.hpp:37
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:877
Array Log(const Array &v)
Definition: array.hpp:849
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:891
Array Abs(const Array &v)
Definition: array.hpp:821
Array Exp(const Array &v)
Definition: array.hpp:863
Array Sqrt(const Array &v)
Definition: array.hpp:835
Real Norm2(const Array &v)
Definition: array.hpp:548
Real DotProduct(const Array &v1, const Array &v2)
Definition: array.hpp:541
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.