146#include <tclap/CmdLine.h>
155using namespace Aleph;
163 cout <<
"\n" << string(60,
'=') <<
"\n";
164 cout <<
" " << title <<
"\n";
165 cout << string(60,
'=') <<
"\n\n";
170 cout <<
"\n--- " << title <<
" ---\n";
186 for (
int i = 0; i < 10; i++)
187 (
void)domain->insert(i);
192 cout <<
"Created sparse vector with domain {0, 1, ..., 9}" <<
endl;
193 cout <<
"Initial storage: only non-zero elements are stored" <<
endl;
201 cout <<
"Set v[0] = 1.5, v[3] = 2.7, v[7] = -4.2" <<
endl;
202 cout <<
"\nNon-zero entries:" <<
endl;
203 for (
auto it = v.
get_it(); it.has_curr(); it.next())
205 auto entry = it.get_curr();
206 cout <<
" v[" << entry.first <<
"] = " << entry.second <<
endl;
213 cout <<
"v[5] = " << v.
get_entry(5) <<
" (not set, returns 0)" <<
endl;
217 for (
auto it = v.
get_it(); it.has_curr(); it.next())
219 cout <<
"\nNumber of non-zero entries: " <<
nnz <<
endl;
220 cout <<
"Memory savings: only storing " <<
nnz <<
" of 10 possible values" <<
endl;
231 cout <<
"Vectors can be indexed by ANY type, not just integers!" <<
endl;
246 population.
set_entry(
"Barranquilla", 1.2);
249 cout <<
"\nColombian city populations (millions):" <<
endl;
250 for (
auto it = population.
get_it(); it.has_curr(); it.next())
252 auto entry = it.get_curr();
253 cout <<
" " << setw(15) << left << entry.first
254 <<
": " << entry.second <<
"M" <<
endl;
257 cout <<
"\nCartagena (not set): " << population.
get_entry(
"Cartagena") <<
"M" <<
endl;
261 auto doubled = population * 2.0;
262 cout <<
"Population * 2:" <<
endl;
263 for (
auto it =
doubled.get_it(); it.has_curr(); it.next())
265 auto entry = it.get_curr();
266 cout <<
" " << setw(15) << left << entry.
first
267 <<
": " << entry.second <<
"M" <<
endl;
283 for (
int i = 0; i < 5; i++)
285 (
void)rows->insert(i);
286 (
void)cols->insert(i);
293 cout <<
"Matrix is 5x5 but only non-zero entries are stored" <<
endl;
305 cout <<
"\nNon-zero entries:" <<
endl;
307 for (
int i = 0; i < 5; i++)
308 cout <<
" M[" << i <<
"][" << i <<
"] = " << M.
get_entry(i, i) <<
endl;
314 cout <<
"\nStored entries: " <<
nnz <<
" out of " << (5*5)
315 <<
" possible (" << (100.0 *
nnz / 25) <<
"% fill)" <<
endl;
326 cout <<
"Sparse matrices are perfect for real-world data with named dimensions" <<
endl;
336 (
void)stores->insert(
"BOG");
337 (
void)stores->insert(
"MED");
338 (
void)stores->insert(
"CAL");
339 (
void)stores->insert(
"BAQ");
344 sales.set_entry(
"Laptop",
"BOG", 150);
345 sales.set_entry(
"Laptop",
"MED", 120);
346 sales.set_entry(
"Phone",
"BOG", 500);
347 sales.set_entry(
"Phone",
"MED", 450);
348 sales.set_entry(
"Phone",
"CAL", 300);
349 sales.set_entry(
"Phone",
"BAQ", 200);
350 sales.set_entry(
"Tablet",
"BOG", 80);
351 sales.set_entry(
"Monitor",
"MED", 50);
353 cout <<
"\nSales data (only non-zero entries stored):" <<
endl;
354 cout << string(45,
'-') <<
endl;
357 cout <<
" Laptop @ BOG: " <<
sales.get_entry(
"Laptop",
"BOG") <<
" units" <<
endl;
358 cout <<
" Laptop @ MED: " <<
sales.get_entry(
"Laptop",
"MED") <<
" units" <<
endl;
359 cout <<
" Phone @ BOG: " <<
sales.get_entry(
"Phone",
"BOG") <<
" units" <<
endl;
360 cout <<
" Phone @ MED: " <<
sales.get_entry(
"Phone",
"MED") <<
" units" <<
endl;
361 cout <<
" Phone @ CAL: " <<
sales.get_entry(
"Phone",
"CAL") <<
" units" <<
endl;
362 cout <<
" Phone @ BAQ: " <<
sales.get_entry(
"Phone",
"BAQ") <<
" units" <<
endl;
363 cout <<
" Tablet @ BOG: " <<
sales.get_entry(
"Tablet",
"BOG") <<
" units" <<
endl;
364 cout <<
" Monitor @ MED:" <<
sales.get_entry(
"Monitor",
"MED") <<
" units" <<
endl;
369 cout <<
"Products sold in Bogota:" <<
endl;
370 for (
auto it =
bog_sales.get_it(); it.has_curr(); it.next())
372 auto entry = it.get_curr();
373 cout <<
" " << setw(10) << left << entry.first
374 <<
": " << entry.second <<
" units" <<
endl;
380 cout <<
"Phone sales by store:" <<
endl;
381 for (
auto it =
phone_sales.get_it(); it.has_curr(); it.next())
383 auto entry = it.get_curr();
384 cout <<
" " << setw(5) << left << entry.first
385 <<
": " << entry.second <<
" units" <<
endl;
399 for (
int i = 0; i < 5; i++)
400 (
void)domain->insert(i);
414 cout << name <<
": ";
415 for (
auto it = v.get_it(); it.has_curr(); it.next())
417 auto e = it.get_curr();
418 cout <<
"(" << e.first <<
":" << e.second <<
") ";
430 cout <<
" Note: sparse + sparse = sparse (union of indices)" <<
endl;
451 cout <<
"Sparse matrices are ideal for representing graphs" <<
endl;
452 cout <<
"Most graphs are sparse (few edges vs all possible edges)" <<
endl;
474 cout <<
"\nGraph edges (weighted):" <<
endl;
475 cout <<
" A -> B : weight " << adj.
get_entry(
"A",
"B") <<
endl;
476 cout <<
" A -> C : weight " << adj.
get_entry(
"A",
"C") <<
endl;
477 cout <<
" B -> C : weight " << adj.
get_entry(
"B",
"C") <<
endl;
478 cout <<
" B -> D : weight " << adj.
get_entry(
"B",
"D") <<
endl;
479 cout <<
" C -> D : weight " << adj.
get_entry(
"C",
"D") <<
endl;
480 cout <<
" C -> E : weight " << adj.
get_entry(
"C",
"E") <<
endl;
481 cout <<
" D -> E : weight " << adj.
get_entry(
"D",
"E") <<
endl;
484 size_t num_edges = 7;
489 cout <<
"\nGraph statistics:" <<
endl;
491 cout <<
" Edges: " << num_edges <<
endl;
492 cout <<
" Density: " << fixed << setprecision(1)
494 cout <<
" Memory: storing only " << num_edges
500 for (
auto it =
b_out.get_it(); it.has_curr(); it.next())
502 auto entry = it.get_curr();
503 cout <<
" B -> " << entry.first <<
" : " << entry.second <<
endl;
515 cout <<
"Sparse vectors/matrices automatically handle near-zero values" <<
endl;
518 for (
int i = 0; i < 5; i++)
519 (
void)domain->insert(i);
530 cout <<
"\nAfter setting v[0]=1.0, v[1]=0.0001, v[2]=0.0:" <<
endl;
531 for (
auto it = v.
get_it(); it.has_curr(); it.next())
533 auto entry = it.get_curr();
534 cout <<
" v[" << entry.first <<
"] = " << entry.second <<
endl;
537 cout <<
"\nNote: v[2]=0.0 is not stored (it's zero)" <<
endl;
538 cout <<
"v[1]=0.0001 is stored because |0.0001| > epsilon" <<
endl;
547 cout <<
"\nAfter setting v[3]=0.0005 (< epsilon):" <<
endl;
548 for (
auto it = v.
get_it(); it.has_curr(); it.next())
550 auto entry = it.get_curr();
551 cout <<
" v[" << entry.first <<
"] = " << entry.second <<
endl;
553 cout <<
"\nv[3] was not stored because 0.0005 < 0.001 (epsilon)" <<
endl;
564 cout <<
"Matrices can be constructed directly from initializer lists" <<
endl;
565 cout <<
"(similar to how you'd write a matrix on paper)" <<
endl;
570 for (
int i = 0; i < 3; i++)
572 (
void)rows->insert(i);
573 (
void)cols->insert(i);
583 cout <<
"\nMatrix A (from initializer list):" <<
endl;
594 cout <<
"\nDiagonal matrix B (zeros not stored internally):" <<
endl;
596 cout <<
"\nNote: only 3 entries are stored (the diagonal)" <<
endl;
607 cout <<
"The transpose() method swaps rows and columns" <<
endl;
612 (
void)rows->insert(
"r0");
613 (
void)rows->insert(
"r1");
614 (
void)cols->insert(
"c0");
615 (
void)cols->insert(
"c1");
616 (
void)cols->insert(
"c2");
622 cout <<
"\nOriginal matrix M (2x3):" <<
endl;
626 cout <<
"\nTranspose M^T (3x2):" <<
endl;
629 cout <<
"\nProperty: M[r][c] = M^T[c][r]" <<
endl;
631 cout <<
" M^T[c2][r0] = " <<
Mt.get_entry(
"c2",
"r0") <<
endl;
642 cout <<
"The identity() method creates I (only for square matrices)" <<
endl;
643 cout <<
"Property: A * I = I * A = A" <<
endl;
646 for (
int i = 0; i < 4; i++)
647 (
void)domain->insert(i);
656 cout <<
"\nMatrix A:" <<
endl;
659 auto I = A.identity();
660 cout <<
"\nIdentity matrix I:" <<
endl;
661 cout <<
I.to_str() <<
endl;
663 cout <<
"\nIdentity is sparse: only diagonal entries stored" <<
endl;
674 cout <<
"Multiple methods available for M * v:" <<
endl;
675 cout <<
" - Linear combination (default)" <<
endl;
676 cout <<
" - Dot product" <<
endl;
677 cout <<
" - Sparse iteration" <<
endl;
681 for (
int i = 0; i < 3; i++)
683 (
void)rows->insert(i);
684 (
void)cols->insert(i);
698 cout <<
"\nMatrix M:" <<
endl;
699 cout << M.to_str() <<
endl;
701 cout <<
"\nVector v: (0:1, 2:2) -- note v[1]=0 not stored" <<
endl;
705 cout <<
"\nM * v (linear combination):" <<
endl;
706 for (
auto it =
r1.get_it(); it.has_curr(); it.next())
708 auto e = it.get_curr();
709 cout <<
" [" << e.first <<
"] = " << e.second <<
endl;
714 cout <<
"\nM * v (dot product):" <<
endl;
715 for (
auto it = r2.get_it(); it.has_curr(); it.next())
717 auto e = it.get_curr();
718 cout <<
" [" << e.first <<
"] = " << e.second <<
endl;
722 auto r3 = M.mult_matrix_vector_sparse(v);
723 cout <<
"\nM * v (sparse):" <<
endl;
724 for (
auto it =
r3.get_it(); it.has_curr(); it.next())
726 auto e = it.get_curr();
727 cout <<
" [" << e.first <<
"] = " << e.second <<
endl;
730 cout <<
"\nAll methods produce same result (choose based on sparsity)" <<
endl;
738 cout <<
"\nVector u: (0:1.5, 2:3)" <<
endl;
740 cout <<
"\nu * M:" <<
endl;
741 for (
auto it =
r4.get_it(); it.has_curr(); it.next())
743 auto e = it.get_curr();
744 cout <<
" [" << e.
first <<
"] = " << e.second <<
endl;
756 cout <<
"Two methods for A * B:" <<
endl;
757 cout <<
" - vector_matrix_mult: row_i * B for each row" <<
endl;
758 cout <<
" - matrix_vector_mult: A * col_j for each column" <<
endl;
766 for (
int i = 0; i < 2; i++)
767 (
void)
rowsA->insert(i);
768 for (
int i = 0; i < 3; i++)
770 for (
int i = 0; i < 2; i++)
771 (
void)
colsB->insert(i);
786 cout <<
"\nMatrix A (2x3):" <<
endl;
789 cout <<
"\nMatrix B (3x2):" <<
endl;
790 cout << B.to_str() <<
endl;
793 auto C1 = A.vector_matrix_mult(B);
794 cout <<
"\nA * B (vector_matrix_mult):" <<
endl;
795 cout <<
C1.to_str() <<
endl;
798 auto C2 = A.matrix_vector_mult(B);
799 cout <<
"\nA * B (matrix_vector_mult):" <<
endl;
800 cout <<
C2.to_str() <<
endl;
802 cout <<
"\nBoth methods yield the same result" <<
endl;
803 cout <<
"Verified: C1 == C2 ? " << (
C1 ==
C2 ?
"YES" :
"NO") <<
endl;
814 cout <<
"The outer product of vectors u and v produces a matrix M" <<
endl;
815 cout <<
"where M[i][j] = u[i] * v[j]" <<
endl;
835 cout <<
"\nVector u: x=1, y=2, z=3" <<
endl;
836 cout <<
"Vector v: a=4, b=5" <<
endl;
839 cout <<
"\nOuter product u ⊗ v:" <<
endl;
840 cout << M.to_str() <<
endl;
842 cout <<
"\nVerification:" <<
endl;
843 cout <<
" M[y][a] = u[y] * v[a] = 2 * 4 = " << M.get_entry(
"y",
"a") <<
endl;
844 cout <<
" M[z][b] = u[z] * v[b] = 3 * 5 = " << M.get_entry(
"z",
"b") <<
endl;
855 cout <<
"Matrices can be compared with == and != operators" <<
endl;
856 cout <<
"Comparison uses epsilon tolerance for floating-point values" <<
endl;
859 for (
int i = 0; i < 2; i++)
860 (
void)domain->insert(i);
877 cout <<
"\nMatrix A:" <<
endl;
880 cout <<
"\nMatrix B (same as A):" <<
endl;
881 cout << B.to_str() <<
endl;
883 cout <<
"\nMatrix C (A[1][1] is 4.001):" <<
endl;
884 cout << C.to_str() <<
endl;
886 cout <<
"\nComparisons:" <<
endl;
887 cout <<
" A == B ? " << (A == B ?
"YES" :
"NO") <<
endl;
888 cout <<
" A == C ? " << (A == C ?
"YES" :
"NO") <<
endl;
889 cout <<
" A != C ? " << (A != C ?
"YES" :
"NO") <<
endl;
898 cout <<
"\nMatrix D has A[1][1] = 4.0 + 1e-8 (within epsilon=1e-7)" <<
endl;
899 cout <<
" A == D ? " << (A ==
D ?
"YES" :
"NO") <<
" (within epsilon tolerance)" <<
endl;
910 cout <<
"Supported: addition (+, +=), subtraction (-, -=), scalar mult (*)" <<
endl;
913 for (
int i = 0; i < 2; i++)
914 (
void)domain->insert(i);
926 cout <<
"\nMatrix A:" <<
endl;
929 cout <<
"\nMatrix B:" <<
endl;
930 cout << B.to_str() <<
endl;
934 cout <<
"\nA + B:" <<
endl;
939 cout <<
"\nA - B:" <<
endl;
944 cout <<
"\n2.5 * A:" <<
endl;
951 cout <<
"\nC = A; C += B:" <<
endl;
955 cout <<
"\nC.mult_by_scalar(0.5):" <<
endl;
967 cout <<
"Methods for working with rows and columns:" <<
endl;
968 cout <<
" - get_row_vector(), get_col_vector()" <<
endl;
969 cout <<
" - set_vector_as_row(), set_vector_as_col()" <<
endl;
970 cout <<
" - to_rowlist(), to_collist()" <<
endl;
971 cout <<
" - get_row_as_list(), get_col_as_list()" <<
endl;
975 (
void)rows->insert(
"A");
976 (
void)rows->insert(
"B");
977 (
void)cols->insert(
"X");
978 (
void)cols->insert(
"Y");
979 (
void)cols->insert(
"Z");
985 cout <<
"\nMatrix M:" <<
endl;
991 cout <<
"Row 'A' as vector:" <<
endl;
992 for (
auto it =
row_A.get_it(); it.has_curr(); it.next())
994 auto e = it.get_curr();
995 cout <<
" [" << e.first <<
"] = " << e.second <<
endl;
1001 cout <<
"Column 'Y' as vector:" <<
endl;
1002 for (
auto it =
col_Y.get_it(); it.has_curr(); it.next())
1004 auto e = it.get_curr();
1005 cout <<
" [" << e.first <<
"] = " << e.second <<
endl;
1016 cout <<
"After setting row 'B' to (10, 20, 30):" <<
endl;
1022 cout <<
"Matrix as list of " <<
row_list.size() <<
" row vectors" <<
endl;
1033 cout <<
"Using sparse matrices to represent linear systems" <<
endl;
1034 cout <<
"\nSystem: 2x + 3y = 13" <<
endl;
1035 cout <<
" 4x - y = 5" <<
endl;
1036 cout <<
"Solution: x=2, y=3" <<
endl;
1051 cout <<
"\nCoefficient matrix A:" <<
endl;
1059 cout <<
"\nSolution vector: x=2, y=3" <<
endl;
1062 auto b = A * solution;
1063 cout <<
"\nVerification A * solution:" <<
endl;
1064 for (
auto it = b.get_it(); it.has_curr(); it.next())
1066 auto e = it.get_curr();
1067 cout <<
" " << e.
first <<
" = " << e.second <<
endl;
1069 cout <<
"\nExpected: eq1=13, eq2=5 ✓" <<
endl;
1081 "Sparse Matrix and Vector example for Aleph-w.\n"
1082 "Demonstrates domain-based indexing and efficient sparse storage.",
1089 cout <<
"============================================================\n";
1090 cout <<
" ALEPH-W SPARSE MATRIX AND VECTOR EXAMPLE\n";
1091 cout <<
"============================================================\n";
1111 cout <<
"\n" << string(60,
'=') <<
"\n";
1112 cout <<
"Sparse Matrix and Vector demo completed!\n";
1113 cout << string(60,
'=') <<
"\n\n";
1117 catch (TCLAP::ArgException& e)
1119 cerr <<
"Error: " << e.error() <<
" for argument " << e.argId() <<
endl;
1122 catch (exception& e)
1124 cerr <<
"Error: " << e.what() <<
endl;
Functional programming utilities for Aleph-w containers.
void print_vec(const string &label, const vector< T > &v)
Integer domain classes for sparse data structures.
Sparse matrix with generic domains.
Sparse vector with named elements.
const Type * first() const
Get the first element.
Sparse matrix with generic row and column domains.
Vector< Trow, NumType > mult_matrix_vector_dot_product(const Vector< Tcol, NumType > &vec) const
Matrix-vector multiplication using dot products.
Vector< Tcol, NumType > get_row_vector(const Trow &row) const
Given a row, build a vector corresponding to the row.
DynList< Vector< Tcol, NumType > > to_rowlist() const
Return a list of vectors corresponding to the rows.
Matrix & mult_by_scalar(const NumType &scalar)
Multiply all entries by a scalar (in-place).
NumType get_entry(const Trow &row, const Tcol &col)
Get an entry value (non-const version with lazy cleanup).
Vector< Trow, NumType > get_col_vector(const Tcol &col) const
Given a column, build a vector corresponding to the column.
std::string to_str() const
Convert matrix to a formatted string representation.
Matrix transpose() const
Compute the transpose of this matrix.
void set_entry(const Trow &row, const Tcol &col, const NumType &val)
Set an entry value.
Matrix & set_vector_as_row(const Trow &row, const Vector< Tcol, NumType > &vec)
Set a row from a vector.
Sparse vector implementation with domain-based indexing.
void set_entry(const T &i, const NumType &value)
Set a vector entry at given index.
const NumType & get_epsilon() const noexcept
Get the epsilon value used for zero comparisons.
Iterator get_it() const noexcept
void set_epsilon(const NumType &e) noexcept
Set the epsilon value for zero comparisons.
NumType get_entry(const T &i)
Get vector entry at given index (non-const version)
DynArray< Graph::Node * > nodes
Singly linked list implementations with head-tail access.
void print_subsection(const string &title)
void demo_vector_arithmetic()
void print_section(const string &title)
void demo_outer_product()
void demo_linear_system()
void demo_string_indexed_vector()
void demo_adjacency_matrix()
void demo_sparse_matrix()
void demo_matrix_vector_mult()
void demo_matrix_arithmetic()
void demo_initializer_list()
void demo_row_col_operations()
void demo_sparse_vector()
Main namespace for Aleph-w library functions.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
bool diff(const C1 &c1, const C2 &c2, Eq e=Eq())
Check if two containers differ.
Matrix< Trow, Tcol, NumType > outer_product(const Vector< Trow, NumType > &v1, const Vector< Tcol, NumType > &v2)
Compute the outer product of two vectors.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.