File indexing completed on 2025-04-19 09:13:42
0001
0002
0003
0004
0005
0006 #ifndef YODA_Weights_h
0007 #define YODA_Weights_h
0008
0009 #include "YODA/Exceptions.h"
0010 #include <vector>
0011 #include <string>
0012 #include <map>
0013 #include <ostream>
0014
0015 namespace YODA {
0016
0017
0018
0019
0020
0021
0022 class Weights {
0023 public:
0024
0025
0026
0027
0028 Weights(const Weights& other)
0029 : _values(other._values)
0030 { }
0031
0032
0033 Weights(double value) {
0034 _values["0"] = value;
0035 }
0036
0037
0038 Weights(const std::vector<std::pair<std::string, double> >& keys_values) {
0039 for (std::vector<std::pair<std::string, double> >::const_iterator i = keys_values.begin(); i != keys_values.end(); ++i) {
0040 _values[i->first] = i->second;
0041 }
0042 }
0043
0044
0045 Weights(const std::vector<std::string>& keys, const std::vector<double>& values) {
0046 if (keys.size() != values.size()) {
0047 throw WeightError("Mismatch in lengths of keys and values vectors in Weights constructor");
0048 }
0049 for (size_t i = 0; i < keys.size(); ++i) {
0050 _values[keys[i]] = values[i];
0051 }
0052 }
0053
0054
0055 Weights(const std::vector<std::string>& keys, double value=0.0) {
0056 for (std::vector<std::string>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
0057 _values[*i] = value;
0058 }
0059 }
0060
0061
0062
0063 public:
0064
0065
0066
0067
0068
0069
0070
0071 typedef std::map<std::string, double>::iterator iterator;
0072 typedef std::map<std::string, double>::const_iterator const_iterator;
0073 iterator begin() { return _values.begin(); }
0074 const_iterator begin() const { return _values.begin(); }
0075 iterator end() { return _values.end(); }
0076 const_iterator end() const { return _values.end(); }
0077
0078 double& operator [] (const std::string& key) {
0079 if (_values.find(key) == _values.end()) {
0080 throw WeightError("No weight found with supplied name");
0081 }
0082 return _values[key];
0083 }
0084 const double& operator [] (const std::string& key) const {
0085 const_iterator rtn = _values.find(key);
0086 if (rtn == _values.end()) {
0087 throw WeightError("No weight found with supplied name");
0088 }
0089 return rtn->second;
0090 }
0091
0092 double& operator [] (size_t index) {
0093 if (index >= size()) {
0094 throw WeightError("Requested weight index is larger than the weights collection");
0095 }
0096 return _values[keys()[index]];
0097 }
0098 const double& operator [] (size_t index) const {
0099 if (index >= size()) {
0100 throw WeightError("Requested weight index is larger than the weights collection");
0101 }
0102 return _values.find(keys()[index])->second;
0103 }
0104
0105
0106 unsigned int size() const {
0107 return _values.size();
0108 }
0109
0110
0111 std::vector<std::string> keys() const {
0112 std::vector<std::string> rtn;
0113 rtn.reserve(size());
0114 for (const_iterator i = begin(); i != end(); ++i) {
0115 rtn.push_back(i->first);
0116 }
0117 return rtn;
0118 }
0119
0120
0121 std::vector<double> values() const {
0122 std::vector<double> rtn;
0123 rtn.reserve(size());
0124 for (const_iterator i = begin(); i != end(); ++i) {
0125 rtn.push_back(i->second);
0126 }
0127 return rtn;
0128 }
0129
0130
0131
0132
0133
0134
0135
0136
0137 Weights& operator += (const Weights& toAdd) {
0138 if (keys().empty()) _initToMatch(toAdd);
0139 if (keys() != toAdd.keys()) {
0140 throw WeightError("Mismatch in args to Weights += operator");
0141 }
0142 for (size_t i = 0; i < size(); ++i) {
0143 _values[keys()[i]] += toAdd[keys()[i]];
0144 }
0145 return *this;
0146 }
0147
0148
0149 Weights& operator -= (const Weights& toSubtract) {
0150 if (keys().empty()) _initToMatch(toSubtract);
0151 if (keys() != toSubtract.keys()) {
0152 throw WeightError("Mismatch in args to Weights -= operator");
0153 }
0154 for (size_t i = 0; i < size(); ++i) {
0155 _values[keys()[i]] -= toSubtract[keys()[i]];
0156 }
0157 return *this;
0158 }
0159
0160
0161 Weights& operator *= (const Weights& toMultiplyBy) {
0162 if (keys().empty()) _initToMatch(toMultiplyBy);
0163 if (keys() != toMultiplyBy.keys()) {
0164 throw WeightError("Mismatch in args to Weights *= operator");
0165 }
0166 for (size_t i = 0; i < size(); ++i) {
0167 _values[keys()[i]] *= toMultiplyBy[keys()[i]];
0168 }
0169 return *this;
0170 }
0171
0172
0173 Weights& operator /= (const Weights& toDivideBy) {
0174 if (keys().empty()) _initToMatch(toDivideBy);
0175 if (keys() != toDivideBy.keys()) {
0176 throw WeightError("Mismatch in args to Weights /= operator");
0177 }
0178 for (size_t i = 0; i < size(); ++i) {
0179 _values[keys()[i]] /= toDivideBy[keys()[i]];
0180 }
0181 return *this;
0182 }
0183
0184
0185 Weights& operator *= (double toMultiplyBy) {
0186 for (size_t i = 0; i < size(); ++i) {
0187 _values[keys()[i]] *= toMultiplyBy;
0188 }
0189 return *this;
0190 }
0191
0192
0193 Weights& operator /= (double toDivideBy) {
0194 for (size_t i = 0; i < size(); ++i) {
0195 _values[keys()[i]] /= toDivideBy;
0196 }
0197 return *this;
0198 }
0199
0200
0201
0202 Weights operator - () const {
0203 Weights rtn = *this;
0204 rtn *= -1;
0205 return rtn;
0206 }
0207
0208
0209
0210
0211
0212
0213
0214
0215 bool operator == (const Weights& other) const {
0216 return this->_values == other._values;
0217 }
0218
0219
0220 bool operator != (const Weights& other) const {
0221 return !(*this == other);
0222 }
0223
0224
0225
0226
0227
0228
0229
0230 private:
0231
0232
0233 void _initToMatch(const Weights& other) {
0234 if (keys().empty()) {
0235 throw LogicError("Weights::_initToMatch shouldn't ever be called if there are already defined weights keys");
0236 }
0237 for (size_t i = 0; i < other.size(); ++i) {
0238 _values[other.keys()[i]] = 0;
0239 }
0240 }
0241
0242
0243 private:
0244
0245 std::map<std::string, double> _values;
0246
0247 };
0248
0249
0250
0251
0252
0253
0254 inline Weights operator + (const Weights& first, const Weights& second) {
0255 Weights tmp = first;
0256 tmp += second;
0257 return tmp;
0258 }
0259
0260
0261 inline Weights operator - (const Weights& first, const Weights& second) {
0262 Weights tmp = first;
0263 tmp -= second;
0264 return tmp;
0265 }
0266
0267
0268 inline Weights operator * (const Weights& first, const Weights& second) {
0269 Weights tmp = first;
0270 tmp *= second;
0271 return tmp;
0272 }
0273
0274
0275 inline Weights operator / (const Weights& numer, const Weights& denom) {
0276 Weights tmp = numer;
0277 tmp /= denom;
0278 return tmp;
0279 }
0280
0281
0282
0283 inline Weights operator * (double a, const Weights& w) {
0284 Weights tmp = w;
0285 tmp *= a;
0286 return tmp;
0287 }
0288
0289
0290 inline Weights operator * (const Weights& w, double a) {
0291 return a * w;
0292 }
0293
0294
0295 inline Weights operator / (const Weights& w, double a) {
0296 Weights tmp = w;
0297 tmp /= a;
0298 return tmp;
0299 }
0300
0301
0302
0303 inline Weights operator / (double a, const Weights& w) {
0304 Weights tmp(w.keys(), a);
0305 tmp /= w;
0306 return tmp;
0307 }
0308
0309
0310
0311
0312
0313 inline std::ostream& operator<<(std::ostream& out, const Weights& w) {
0314 out << "{ ";
0315 for (Weights::const_iterator i = w.begin(); i != w.end(); ++i) {
0316 if (i != w.begin()) out << ", ";
0317 out << i->first << ": " << i->second;
0318 }
0319 out << "}";
0320 return out;
0321 }
0322
0323
0324 }
0325
0326 #endif