Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
disjoint_sparse_table_example.cc
Go to the documentation of this file.
1/*
2Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
83# include <cstdio>
84# include <iostream>
85# include <iomanip>
86# include <numeric>
87# include <cassert>
88
90
91using namespace std;
92using namespace Aleph;
93
94// =====================================================================
95// SCENARIO 1 — Sales Analytics (range sum)
96// =====================================================================
97
99{
100 cout << "============================================================\n";
101 cout << " SCENARIO 1: Sales Analytics (Sum_Disjoint_Sparse_Table)\n";
102 cout << "============================================================\n\n";
103
104 // Daily revenue (thousands of dollars) for 15 days
105 const vector<int> revenue =
106 {120, 95, 140, 88, 175, 63, 210, 155, 102, 180,
107 135, 90, 200, 110, 165};
108
110
111 cout << "Daily revenue ($ thousands):\n\n";
112 cout << " Day Revenue\n";
113 cout << " --- -------\n";
114 for (size_t i = 0; i < revenue.size(); ++i)
115 cout << " " << setw(2) << i << " $" << setw(3) << revenue[i]
116 << "K\n";
117
118 cout << "\nTable info: " << sales.size() << " elements, "
119 << sales.num_levels() << " levels\n";
120
121 cout << "\nRange sum queries:\n\n";
122 cout << " Range Total Description\n";
123 cout << " ---------- -------- ----------------------------\n";
124
125 struct Query { size_t l, r; const char * desc; };
126 Query queries[] = {
127 {0, 4, "Week 1 (Mon-Fri)"},
128 {5, 9, "Week 2 (Mon-Fri)"},
129 {10, 14, "Week 3 (Mon-Fri)"},
130 {0, 14, "Entire period"},
131 {3, 7, "Mid-period slice"},
132 {6, 6, "Day 6 alone"},
133 };
134
135 for (const auto & q : queries)
136 {
137 int total = sales.query(q.l, q.r);
138 cout << " [" << setw(2) << q.l << ", " << setw(2) << q.r << "]"
139 << " $" << setw(4) << total << "K " << q.desc << "\n";
140 }
141
142 // Brute-force verification
143 int bf = 0;
144 for (size_t i = 0; i <= 14; ++i) bf += revenue[i];
145 assert(sales.query(0, 14) == bf);
146 cout << "\n ✓ Brute-force verification passed for full range\n";
147 cout << endl;
148}
149
150// =====================================================================
151// SCENARIO 2 — Probability Chains (range product)
152// =====================================================================
153
155{
156 cout << "============================================================\n";
157 cout << " SCENARIO 2: Reliability Analysis (Product_Disjoint_Sparse_Table)\n";
158 cout << "============================================================\n\n";
159
160 // Component reliabilities (probability of working)
161 const vector<double> reliability =
162 {0.99, 0.95, 0.98, 0.97, 0.93, 0.96, 0.99, 0.94, 0.98, 0.97};
163
164 const vector<string> names =
165 {"Power", "CPU", "Memory", "Disk", "Network",
166 "Cooling", "PSU", "GPU", "SSD", "Bus"};
167
169
170 cout << "Component reliabilities:\n\n";
171 cout << " # Component Reliability\n";
172 cout << " -- ---------- -----------\n";
173 for (size_t i = 0; i < reliability.size(); ++i)
174 cout << " " << setw(2) << i << " " << setw(10) << left
175 << names[i] << right << " " << fixed << setprecision(4)
176 << reliability[i] << "\n";
177
178 cout << "\nSubsystem reliability queries (product of individual):\n\n";
179 cout << " Range Reliability Description\n";
180 cout << " ---------- ----------- ----------------------\n";
181
182 struct Query { size_t l, r; const char * desc; };
183 Query queries[] = {
184 {0, 2, "Core compute (Power-Memory)"},
185 {3, 5, "Storage+Net (Disk-Cooling)"},
186 {6, 9, "Expansion (PSU-Bus)"},
187 {0, 9, "Full system"},
188 {1, 4, "CPU through Network"},
189 {7, 7, "GPU alone"},
190 };
191
192 for (const auto & q : queries)
193 {
194 double p = rel_table.query(q.l, q.r);
195 cout << " [" << setw(2) << q.l << ", " << setw(2) << q.r << "]"
196 << " " << fixed << setprecision(6) << p
197 << " " << q.desc << "\n";
198 }
199
200 // Brute-force verification of full system
201 double bf = 1.0;
202 for (double r : reliability) bf *= r;
203 double computed = rel_table.query(0, 9);
204 assert(abs(computed - bf) < 1e-12);
205 cout << "\n ✓ Full system reliability = " << fixed << setprecision(6)
206 << computed << " — verified\n";
207 cout << endl;
208}
209
210// =====================================================================
211// SCENARIO 3 — XOR Checksums (custom associative op)
212// =====================================================================
213
214struct Xor_Op
215{
216 constexpr unsigned operator()(unsigned a, unsigned b) const noexcept
217 {
218 return a ^ b;
219 }
220};
221
223{
224 cout << "============================================================\n";
225 cout << " SCENARIO 3: XOR Checksums (Gen_Disjoint_Sparse_Table)\n";
226 cout << "============================================================\n\n";
227
228 const vector<unsigned> data =
229 {0xA3, 0x5F, 0x12, 0xB7, 0x8C, 0xE1, 0x3D, 0x74, 0x9A, 0x06};
230
232
233 cout << "Data blocks (hex):\n\n";
234 cout << " Index Value\n";
235 cout << " ----- -----\n";
236 for (size_t i = 0; i < data.size(); ++i)
237 cout << " " << i << " 0x" << hex << uppercase
238 << setw(2) << setfill('0') << data[i]
239 << setfill(' ') << dec << "\n";
240
241 cout << "\nTable info: " << xor_tbl.size() << " elements, "
242 << xor_tbl.num_levels() << " levels\n";
243
244 cout << "\nRange XOR queries:\n\n";
245 cout << " Range XOR Values\n";
246 cout << " -------- ------ ------\n";
247
248 struct Query { size_t l, r; };
249 Query queries[] = {{0, 2}, {0, 9}, {3, 5}, {1, 4}, {6, 9}, {4, 4}, {0, 5}};
250
251 for (const auto & q : queries)
252 {
253 unsigned result = xor_tbl.query(q.l, q.r);
254
255 cout << " [" << q.l << ", " << q.r << "] 0x"
256 << hex << uppercase << setw(2) << setfill('0') << result
257 << setfill(' ') << dec << " {";
258
259 for (size_t i = q.l; i <= q.r; ++i)
260 {
261 if (i > q.l) cout << ", ";
262 cout << "0x" << hex << uppercase << setw(2) << setfill('0')
263 << data[i] << setfill(' ') << dec;
264 }
265 cout << "}\n";
266 }
267
268 // Brute-force verification
269 bool all_ok = true;
270 for (const auto & q : queries)
271 {
272 unsigned bf = 0;
273 for (size_t i = q.l; i <= q.r; ++i) bf ^= data[i];
274 if (xor_tbl.query(q.l, q.r) != bf)
275 all_ok = false;
276 }
277 assert(all_ok);
278 cout << "\n ✓ All XOR queries verified against brute-force\n";
279 cout << endl;
280}
281
282// =====================================================================
283// SCENARIO 5 — Construction from different containers
284// =====================================================================
285
287{
288 cout << "============================================================\n";
289 cout << " SCENARIO 5: Construction from different containers\n";
290 cout << "============================================================\n\n";
291
292 const vector<int> raw = {5, 3, 7, 1, 9, 2, 8, 4, 6};
293
294 // From Array<int>
295 Array<int> arr(raw.size());
296 for (size_t i = 0; i < raw.size(); ++i)
297 arr.append(raw[i]);
299
300 // From std::vector<int>
302
303 // From DynList<int>
305 for (size_t i = 0; i < raw.size(); ++i)
306 dl.append(raw[i]);
308
309 // From initializer_list
310 Sum_Disjoint_Sparse_Table<int> from_il = {5, 3, 7, 1, 9, 2, 8, 4, 6};
311
312 int expected = 0;
313 for (int v : raw) expected += v;
314
315 cout << "From Array<int>: sum[0,8] = " << from_arr.query(0, 8) << "\n";
316 cout << "From vector<int>: sum[0,8] = " << from_vec.query(0, 8) << "\n";
317 cout << "From DynList<int>: sum[0,8] = " << from_dl.query(0, 8) << "\n";
318 cout << "From init-list: sum[0,8] = " << from_il.query(0, 8) << "\n";
319
320 assert(from_arr.query(0, 8) == expected);
321 assert(from_vec.query(0, 8) == expected);
322 assert(from_dl.query(0, 8) == expected);
323 assert(from_il.query(0, 8) == expected);
324
325 // Reconstruct values
326 auto vals = from_vec.values();
327 cout << "\nReconstructed values: ";
328 for (size_t i = 0; i < vals.size(); ++i)
329 {
330 if (i > 0) cout << ", ";
331 cout << vals(i);
332 }
333 cout << "\n";
334
335 // Cross-validate a sub-range
336 for (size_t l = 0; l < raw.size(); ++l)
337 for (size_t r = l; r < raw.size(); ++r)
338 assert(from_arr.query(l, r) == from_vec.query(l, r));
339
340 cout << "\n ✓ All construction methods produce identical results\n";
341 cout << endl;
342}
343
344// =====================================================================
345// SCENARIO 4 — Parlay Betting (range product of odds)
346// =====================================================================
347
349{
350 cout << "============================================================\n";
351 cout << " SCENARIO 4: Parlay Betting (Product_Disjoint_Sparse_Table)\n";
352 cout << "============================================================\n\n";
353
354 // A Saturday match card: 12 events with decimal odds
355 // Decimal odds already include the stake: payout = stake × odds
356 struct Match { const char * event; double odds; };
357 Match card[] = {
358 {"Arsenal vs Chelsea", 1.85}, // 0
359 {"Real Madrid vs Barcelona", 2.10}, // 1
360 {"Bayern vs Dortmund", 1.55}, // 2
361 {"PSG vs Lyon", 1.40}, // 3
362 {"Juventus vs Inter", 2.25}, // 4
363 {"Liverpool vs Man City", 3.10}, // 5
364 {"Ajax vs Feyenoord", 1.90}, // 6
365 {"Benfica vs Porto", 2.05}, // 7
366 {"Milan vs Napoli", 1.75}, // 8
367 {"Atletico vs Sevilla", 1.60}, // 9
368 {"Tottenham vs Man United", 2.40}, // 10
369 {"Celtic vs Rangers", 1.95}, // 11
370 };
371
372 const size_t N = sizeof(card) / sizeof(card[0]);
373
374 vector<double> odds(N);
375 for (size_t i = 0; i < N; ++i)
376 odds[i] = card[i].odds;
377
379
380 cout << "Saturday Match Card:\n\n";
381 cout << " # Match Odds\n";
382 cout << " -- --------------------------- ----\n";
383 for (size_t i = 0; i < N; ++i)
384 cout << " " << setw(2) << i << " " << setw(27) << left
385 << card[i].event << right << " " << fixed << setprecision(2)
386 << card[i].odds << "\n";
387
388 cout << "\nTable info: " << parlay.size() << " events, "
389 << parlay.num_levels() << " levels\n";
390
391 // Parlay queries: what is the combined multiplier for a range?
392 cout << "\nParlay (accumulator) queries — combined payout multiplier:\n\n";
393 cout << " Parlay Combined $10 Bet\n";
394 cout << " Range Legs Multiplier Payout\n";
395 cout << " ------ ------ ---------- --------\n";
396
397 struct PQuery { size_t l, r; const char * desc; };
398 PQuery queries[] = {
399 {0, 1, nullptr}, // double
400 {0, 2, nullptr}, // treble
401 {0, 4, nullptr}, // 5-fold
402 {5, 8, nullptr}, // 4-fold mid-card
403 {0, 11, nullptr}, // full card 12-fold
404 {3, 3, nullptr}, // single
405 {9, 11, nullptr}, // last 3
406 };
407
408 for (const auto & q : queries)
409 {
410 double mult = parlay.query(q.l, q.r);
411 size_t legs = q.r - q.l + 1;
412 double payout = 10.0 * mult;
413
414 cout << " [" << setw(2) << q.l << "," << setw(2) << q.r << "]"
415 << " " << setw(2) << legs << "-fold"
416 << " " << setw(10) << fixed << setprecision(2) << mult
417 << " $" << setw(7) << fixed << setprecision(2) << payout
418 << "\n";
419 }
420
421 // Brute-force verification
422 double bf_full = 1.0;
423 for (size_t i = 0; i < N; ++i) bf_full *= odds[i];
424 double computed_full = parlay.query(0, N - 1);
425 assert(abs(computed_full - bf_full) < 1e-6);
426
427 cout << "\n Full-card 12-fold parlay: $10 bet pays $"
428 << fixed << setprecision(2) << 10.0 * computed_full << "\n";
429
430 // Show why classical Sparse Table can't do this:
431 // product is NOT idempotent: 2.0 * 2.0 = 4.0 ≠ 2.0
432 cout << "\n Note: product is NOT idempotent (odds × odds ≠ odds),\n"
433 << " so a classical Sparse Table cannot handle parlay queries.\n"
434 << " The Disjoint Sparse Table handles them in O(1).\n";
435
436 cout << "\n ✓ Full-card parlay verified against brute-force\n";
437 cout << endl;
438}
439
440// =====================================================================
441// SCENARIO 5 — Construction from different containers
442// =====================================================================
443
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:239
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
Disjoint Sparse Table over an arbitrary associative binary operation.
size_t size() const noexcept
Count the number of elements of the list.
Definition htlist.H:1319
void scenario_parlay_betting()
void scenario_construction()
void scenario_sales_analytics()
void scenario_probability()
void scenario_xor_checksum()
#define N
Definition fib.C:294
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_abs_function > > abs(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4051
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
DynList< T > maps(const C &c, Op op)
Classic map operation.
STL namespace.
Disjoint Sparse Table for range product queries.
Disjoint Sparse Table for range sum queries.
constexpr unsigned operator()(unsigned a, unsigned b) const noexcept
Disjoint Sparse Table for static range queries in O(1).
DynList< int > l