yinspire 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +24 -0
- data/bench/pq/Makefile +5 -0
- data/bench/pq/bench.cc +321 -0
- data/bench/pq/bench.rb +125 -0
- data/bench/pq/bench_binaryheap.h +46 -0
- data/bench/pq/bench_calendarqueue.h +58 -0
- data/bench/pq/bench_pairingheap.h +61 -0
- data/bench/pq/bench_stlpq.h +46 -0
- data/bench/pq/benchmark.h +225 -0
- data/bench/pq/distribution.h +93 -0
- data/bench/pq/make.rb +24 -0
- data/bin/yinspire +186 -0
- data/examples/nets/gereon2005.c.json +93723 -0
- data/examples/nets/gereon2005.yin +232650 -0
- data/examples/nets/skorpion.graphml +396 -0
- data/examples/nets/spiketrains_angle_180.txt +8 -0
- data/lib/Algorithms/Array.h +52 -0
- data/lib/Algorithms/BinaryHeap.h +265 -0
- data/lib/Algorithms/CalendarQueue.h +257 -0
- data/lib/Algorithms/IndexedBinaryHeap.h +90 -0
- data/lib/Algorithms/PairingHeap.h +169 -0
- data/lib/Allocators/ChunkedFreelistAllocator.h +96 -0
- data/lib/Allocators/MemoryAllocator.h +45 -0
- data/lib/Allocators/RubyMemoryAllocator.h +37 -0
- data/lib/Yinspire.rb +69 -0
- data/lib/Yinspire/All.rb +10 -0
- data/lib/Yinspire/Core/NeuralEntity.rb +133 -0
- data/lib/Yinspire/Core/Neuron.rb +162 -0
- data/lib/Yinspire/Core/Scheduling/NeuralEntity.rb +123 -0
- data/lib/Yinspire/Core/Scheduling/Simulator.rb +94 -0
- data/lib/Yinspire/Core/Simulator.rb +36 -0
- data/lib/Yinspire/Core/StimuliMixin.rb +103 -0
- data/lib/Yinspire/Core/Stimulus.rb +25 -0
- data/lib/Yinspire/Core/Synapse.rb +64 -0
- data/lib/Yinspire/Dumpers/Dumper.rb +19 -0
- data/lib/Yinspire/Dumpers/Dumper_Dot.rb +28 -0
- data/lib/Yinspire/Loaders/GraphML.rb +84 -0
- data/lib/Yinspire/Loaders/Loader.rb +31 -0
- data/lib/Yinspire/Loaders/Loader_GraphML.rb +97 -0
- data/lib/Yinspire/Loaders/Loader_JSON.rb +181 -0
- data/lib/Yinspire/Loaders/Loader_Spike.rb +42 -0
- data/lib/Yinspire/Loaders/Loader_Yin.rb +62 -0
- data/lib/Yinspire/Loaders/YinScanner.rb +247 -0
- data/lib/Yinspire/Models/Neuron_Base.rb +38 -0
- data/lib/Yinspire/Models/Neuron_Input.rb +12 -0
- data/lib/Yinspire/Models/Neuron_InputOutput.rb +39 -0
- data/lib/Yinspire/Models/Neuron_Output.rb +15 -0
- data/lib/Yinspire/Models/Neuron_SRM01.rb +50 -0
- data/lib/Yinspire/Models/Neuron_SRM02.rb +64 -0
- data/lib/Yinspire/Models/Synapse_Hebb.rb +67 -0
- data/pure_cpp/Makefile +22 -0
- data/pure_cpp/README +2 -0
- data/pure_cpp/src/algo/binary_heap.h +277 -0
- data/pure_cpp/src/algo/indexed_binary_heap.h +90 -0
- data/pure_cpp/src/json/json.cc +542 -0
- data/pure_cpp/src/json/json.h +182 -0
- data/pure_cpp/src/json/json_parser.cc +685 -0
- data/pure_cpp/src/json/json_parser.h +15 -0
- data/pure_cpp/src/json/json_parser.rl +213 -0
- data/pure_cpp/src/main.cc +49 -0
- data/pure_cpp/src/memory_allocator.h +45 -0
- data/pure_cpp/src/neural_entity.cc +208 -0
- data/pure_cpp/src/neural_entity.h +243 -0
- data/pure_cpp/src/neuron.cc +136 -0
- data/pure_cpp/src/neuron.h +70 -0
- data/pure_cpp/src/neuron_srm_01.cc +77 -0
- data/pure_cpp/src/neuron_srm_01.h +36 -0
- data/pure_cpp/src/simulator.cc +151 -0
- data/pure_cpp/src/simulator.h +116 -0
- data/pure_cpp/src/synapse.cc +117 -0
- data/pure_cpp/src/synapse.h +60 -0
- data/pure_cpp/src/types.h +18 -0
- data/run.rb +68 -0
- data/tools/conv_jsonc_to_yin.rb +165 -0
- data/tools/converter.rb +93 -0
- data/tools/json_writer.rb +122 -0
- data/yinspire.gemspec +20 -0
- metadata +156 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
#include "algo/binary_heap.h"
|
2
|
+
#include "memory_allocator.h"
|
3
|
+
|
4
|
+
namespace BenchBinaryHeap
|
5
|
+
{
|
6
|
+
template<class ET>
|
7
|
+
struct T
|
8
|
+
{
|
9
|
+
typedef BinaryHeap<ET, MemoryAllocator<ET> > PQ;
|
10
|
+
|
11
|
+
struct ACC
|
12
|
+
{
|
13
|
+
inline void hold(PQ *pq, double increment)
|
14
|
+
{
|
15
|
+
ET e = pq->top();
|
16
|
+
e.priority += increment;
|
17
|
+
pq->pop();
|
18
|
+
pq->push(e);
|
19
|
+
}
|
20
|
+
|
21
|
+
inline void push(PQ *pq, double priority)
|
22
|
+
{
|
23
|
+
ET e;
|
24
|
+
e.priority = priority;
|
25
|
+
pq->push(e);
|
26
|
+
}
|
27
|
+
|
28
|
+
inline void pop(PQ *pq)
|
29
|
+
{
|
30
|
+
pq->pop();
|
31
|
+
}
|
32
|
+
|
33
|
+
inline double pop_return_priority(PQ *pq)
|
34
|
+
{
|
35
|
+
ET e = pq->top();
|
36
|
+
pq->pop();
|
37
|
+
return e.priority;
|
38
|
+
}
|
39
|
+
|
40
|
+
static const char* algorithm_name()
|
41
|
+
{
|
42
|
+
return "BinaryHeap";
|
43
|
+
}
|
44
|
+
};
|
45
|
+
};
|
46
|
+
};
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#include "algo/calendar_queue.h"
|
2
|
+
#include "chunked_freelist_allocator.h"
|
3
|
+
|
4
|
+
namespace BenchCalendarQueue
|
5
|
+
{
|
6
|
+
template<class ET>
|
7
|
+
struct T
|
8
|
+
{
|
9
|
+
typedef CalendarQueue<ET> PQ;
|
10
|
+
|
11
|
+
struct ACC
|
12
|
+
{
|
13
|
+
ChunkedFreelistAllocator<ET> *freelist;
|
14
|
+
|
15
|
+
ACC()
|
16
|
+
{
|
17
|
+
this->freelist = new ChunkedFreelistAllocator<ET>(100000);
|
18
|
+
}
|
19
|
+
|
20
|
+
~ACC()
|
21
|
+
{
|
22
|
+
delete this->freelist;
|
23
|
+
}
|
24
|
+
|
25
|
+
inline void hold(PQ *pq, double increment)
|
26
|
+
{
|
27
|
+
ET *e = pq->pop();
|
28
|
+
e->_priority += increment;
|
29
|
+
pq->push(e);
|
30
|
+
}
|
31
|
+
|
32
|
+
inline void push(PQ *pq, double priority)
|
33
|
+
{
|
34
|
+
ET *e = this->freelist->allocate();
|
35
|
+
e->_priority = priority;
|
36
|
+
pq->push(e);
|
37
|
+
}
|
38
|
+
|
39
|
+
inline void pop(PQ *pq)
|
40
|
+
{
|
41
|
+
this->freelist->free(pq->pop());
|
42
|
+
}
|
43
|
+
|
44
|
+
inline double pop_return_priority(PQ *pq)
|
45
|
+
{
|
46
|
+
ET *e = pq->pop();
|
47
|
+
double res = e->_priority;
|
48
|
+
this->freelist->free(e);
|
49
|
+
return res;
|
50
|
+
}
|
51
|
+
|
52
|
+
static const char* algorithm_name()
|
53
|
+
{
|
54
|
+
return "CalendarQueue";
|
55
|
+
}
|
56
|
+
};
|
57
|
+
};
|
58
|
+
};
|
@@ -0,0 +1,61 @@
|
|
1
|
+
#include "algo/pairing_heap.h"
|
2
|
+
#include "chunked_freelist_allocator.h"
|
3
|
+
|
4
|
+
namespace BenchPairingHeap
|
5
|
+
{
|
6
|
+
template<class ET>
|
7
|
+
struct T
|
8
|
+
{
|
9
|
+
typedef PairingHeap<ET> PQ;
|
10
|
+
|
11
|
+
struct ACC
|
12
|
+
{
|
13
|
+
ChunkedFreelistAllocator<ET> *freelist;
|
14
|
+
|
15
|
+
ACC()
|
16
|
+
{
|
17
|
+
this->freelist = new ChunkedFreelistAllocator<ET>(100000);
|
18
|
+
}
|
19
|
+
|
20
|
+
~ACC()
|
21
|
+
{
|
22
|
+
delete this->freelist;
|
23
|
+
}
|
24
|
+
|
25
|
+
inline void hold(PQ *pq, double increment)
|
26
|
+
{
|
27
|
+
ET *e = pq->top();
|
28
|
+
e->priority += increment;
|
29
|
+
pq->pop();
|
30
|
+
pq->push(e);
|
31
|
+
}
|
32
|
+
|
33
|
+
inline void push(PQ *pq, double priority)
|
34
|
+
{
|
35
|
+
ET *e = this->freelist->allocate();
|
36
|
+
e->priority = priority;
|
37
|
+
pq->push(e);
|
38
|
+
}
|
39
|
+
|
40
|
+
inline void pop(PQ *pq)
|
41
|
+
{
|
42
|
+
this->freelist->free(pq->top());
|
43
|
+
pq->pop();
|
44
|
+
}
|
45
|
+
|
46
|
+
inline double pop_return_priority(PQ *pq)
|
47
|
+
{
|
48
|
+
ET *e = pq->top();
|
49
|
+
double res = e->priority;
|
50
|
+
pq->pop();
|
51
|
+
this->freelist->free(e);
|
52
|
+
return res;
|
53
|
+
}
|
54
|
+
|
55
|
+
static const char* algorithm_name()
|
56
|
+
{
|
57
|
+
return "PairingHeap";
|
58
|
+
}
|
59
|
+
};
|
60
|
+
};
|
61
|
+
};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#include <vector>
|
2
|
+
#include <queue>
|
3
|
+
|
4
|
+
namespace BenchStlPq
|
5
|
+
{
|
6
|
+
template<class ET>
|
7
|
+
struct T
|
8
|
+
{
|
9
|
+
typedef std::priority_queue<ET, std::vector<ET>, ET> PQ;
|
10
|
+
|
11
|
+
struct ACC
|
12
|
+
{
|
13
|
+
inline void hold(PQ *pq, double increment)
|
14
|
+
{
|
15
|
+
ET e = pq->top();
|
16
|
+
e.priority += increment;
|
17
|
+
pq->pop();
|
18
|
+
pq->push(e);
|
19
|
+
}
|
20
|
+
|
21
|
+
inline void push(PQ *pq, double priority)
|
22
|
+
{
|
23
|
+
ET e;
|
24
|
+
e.priority = priority;
|
25
|
+
pq->push(e);
|
26
|
+
}
|
27
|
+
|
28
|
+
inline void pop(PQ *pq)
|
29
|
+
{
|
30
|
+
pq->pop();
|
31
|
+
}
|
32
|
+
|
33
|
+
inline double pop_return_priority(PQ *pq)
|
34
|
+
{
|
35
|
+
ET e = pq->top();
|
36
|
+
pq->pop();
|
37
|
+
return e.priority;
|
38
|
+
}
|
39
|
+
|
40
|
+
static const char* algorithm_name()
|
41
|
+
{
|
42
|
+
return "std::priority_queue";
|
43
|
+
}
|
44
|
+
};
|
45
|
+
};
|
46
|
+
};
|
@@ -0,0 +1,225 @@
|
|
1
|
+
#include <assert.h>
|
2
|
+
#include "distribution.h"
|
3
|
+
#include <time.h> // clock()
|
4
|
+
|
5
|
+
/*
|
6
|
+
*
|
7
|
+
* ACC:
|
8
|
+
*
|
9
|
+
* hold(PQ* pq, double priority_increment);
|
10
|
+
* push(PQ* pq, double priority_value);
|
11
|
+
*
|
12
|
+
*/
|
13
|
+
template <class PQ, class ACC>
|
14
|
+
class Benchmark
|
15
|
+
{
|
16
|
+
public:
|
17
|
+
|
18
|
+
Benchmark(PQ *pq, Distribution *distribution)
|
19
|
+
{
|
20
|
+
this->pq = pq;
|
21
|
+
this->distribution = distribution;
|
22
|
+
}
|
23
|
+
|
24
|
+
/*
|
25
|
+
* In the updown benchmark the xxx_cycles mean complete up/down
|
26
|
+
* cycles.
|
27
|
+
*/
|
28
|
+
double
|
29
|
+
updown(int max_queue_size, int warmup_cycles, int empty_updown_cycles, int updown_cycles)
|
30
|
+
{
|
31
|
+
clock_t t1, t2;
|
32
|
+
|
33
|
+
// warmup & validation
|
34
|
+
if (!run_updown_validate(max_queue_size, warmup_cycles))
|
35
|
+
{
|
36
|
+
throw "pq validation failed";
|
37
|
+
}
|
38
|
+
|
39
|
+
t1 = clock();
|
40
|
+
run_empty_updown(max_queue_size, empty_updown_cycles);
|
41
|
+
t2 = clock();
|
42
|
+
double empty_updown_time = ((double)(t2 - t1)) / empty_updown_cycles;
|
43
|
+
|
44
|
+
t1 = clock();
|
45
|
+
run_updown(max_queue_size, updown_cycles);
|
46
|
+
t2 = clock();
|
47
|
+
double updown_time = ((double)(t2 - t1)) / updown_cycles;
|
48
|
+
|
49
|
+
return (updown_time - empty_updown_time) / CLOCKS_PER_SEC;
|
50
|
+
}
|
51
|
+
|
52
|
+
double
|
53
|
+
classic_hold(int queue_size, int warmup_cycles, int empty_hold_cycles, int hold_cycles)
|
54
|
+
{
|
55
|
+
clock_t t1, t2;
|
56
|
+
|
57
|
+
setup(queue_size);
|
58
|
+
warmup(warmup_cycles);
|
59
|
+
|
60
|
+
t1 = clock();
|
61
|
+
perform_empty_holds(empty_hold_cycles);
|
62
|
+
t2 = clock();
|
63
|
+
double empty_hold_time = ((double)(t2 - t1)) / empty_hold_cycles;
|
64
|
+
|
65
|
+
t1 = clock();
|
66
|
+
perform_holds(hold_cycles);
|
67
|
+
t2 = clock();
|
68
|
+
double hold_time = ((double)(t2 - t1)) / hold_cycles;
|
69
|
+
|
70
|
+
return (hold_time - empty_hold_time) / CLOCKS_PER_SEC;
|
71
|
+
}
|
72
|
+
|
73
|
+
protected:
|
74
|
+
|
75
|
+
void
|
76
|
+
run_updown(unsigned int max_queue_size, unsigned int cycles)
|
77
|
+
{
|
78
|
+
unsigned int i, j;
|
79
|
+
|
80
|
+
for (i=0; i<cycles; i++)
|
81
|
+
{
|
82
|
+
for (j=0; j<max_queue_size; j++)
|
83
|
+
{
|
84
|
+
this->acc.push(this->pq, distribution->next());
|
85
|
+
}
|
86
|
+
for (j=0; j<max_queue_size; j++)
|
87
|
+
{
|
88
|
+
this->acc.pop(this->pq);
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
/*
|
94
|
+
* We assume a "<" relation.
|
95
|
+
*/
|
96
|
+
bool
|
97
|
+
run_updown_validate(unsigned int max_queue_size, unsigned int cycles)
|
98
|
+
{
|
99
|
+
unsigned int i, j;
|
100
|
+
double last, prio;
|
101
|
+
|
102
|
+
for (i=0; i<cycles; i++)
|
103
|
+
{
|
104
|
+
for (j=0; j<max_queue_size; j++)
|
105
|
+
{
|
106
|
+
this->acc.push(this->pq, distribution->next());
|
107
|
+
}
|
108
|
+
last = -INFINITY;
|
109
|
+
for (j=0; j<max_queue_size; j++)
|
110
|
+
{
|
111
|
+
prio = this->acc.pop_return_priority(this->pq);
|
112
|
+
if (prio < last) return false;
|
113
|
+
last = prio;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
return true;
|
118
|
+
}
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
void
|
123
|
+
run_empty_updown(unsigned int max_queue_size, unsigned int cycles)
|
124
|
+
{
|
125
|
+
unsigned int i, j;
|
126
|
+
|
127
|
+
for (i=0; i<cycles; i++)
|
128
|
+
{
|
129
|
+
// To avoid dead code elemination...
|
130
|
+
for (j=0; j<2*max_queue_size; j++)
|
131
|
+
{
|
132
|
+
if (j&1 == 0)
|
133
|
+
{
|
134
|
+
distribution->next();
|
135
|
+
}
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
/*
|
141
|
+
* Setup the priority queue with a size of +queue_size+.
|
142
|
+
*/
|
143
|
+
void
|
144
|
+
setup(unsigned int queue_size, double insert_prob=0.75, double delete_prob=0.5)
|
145
|
+
{
|
146
|
+
RandomDistribution rnd_bool;
|
147
|
+
RandomDistribution rnd_real;
|
148
|
+
|
149
|
+
assert(insert_prob > delete_prob);
|
150
|
+
|
151
|
+
while (this->pq->size() < queue_size)
|
152
|
+
{
|
153
|
+
if (rnd_bool.next() < insert_prob)
|
154
|
+
{
|
155
|
+
this->acc.push(this->pq, rnd_real.next());
|
156
|
+
}
|
157
|
+
|
158
|
+
if (!this->pq->empty() && rnd_bool.next() < delete_prob)
|
159
|
+
{
|
160
|
+
this->acc.pop(this->pq);
|
161
|
+
}
|
162
|
+
}
|
163
|
+
}
|
164
|
+
|
165
|
+
/*
|
166
|
+
* To reach the steady state, +repeats+ number of hold operations are
|
167
|
+
* performed.
|
168
|
+
*
|
169
|
+
* A common number of repeat cycles is "30*queue_size".
|
170
|
+
*/
|
171
|
+
void
|
172
|
+
warmup(int repeats)
|
173
|
+
{
|
174
|
+
for (; repeats > 0; repeats--)
|
175
|
+
{
|
176
|
+
hold();
|
177
|
+
}
|
178
|
+
}
|
179
|
+
|
180
|
+
void
|
181
|
+
perform_empty_holds(int repeats)
|
182
|
+
{
|
183
|
+
for (; repeats > 0; repeats--)
|
184
|
+
{
|
185
|
+
empty_hold();
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
void
|
190
|
+
perform_holds(int repeats)
|
191
|
+
{
|
192
|
+
for (; repeats > 0; repeats--)
|
193
|
+
{
|
194
|
+
hold();
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/*
|
199
|
+
* Perform a hold operation
|
200
|
+
*/
|
201
|
+
inline void
|
202
|
+
hold()
|
203
|
+
{
|
204
|
+
this->acc.hold(this->pq, distribution->next());
|
205
|
+
}
|
206
|
+
|
207
|
+
/*
|
208
|
+
* Perform an empty hold operation for measuring the overhead of
|
209
|
+
* random number generation etc (all except priority queue
|
210
|
+
* operations).
|
211
|
+
*/
|
212
|
+
inline void
|
213
|
+
empty_hold()
|
214
|
+
{
|
215
|
+
distribution->next();
|
216
|
+
}
|
217
|
+
|
218
|
+
|
219
|
+
private:
|
220
|
+
|
221
|
+
PQ *pq;
|
222
|
+
Distribution *distribution;
|
223
|
+
ACC acc;
|
224
|
+
|
225
|
+
};
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#include <math.h>
|
2
|
+
#include <ostream>
|
3
|
+
#include <boost/random.hpp>
|
4
|
+
|
5
|
+
class Distribution
|
6
|
+
{
|
7
|
+
protected:
|
8
|
+
|
9
|
+
boost::mt19937 eng;
|
10
|
+
boost::uniform_real<> dis;
|
11
|
+
boost::variate_generator<boost::mt19937&, boost::uniform_real<> > gen;
|
12
|
+
|
13
|
+
public:
|
14
|
+
|
15
|
+
Distribution() : gen(eng, dis) {}
|
16
|
+
|
17
|
+
virtual double next() = 0;
|
18
|
+
virtual void output_name(std::ostream &o) { o << "undefined"; }
|
19
|
+
|
20
|
+
void
|
21
|
+
seed(unsigned seed)
|
22
|
+
{
|
23
|
+
eng.seed(seed);
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
struct RandomDistribution : public Distribution
|
28
|
+
{
|
29
|
+
virtual double next() { return gen(); }
|
30
|
+
virtual void output_name(std::ostream &o) { o << "Random"; }
|
31
|
+
};
|
32
|
+
|
33
|
+
struct ExponentialDistribution : public Distribution
|
34
|
+
{
|
35
|
+
double a;
|
36
|
+
ExponentialDistribution(double _a) : a(_a) {}
|
37
|
+
|
38
|
+
virtual double next() { return a * -log(gen()); }
|
39
|
+
|
40
|
+
virtual void output_name(std::ostream &o) { o << "Exponential(" << this->a << ")"; }
|
41
|
+
};
|
42
|
+
|
43
|
+
struct UniformDistribution : public Distribution
|
44
|
+
{
|
45
|
+
double a, b;
|
46
|
+
|
47
|
+
UniformDistribution(double _a, double _b) : a(_a), b(_b) {}
|
48
|
+
|
49
|
+
virtual double next() { return (a + (b-a)*gen()); }
|
50
|
+
virtual void output_name(std::ostream &o) { o << "Uniform(" << this->a << "," << this->b << ")"; }
|
51
|
+
};
|
52
|
+
|
53
|
+
struct TriangularDistribution : public Distribution
|
54
|
+
{
|
55
|
+
double a, b;
|
56
|
+
|
57
|
+
TriangularDistribution(double _a, double _b) : a(_a), b(_b) {}
|
58
|
+
|
59
|
+
virtual double next() { return (a + (b-a)*sqrt(gen())); }
|
60
|
+
virtual void output_name(std::ostream &o) { o << "Triangular(" << this->a << "," << this->b << ")"; }
|
61
|
+
};
|
62
|
+
|
63
|
+
struct NegativeTriangularDistribution : public Distribution
|
64
|
+
{
|
65
|
+
double a, b;
|
66
|
+
|
67
|
+
NegativeTriangularDistribution(double _a, double _b) : a(_a), b(_b) {}
|
68
|
+
|
69
|
+
virtual double next() { return (a + (b-a)*(1.0 - sqrt(1.0 - gen()))); }
|
70
|
+
virtual void output_name(std::ostream &o) { o << "NegativeTriangular(" << this->a << "," << this->b << ")"; }
|
71
|
+
};
|
72
|
+
|
73
|
+
struct BimodalDistribution : public Distribution
|
74
|
+
{
|
75
|
+
double a, b;
|
76
|
+
|
77
|
+
BimodalDistribution(double _a=9.95238, double _b=0.1) : a(_a), b(_b) {}
|
78
|
+
|
79
|
+
virtual double next() { return a * gen() + (gen() < b ? a : 0); }
|
80
|
+
|
81
|
+
virtual void output_name(std::ostream &o) { o << "Bimodal(" << this->a << "," << this->b << ")"; }
|
82
|
+
};
|
83
|
+
|
84
|
+
struct ParetoDistribution : public Distribution
|
85
|
+
{
|
86
|
+
double a;
|
87
|
+
|
88
|
+
ParetoDistribution(double _a) : a(_a) {}
|
89
|
+
|
90
|
+
virtual double next() { return pow(1.0/(1.0 - gen()), 1.0 / a); }
|
91
|
+
|
92
|
+
virtual void output_name(std::ostream &o) { o << "Pareto(" << this->a << ")"; }
|
93
|
+
};
|