146#include <tclap/CmdLine.h>
155using namespace Aleph;
163 cout <<
"\n" << string(60,
'=') <<
"\n";
165 cout << string(60,
'=') <<
"\n\n";
186 for (
int i = 0; i < 10; 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;
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;
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++)
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++)
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;
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;
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;
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;
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++)
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;
489 cout <<
"\nGraph statistics:" <<
endl;
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++)
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++)
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;
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++)
659 auto I = A.identity();
660 cout <<
"\nIdentity matrix I:" <<
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;
677 cout <<
" - Sparse iteration" <<
endl;
681 for (
int i = 0; i < 3; i++)
684 (
void)cols->insert(i);
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;
713 auto r2 = M.mult_matrix_vector_dot_product(v);
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;
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++)
768 for (
int i = 0; i < 3; i++)
770 for (
int i = 0; i < 2; i++)
786 cout <<
"\nMatrix A (2x3):" <<
endl;
789 cout <<
"\nMatrix B (3x2):" <<
endl;
793 auto C1 = A.vector_matrix_mult(
B);
794 cout <<
"\nA * B (vector_matrix_mult):" <<
endl;
798 auto C2 = A.matrix_vector_mult(
B);
799 cout <<
"\nA * B (matrix_vector_mult):" <<
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;
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++)
880 cout <<
"\nMatrix B (same as A):" <<
endl;
883 cout <<
"\nMatrix C (A[1][1] is 4.001):" <<
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++)
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;
976 (
void)rows->insert(
"B");
977 (
void)cols->insert(
"X");
978 (
void)cols->insert(
"Y");
979 (
void)cols->insert(
"Z");
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;
1033 cout <<
"Using sparse matrices to represent linear systems" <<
endl;
1034 cout <<
"\nSystem: 2x + 3y = 13" <<
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.
T & insert(const T &item)
Insert a new item by copy.
size_t size() const noexcept
Count the number of elements of the list.
Sparse matrix with generic row and column domains.
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)
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
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.
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.
DynList< T > maps(const C &c, Op op)
Classic map operation.
T sum(const Container &container, const T &init=T{})
Compute sum of all elements.