Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
jaggedcube.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file orea/cube/jaggedcube.hpp
20 \brief A cube implementation that stores the cube in memory
21 \ingroup cube
22*/
23#pragma once
24
25#include <fstream>
26#include <iostream>
27#include <ql/errors.hpp>
28#include <vector>
29
30#include <boost/make_shared.hpp>
31#include <orea/cube/npvcube.hpp>
35
36namespace ore {
37namespace analytics {
38using QuantLib::Date;
39using QuantLib::Real;
40using QuantLib::Size;
41using std::vector;
42
43template <typename T> class TradeBlock {
44private:
46 Size depth_;
48 vector<T> data_;
49
50public:
52
53 TradeBlock(Size inputDates, Size inputDepth, Size samples)
54 : dateLen_(inputDates), depth_(inputDepth), samples_(samples) {
55 Size len = (1 + (dateLen_ * samples_)) * depth_;
56 data_ = vector<T>(len, T());
57 }
58
59 Size index(Size date, Size dep, Size sample) const {
60 // calculate index of element
61 return depth_ + // T0 block
62 dep + (sample * depth_) + (date * depth_ * samples_);
63 }
64
65 Size indexT0(Size dep) const { return dep; }
66
67 bool isValid(Size date, Size dep, Size sample) const {
68 // return true if this is valid
69 return date < dateLen_ && sample < samples_ && dep < depth_;
70 }
71
72 bool isValidT0(Size dep) const { return dep < depth_; }
73
74 Real getT0(Size dep) const {
75 if (this->isValidT0(dep)) {
76 return static_cast<Real>(this->data_[indexT0(dep)]);
77 } else {
78 return 0;
79 }
80 }
81
82 void setT0(Real value, Size dep) {
83 if (this->isValidT0(dep)) {
84 this->data_[indexT0(dep)] = static_cast<T>(value);
85 } else {
86 QL_REQUIRE(value == 0, "Cannot set nonzero value for T0 dep = " << dep);
87 }
88 }
89
90 Real get(Size date, Size sample, Size dep) const {
91 // if isValid return the value cast to a Real
92 if (this->isValid(date, dep, sample)) {
93 return static_cast<Real>(this->data_[index(date, dep, sample)]);
94 } else {
95 return 0;
96 }
97 }
98
99 void set(Real value, Size date, Size sample, Size dep) {
100 // if isValid set in the buffer
101 if (this->isValid(date, dep, sample)) {
102 this->data_[index(date, dep, sample)] = static_cast<T>(value);
103 } else {
104 QL_REQUIRE(value == 0,
105 "Cannot set nonzero value for date: " << date << ", depth: " << dep << ", sample: " << sample);
106 }
107 }
108
109private:
111 template <class Archive> void serialize(Archive& ar, const unsigned int) {
112 ar& depth_;
113 ar& dateLen_;
114 ar& samples_;
115 ar& data_;
116 }
117};
118
120public:
121 virtual ~DepthCalculator() {}
122 virtual Size depth(const QuantLib::ext::shared_ptr<ore::data::Trade>& t) const = 0;
123};
124
126public:
127 ConstantDepthCalculator(Size d = 1) : d_(d) {}
128 Size depth(const QuantLib::ext::shared_ptr<ore::data::Trade>&) const override { return d_; }
129
130private:
131 Size d_;
132};
133
134//! JaggedCube stores the cube in memory using a vector of trade specific blocks
135/*! JaggedCube stores the cube in memory using a vector of trade specific blocks
136 * to allow both single and double precision implementations.
137 *
138 \ingroup cube
139 */
140template <typename T> class JaggedCube : public ore::analytics::NPVCube {
141public:
142 JaggedCube(Date asof, QuantLib::ext::shared_ptr<ore::data::Portfolio>& portfolio, const vector<Date>& dates, Size samples,
143 Size depth) {
145 }
146
147 JaggedCube(Date asof, QuantLib::ext::shared_ptr<ore::data::Portfolio>& portfolio, const vector<Date>& dates, Size samples,
148 const DepthCalculator& dc) {
149 init(asof, portfolio, dates, samples, dc);
150 }
151
152 // go back to depth, dep??? they are different
153 void init(Date asof, QuantLib::ext::shared_ptr<ore::data::Portfolio>& portfolio, const vector<Date>& dates, Size samples,
154 const DepthCalculator& dc) {
155 asof_ = asof;
156 dates_ = dates;
158 maxDepth_ = 0;
159 // Loop over each trade, calculate it's dateLength by checking the trade maturity
160 // get depth with the depth calculator
161 // create a TradeBlock with these parameters and store it.
162 //
163 // setup asof, .....
164 Size pos = 0;
165 for (const auto& [tid, t] : portfolio->trades()) {
166 // for each trade: set id and set a tradeblock
167 ids_[tid] = pos++;
168 // TradeBlock
169 Size depth = dc.depth(t);
170 maxDepth_ = std::max(maxDepth_, depth);
171
172 Size dateLen = 0;
173 while (dateLen < dates_.size() && dates_[dateLen] < t->maturity())
174 dateLen++;
175 blocks_.push_back(TradeBlock<T>(dateLen, depth, samples));
176 }
177 }
178
179 //! Return the length of each dimension
180 Size numIds() const override { return ids_.size(); }
181 Size numDates() const override { return dates_.size(); }
182 Size samples() const override { return samples_; }
183 Size depth() const override { return maxDepth_; }
184
185 Real avgDateLen() const {
186 // loop over tradeblocks
187 Size dateTotal = 0;
188 Real dateLenAvg = 0.0;
189 for (auto b : blocks_)
190 dateTotal += b.dateLen;
191 // get date length of each
192 // return avg date (float)
193 dateLenAvg = dateTotal / blocks_.size();
194 return dateLenAvg;
195 }
196
197 Real avgDepth() const {
198 // same as above
199 Size depthTotal = 0;
200 Real depthAvg = 0.0;
201 for (auto b : blocks_)
202 depthTotal += b.depth;
203 depthAvg = depthTotal / blocks_.size();
204 return depthAvg;
205 }
206
207 //! Get the vector of ids for this cube
208 const std::map<std::string, Size>& idsAndIndexes() const override { return ids_; }
209 //! Get the vector of dates for this cube
210 const std::vector<QuantLib::Date>& dates() const override { return dates_; }
211
212 //! Return the asof date (T0 date)
213 QuantLib::Date asof() const override { return asof_; }
214
215 //! Get a T0 value from the cube
216 Real getT0(Size i, Size d) const override {
217 QL_REQUIRE(i < blocks_.size(), "Invalid trade index i " << i);
218 return blocks_[i].getT0(d);
219 }
220
221 //! Set a value in the cube
222 void setT0(Real value, Size i, Size d) override {
223 QL_REQUIRE(i < blocks_.size(), "Invalid trade index i " << i);
224 TradeBlock<T>& tb = blocks_[i];
225 return tb.setT0(value, d);
226 }
227
228 //! Get a value from the cube
229 Real get(Size i, Size j, Size k, Size d) const override {
230 check(i, j, k, d);
231 return blocks_[i].get(j, k, d);
232 }
233
234 //! Set a value in the cube
235 void set(Real value, Size i, Size j, Size k, Size d) override {
236 check(i, j, k, d);
237 TradeBlock<T>& tb = blocks_[i];
238 return tb.set(value, j, k, d);
239 }
240
241protected:
242 void check(Size i, Size j, Size k, Size d) const {
243 QL_REQUIRE(i < numIds(), "Out of bounds on ids (i=" << i << ")");
244 QL_REQUIRE(j < numDates(), "Out of bounds on dates (j=" << j << ")");
245 QL_REQUIRE(k < samples(), "Out of bounds on samples (k=" << k << ")");
246 QL_REQUIRE(d < depth(), "Out of bounds on depth (d=" << d << ")");
247 }
248
249private:
251 template <class Archive> void serialize(Archive& ar, const unsigned int) {
252 ar& asof_;
253 ar& ids_;
254 ar& dates_;
255 ar& samples_;
256 ar& maxDepth_;
257 ar& blocks_;
258 }
259
260 QuantLib::Date asof_;
261 std::map<std::string, Size> ids_;
262 vector<QuantLib::Date> dates_;
265 vector<TradeBlock<T>> blocks_;
266};
267
268//! Jagged cube with single precision floating point numbers.
270
271//! Jagged cube with double precision floating point numbers.
273} // namespace analytics
274} // namespace ore
Size depth(const QuantLib::ext::shared_ptr< ore::data::Trade > &) const override
Definition: jaggedcube.hpp:128
virtual Size depth(const QuantLib::ext::shared_ptr< ore::data::Trade > &t) const =0
JaggedCube stores the cube in memory using a vector of trade specific blocks.
Definition: jaggedcube.hpp:140
Size numDates() const override
Definition: jaggedcube.hpp:181
void setT0(Real value, Size i, Size d) override
Set a value in the cube.
Definition: jaggedcube.hpp:222
const std::map< std::string, Size > & idsAndIndexes() const override
Get the vector of ids for this cube.
Definition: jaggedcube.hpp:208
Size numIds() const override
Return the length of each dimension.
Definition: jaggedcube.hpp:180
Real getT0(Size i, Size d) const override
Get a T0 value from the cube.
Definition: jaggedcube.hpp:216
void check(Size i, Size j, Size k, Size d) const
Definition: jaggedcube.hpp:242
const std::vector< QuantLib::Date > & dates() const override
Get the vector of dates for this cube.
Definition: jaggedcube.hpp:210
void init(Date asof, QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const vector< Date > &dates, Size samples, const DepthCalculator &dc)
Definition: jaggedcube.hpp:153
JaggedCube(Date asof, QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const vector< Date > &dates, Size samples, const DepthCalculator &dc)
Definition: jaggedcube.hpp:147
Size depth() const override
Definition: jaggedcube.hpp:183
QuantLib::Date asof() const override
Return the asof date (T0 date)
Definition: jaggedcube.hpp:213
Real get(Size i, Size j, Size k, Size d) const override
Get a value from the cube.
Definition: jaggedcube.hpp:229
std::map< std::string, Size > ids_
Definition: jaggedcube.hpp:261
friend class boost::serialization::access
Definition: jaggedcube.hpp:250
Size samples() const override
Definition: jaggedcube.hpp:182
vector< TradeBlock< T > > blocks_
Definition: jaggedcube.hpp:265
void set(Real value, Size i, Size j, Size k, Size d) override
Set a value in the cube.
Definition: jaggedcube.hpp:235
vector< QuantLib::Date > dates_
Definition: jaggedcube.hpp:262
void serialize(Archive &ar, const unsigned int)
Definition: jaggedcube.hpp:251
JaggedCube(Date asof, QuantLib::ext::shared_ptr< ore::data::Portfolio > &portfolio, const vector< Date > &dates, Size samples, Size depth)
Definition: jaggedcube.hpp:142
NPV Cube class stores both future and current NPV values.
Definition: npvcube.hpp:53
Real getT0(Size dep) const
Definition: jaggedcube.hpp:74
bool isValidT0(Size dep) const
Definition: jaggedcube.hpp:72
Real get(Size date, Size sample, Size dep) const
Definition: jaggedcube.hpp:90
Size index(Size date, Size dep, Size sample) const
Definition: jaggedcube.hpp:59
Size indexT0(Size dep) const
Definition: jaggedcube.hpp:65
TradeBlock(Size inputDates, Size inputDepth, Size samples)
Definition: jaggedcube.hpp:53
void set(Real value, Size date, Size sample, Size dep)
Definition: jaggedcube.hpp:99
friend class boost::serialization::access
Definition: jaggedcube.hpp:110
bool isValid(Size date, Size dep, Size sample) const
Definition: jaggedcube.hpp:67
void serialize(Archive &ar, const unsigned int)
Definition: jaggedcube.hpp:111
void setT0(Real value, Size dep)
Definition: jaggedcube.hpp:82
SafeStack< ValueType > value
The base NPV cube class.