[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi] [PATCH 4/4] multi-dimensional tables
From: |
Vaclav Slavik |
Subject: |
[lmi] [PATCH 4/4] multi-dimensional tables |
Date: |
Thu, 02 Aug 2012 14:32:28 +0200 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:14.0) Gecko/20120713 Thunderbird/14.0 |
Hi,
finally, this is the important bit:
Add support for multi-dimensional tables.
Load multiple basic tables from XML file. The new queries API takes a
database_index key that is used to choose an appropriate basic table.
Old API is still provided for compatibility. It only works reasonably
with single-table files (which is the only kind we care about for
compatibility), otherwise it just picks the first table in the file.
---
actuarial_table.cpp | 174 +++++++++++++++++++++++++++++++++++++++++++++++-----
actuarial_table.hpp | 67 ++++++++++++++++++--
2 files changed, 222 insertions(+), 19 deletions(-)
diff --git a/actuarial_table.cpp b/actuarial_table.cpp
index 4fda41f..bc8949c 100644
--- a/actuarial_table.cpp
+++ b/actuarial_table.cpp
@@ -143,14 +143,120 @@ void xml_actuarial_table::load_xml_table(std::string
const& filename)
;
}
- table_.load(*child);
+ basic_table_key key;
+ load_xml_basic_tables(*child, key);
+}
+
+void xml_actuarial_table::load_xml_basic_tables
+ (xml::node const& root
+ ,basic_table_key const& parent_key
+ )
+{
+ if(strcmp(root.get_name(), "smoking") == 0)
+ {
+ load_xml_basic_tables_for_axis
+ <e_axis_smoking
+ ,mcenum_smoking
+ ,&database_index::smoking
+ >(root, parent_key);
+ }
+ else if(strcmp(root.get_name(), "gender") == 0)
+ {
+ load_xml_basic_tables_for_axis
+ <e_axis_gender
+ ,mcenum_gender
+ ,&database_index::gender
+ >(root, parent_key);
+ }
+ else // a basic table
+ {
+ tables_.push_back(basic_table_record());
+ tables_.back().first = parent_key;
+ tables_.back().second.load(root);
+ }
+}
+
+template<int Axis
+ ,typename EnumType
+ ,database_index& (database_index::*KeySetterFunc)(EnumType)>
+void xml_actuarial_table::load_xml_basic_tables_for_axis
+ (xml::node const& root
+ ,basic_table_key const& parent_key
+ )
+{
+ typedef xml::const_nodes_view::const_iterator cnvi;
+
+ xml::const_nodes_view items(root.elements("item"));
+ for(cnvi i = items.begin(); i != items.end(); ++i)
+ {
+ std::string value_str;
+ if(!xml_lmi::get_attr(*i, "for", value_str))
+ {
+ fatal_error()
+ << "XML <item> node doesn't have 'for' attribute."
+ << LMI_FLUSH
+ ;
+ }
+
+ xml::const_nodes_view data(i->elements());
+ if(1 != std::distance(data.begin(), data.end()))
+ {
+ fatal_error()
+ << "XML <item> node doesn't have exactly one child element."
+ << LMI_FLUSH
+ ;
+ }
+
+ basic_table_key key(parent_key);
+ (key.index_.*KeySetterFunc)(mc_enum<EnumType>(value_str).value());
+ key.index_mask_[Axis] = true;
+
+ load_xml_basic_tables(*data.begin(), key);
+ }
+}
+
+bool xml_actuarial_table::basic_table_key::matches(database_index const&
index) const
+{
+ // issue age part of database_index is ignored, this parameter is specified
+ // separately from other axes:
+ LMI_ASSERT(!index_mask_[e_axis_issue_age]);
+
+ std::vector<int> const& vect_my = index_.index_vector();
+ std::vector<int> const& vect_other = index.index_vector();
+
+ for(unsigned axis = 0; axis < number_of_indices; axis++)
+ {
+ if(index_mask_[axis] && vect_my[axis] != vect_other[axis])
+ return false;
+ }
+ return true;
+}
+
+xml_actuarial_table::basic_table const&
+xml_actuarial_table::find_basic_table(database_index const& key) const
+{
+ for(std::vector<basic_table_record>::const_iterator i = tables_.begin()
+ ;i != tables_.end()
+ ;++i)
+ {
+ if(i->first.matches(key))
+ return i->second;
+ }
+ fatal_error()
+ << "Table doesn't contain data for requested axis or value."
+ << LMI_FLUSH
+ ;
}
/// Read a given number of values for a given issue age.
-std::vector<double> xml_actuarial_table::values(int issue_age, int length)
const
+std::vector<double> xml_actuarial_table::values
+ (database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ ) const
{
- return table_.values(issue_age, length);
+ return find_basic_table(lookup_for).values(issue_age, length);
}
/// Read a given number of values for a given issue age, using a
@@ -161,14 +267,15 @@ std::vector<double> xml_actuarial_table::values(int
issue_age, int length) const
/// sane what was insane ab ovo.
std::vector<double> xml_actuarial_table::values_elaborated
- (int issue_age
+ (database_index const& lookup_for
+ ,int issue_age
,int length
,e_actuarial_table_method method
,int inforce_duration
,int reset_duration
) const
{
- return table_.values_elaborated
+ return find_basic_table(lookup_for).values_elaborated
(issue_age
,length
,method
@@ -1095,11 +1202,15 @@ std::vector<double> actuarial_table_rates
#if defined LMI_USE_XML_TABLES
std::string const xmlfile
(xml_actuarial_table::compatibility_filename(table_filename,
table_number)
- );
- boost::shared_ptr<xml_actuarial_table const>
z(xml_actuarial_table::get_cached(xmlfile));
- soa_actuarial_table z_soa(table_filename, table_number);
+ );
+ std::vector<double> values(actuarial_table_rates
+ (xmlfile
+ ,database_index() // doesn't matter for simple 1D/2D files
+ ,issue_age
+ ,length
+ ));
- std::vector<double> values (z->values(issue_age, length));
+ soa_actuarial_table z_soa(table_filename, table_number);
std::vector<double> values_soa(z_soa.values(issue_age, length));
// SOA !! Temporarily verify correctness of XML implementation,
@@ -1126,17 +1237,18 @@ std::vector<double> actuarial_table_rates_elaborated
#if defined LMI_USE_XML_TABLES
std::string const xmlfile
(xml_actuarial_table::compatibility_filename(table_filename,
table_number)
- );
- boost::shared_ptr<xml_actuarial_table const>
z(xml_actuarial_table::get_cached(xmlfile));
- soa_actuarial_table z_soa(table_filename, table_number);
-
- std::vector<double> values(z->values_elaborated
- (issue_age
+ );
+ std::vector<double> values(actuarial_table_rates_elaborated
+ (xmlfile
+ ,database_index() // doesn't matter for simple 1D/2D files
+ ,issue_age
,length
,method
,inforce_duration
,reset_duration
));
+
+ soa_actuarial_table z_soa(table_filename, table_number);
std::vector<double> values_soa(z_soa.values_elaborated
(issue_age
,length
@@ -1162,3 +1274,35 @@ std::vector<double> actuarial_table_rates_elaborated
#endif // !defined LMI_USE_XML_TABLES
}
+std::vector<double> actuarial_table_rates
+ (std::string const& table_filename
+ ,database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ )
+{
+ boost::shared_ptr<xml_actuarial_table const>
z(xml_actuarial_table::get_cached(table_filename));
+ return z->values(lookup_for, issue_age, length);
+}
+
+std::vector<double> actuarial_table_rates_elaborated
+ (std::string const& table_filename
+ ,database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ ,e_actuarial_table_method method
+ ,int inforce_duration
+ ,int reset_duration
+ )
+{
+ boost::shared_ptr<xml_actuarial_table const>
z(xml_actuarial_table::get_cached(table_filename));
+ return z->values_elaborated
+ (lookup_for
+ ,issue_age
+ ,length
+ ,method
+ ,inforce_duration
+ ,reset_duration
+ );
+}
+
diff --git a/actuarial_table.hpp b/actuarial_table.hpp
index 7482146..1c178e1 100644
--- a/actuarial_table.hpp
+++ b/actuarial_table.hpp
@@ -26,6 +26,7 @@
#include "config.hpp"
+#include "dbindex.hpp"
#include "loaded_files_cache.hpp"
#include "obstruct_slicing.hpp"
#include "uncopyable_lmi.hpp"
@@ -144,9 +145,15 @@ class xml_actuarial_table
,int table_number
);
- std::vector<double> values(int issue_age, int length) const;
+ std::vector<double> values
+ (database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ ) const;
+
std::vector<double> values_elaborated
- (int issue_age
+ (database_index const& lookup_for
+ ,int issue_age
,int length
,e_actuarial_table_method method
,int inforce_duration
@@ -205,7 +212,33 @@ class xml_actuarial_table
std::vector<double> ultimate_;
};
- basic_table table_;
+ struct basic_table_key
+ {
+ basic_table_key() : index_mask_(number_of_indices) {}
+
+ database_index index_;
+ std::vector<bool> index_mask_;
+
+ bool matches(database_index const& index) const;
+ };
+
+ typedef std::pair<basic_table_key, basic_table> basic_table_record;
+ std::vector<basic_table_record> tables_;
+
+ basic_table const& find_basic_table(database_index const& key) const;
+
+ void load_xml_basic_tables
+ (xml::node const& root
+ ,basic_table_key const& parent_key
+ );
+
+ template<int Axis
+ ,typename EnumType
+ ,database_index& (database_index::*KeySetterFunc)(EnumType)>
+ void load_xml_basic_tables_for_axis
+ (xml::node const& root
+ ,basic_table_key const& parent_key
+ );
};
/// Read a table from a database in the binary format designed by the
@@ -278,6 +311,7 @@ class soa_actuarial_table
/// Convenience function: read particular values from a table stored
/// in the SOA table-manager format.
+// SOA !! To be removed, compatibility only
std::vector<double> actuarial_table_rates
(std::string const& table_filename
,int table_number
@@ -287,7 +321,7 @@ std::vector<double> actuarial_table_rates
/// Convenience function: read particular values from a table stored
/// in the SOA table-manager format, using a nondefault lookup method.
-
+// SOA !! To be removed, compatibility only
std::vector<double> actuarial_table_rates_elaborated
(std::string const& table_filename
,int table_number
@@ -298,6 +332,31 @@ std::vector<double> actuarial_table_rates_elaborated
,int reset_duration
);
+
+/// Convenience function: read particular values from a table stored
+/// in the SOA table-manager format.
+
+std::vector<double> actuarial_table_rates
+ (std::string const& table_filename
+ ,database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ );
+
+/// Convenience function: read particular values from a table stored
+/// in the SOA table-manager format, using a nondefault lookup method.
+
+std::vector<double> actuarial_table_rates_elaborated
+ (std::string const& table_filename
+ ,database_index const& lookup_for
+ ,int issue_age
+ ,int length
+ ,e_actuarial_table_method method
+ ,int inforce_duration
+ ,int reset_duration
+ );
+
+
// #define LMI_USE_XML_TABLES
#if defined LMI_USE_XML_TABLES
--
1.7.11.3
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi] [PATCH 4/4] multi-dimensional tables,
Vaclav Slavik <=