14 #ifndef EMP_UNORDERED_INDEX_MAP_H 15 #define EMP_UNORDERED_INDEX_MAP_H 17 #include "../base/vector.h" 31 mutable bool needs_refresh;
35 size_t ParentID(
size_t id)
const {
return (
id-1) / 2; }
38 size_t LeftID(
size_t id)
const {
return 2*
id + 1; }
41 size_t RightID(
size_t id)
const {
return 2*
id + 2; }
50 operator double()
const {
return index_map.
RawWeight(
id); }
51 Proxy &
operator=(
double new_weight) { index_map.
RawAdjust(
id, new_weight);
return *
this; }
55 void ResolveRefresh()
const {
56 if (!needs_refresh)
return;
59 const size_t pivot = num_items - 1;
60 for (
size_t i = pivot-1; i < pivot; i--) {
61 weights[i] = weights[LeftID(i)] + weights[RightID(i)];
64 needs_refresh =
false;
71 : num_items(_items), num_nodes(_items-1), needs_refresh(_items && init_weight), weights(0)
72 {
if (_items > 0) weights.
resize(_items*2-1, init_weight); }
80 size_t GetSize()
const {
return num_items; }
83 double GetWeight()
const { ResolveRefresh();
return weights[0]; }
86 double RawWeight(
size_t id)
const {
return weights[id]; }
90 double RawProb(
size_t id)
const { ResolveRefresh();
return weights[id] / weights[0]; }
94 void Resize(
size_t new_size,
double def_value=0.0) {
95 const size_t min_size = std::min(num_items, new_size);
99 for (
size_t i = 0; i < min_size; i++) {
100 new_weights[new_size - 1 + i] = weights[num_nodes + i];
104 for (
size_t i = min_size; i < new_size; i++) {
105 new_weights[new_size - 1 + i] = def_value;
109 needs_refresh =
true;
110 num_items = new_size;
111 num_nodes = num_items - 1;
112 std::swap(weights, new_weights);
115 size_t size()
const {
return num_items; }
120 for (
auto & x : weights) { x = 0.0; }
121 needs_refresh =
false;
126 if (new_size == 0) weights.
resize(0);
127 else weights.
resize(2*new_size - 1);
128 num_items = new_size;
129 num_nodes = num_items - 1;
138 const double weight_diff = new_weight - weights[id];
139 weights[id] = new_weight;
141 if (needs_refresh)
return;
146 weights[id] += weight_diff;
150 void Adjust(
size_t id,
const double new_weight) {
RawAdjust(
id + num_nodes, new_weight); }
154 num_items = new_weights.
size();
155 num_nodes = num_items - 1;
157 weights.
resize(num_items*2 - 1);
158 for (
size_t i = 0; i < num_items; i++) weights[i + num_nodes] = new_weights[i];
160 needs_refresh =
true;
165 for (
size_t i = 0; i < num_items; i++) weights[i + num_nodes] = new_weight;
166 needs_refresh =
true;
170 size_t Index(
double index,
size_t cur_id=0)
const {
174 emp_assert(index < weights[cur_id], index, cur_id, weights.
size(), weights[cur_id]);
177 if (cur_id >= num_nodes)
return cur_id - num_nodes;
179 const size_t left_id = LeftID(cur_id);
180 const double left_weight = weights[left_id];
182 if (index < left_weight)
return Index(index, left_id);
183 return Index(index-left_weight, left_id+1);
189 Proxy
operator[](
size_t id) {
return Proxy(*
this,
id + num_nodes); }
190 double operator[](
size_t id)
const {
return weights[
id + num_nodes]; }
195 for (
size_t i = 0; i < in_map.
size(); i++) {
196 weights[i+num_nodes] += in_map.weights[i+num_nodes];
198 needs_refresh =
true;
205 for (
size_t i = 0; i < in_map.
size(); i++) {
206 weights[i+num_nodes] -= in_map.weights[i+num_nodes];
208 needs_refresh =
true;
216 needs_refresh =
true;
void AdjustAll(double new_weight)
Adjust all index weights to the set provided.
Definition: UnorderedIndexMap.h:164
void ResizeClear(size_t new_size)
Change the size of this map AND change all weights to zero.
Definition: UnorderedIndexMap.h:125
void Adjust(size_t id, const double new_weight)
Definition: UnorderedIndexMap.h:150
void Adjust(const emp::vector< double > &new_weights)
Adjust all index weights to the set provided.
Definition: UnorderedIndexMap.h:153
void Clear()
Reset all item weights to zero.
Definition: UnorderedIndexMap.h:119
size_t size() const
Standard library compatibility.
Definition: UnorderedIndexMap.h:115
size_t size() const
Definition: vector.h:151
double GetProb(size_t id) const
Definition: UnorderedIndexMap.h:91
double GetWeight() const
What is the total weight of all indices in this map?
Definition: UnorderedIndexMap.h:83
size_t GetSize() const
How many indices are in this map?
Definition: UnorderedIndexMap.h:80
void resize(size_t new_size)
Definition: vector.h:161
void resize(size_t new_size)
Standard library compatibility.
Definition: UnorderedIndexMap.h:116
void DeferRefresh()
Definition: UnorderedIndexMap.h:215
UnorderedIndexMap & operator+=(UnorderedIndexMap &in_map)
Add the weights in another index map to this one.
Definition: UnorderedIndexMap.h:193
If we are in emscripten, make sure to include the header.
Definition: array.h:37
#define emp_assert(...)
Definition: assert.h:199
Proxy operator[](size_t id)
Index into a specified ID.
Definition: UnorderedIndexMap.h:189
double RawProb(size_t id) const
What is the probability of the specified index being selected?
Definition: UnorderedIndexMap.h:90
~UnorderedIndexMap()=default
UnorderedIndexMap & operator-=(UnorderedIndexMap &in_map)
Substract the weigthes from another index map from this one.
Definition: UnorderedIndexMap.h:203
Definition: UnorderedIndexMap.h:23
size_t Index(double index, size_t cur_id=0) const
Determine the ID at the specified index position.
Definition: UnorderedIndexMap.h:170
UnorderedIndexMap(size_t _items=0, double init_weight=0.0)
Definition: UnorderedIndexMap.h:70
double operator[](size_t id) const
Definition: UnorderedIndexMap.h:190
double RawWeight(size_t id) const
What is the current weight of the specified index?
Definition: UnorderedIndexMap.h:86
void RawAdjust(size_t id, const double new_weight)
Definition: UnorderedIndexMap.h:136
double GetWeight(size_t id) const
Definition: UnorderedIndexMap.h:87
void Resize(size_t new_size, double def_value=0.0)
Change the number of indecies in the map.
Definition: UnorderedIndexMap.h:94
UnorderedIndexMap & operator=(const UnorderedIndexMap &)=default