Vector Demo — Practical Numeric Vectors
Vector<T> is a dynamically-sized numeric vector, and
StaticVector<T, N> is a fixed-size vector whose dimension is determined at compile time.
They provide fundamental vector operations including dot product (dot),
norm (norm), and normalization (normalized).
This page presents three demos showcasing practical applications of vector operations. All outputs below were actually computed by calx. The source code is provided at the bottom of the page, and you can reproduce the same results by building calx.
Demo 1: PageRank — Ranking Web Pages with the Power Method
We compute Google's PageRank algorithm using the power method.
The ranking vector is iteratively updated for a 4-page web graph
to determine the importance of each page.
A damping factor of 0.85 is used, with norm(next - r) for convergence testing.
Demo 2: 3D Ray Reflection — Computing the Reflection Vector with dot product
We compute 3D ray reflection using the dot product.
The reflection formula $\mathbf{r}' = \mathbf{r} - 2(\mathbf{r} \cdot \mathbf{n})\mathbf{n}$ is
implemented with StaticVector.
The angle of incidence is obtained as $\cos^{-1}(-\mathbf{r} \cdot \mathbf{n})$.
Demo 3: Cosine Similarity — Semantic Distance Between Documents
We represent documents using the vector space model and compute their similarity with cosine similarity $\cos\theta = \frac{\mathbf{a} \cdot \mathbf{b}}{|\mathbf{a}||\mathbf{b}|}$. This is a fundamental technique in information retrieval and machine learning.
Source Code and How to Run
All outputs on this page were generated from the following C++ program. You can reproduce the same results by building calx.
example_vector_demo.cpp (click to expand)
// Copyright (C) 2026 Kiyotsugu Arai
// SPDX-License-Identifier: LGPL-3.0-or-later
// example_vector_demo.cpp
// Vector demo: showcasing Vector's capabilities in 3 scenarios
//
// Build:
// cl /std:c++latest /EHsc /O2 /MD /utf-8 /I<calx>/include examples\example_vector_demo.cpp /MACHINE:X64
#include <math/core/vector.hpp>
#include <iostream>
#include <iomanip>
#include <cmath>
#include <string>
#include <vector>
using namespace calx;
// ============================================================================
// Demo 1: PageRank -- Ranking Web Pages with the Power Method
// -- Google's original algorithm, computed with vector iteration
// ============================================================================
static void demo_pagerank() {
std::cout << "============================================================\n";
std::cout << " Demo 1: PageRank -- Ranking Web Pages\n";
std::cout << "============================================================\n\n";
// A small web graph (4 pages):
// Page 0 -> Page 1, Page 2
// Page 1 -> Page 2
// Page 2 -> Page 0
// Page 3 -> Page 0, Page 1, Page 2
const int N = 4;
const double damping = 0.85;
const std::string names[] = {"Home", "About", "Blog", "External"};
// Build column-stochastic transition matrix (stored as rows for simplicity)
// M[i][j] = probability of going from page j to page i
double M[N][N] = {};
// Page 0 links to 1, 2 (each gets 1/2)
M[1][0] = 0.5; M[2][0] = 0.5;
// Page 1 links to 2
M[2][1] = 1.0;
// Page 2 links to 0
M[0][2] = 1.0;
// Page 3 links to 0, 1, 2 (each gets 1/3)
M[0][3] = 1.0/3; M[1][3] = 1.0/3; M[2][3] = 1.0/3;
// Power iteration: r = d * M * r + (1-d)/N
Vector<double> r(N, 1.0 / N); // uniform initial
const double teleport = (1.0 - damping) / N;
std::cout << " Iterating with damping factor = " << damping << " ...\n\n";
for (int iter = 0; iter < 50; ++iter) {
Vector<double> next(N, teleport);
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
next[i] += damping * M[i][j] * r[j];
double diff = norm(next - r);
r = std::move(next);
if (diff < 1e-10) {
std::cout << " Converged after " << (iter + 1) << " iterations.\n\n";
break;
}
}
// Display rankings
std::cout << std::fixed << std::setprecision(4);
std::cout << " Page Rankings:\n";
for (int i = 0; i < N; ++i) {
int bar_len = static_cast<int>(r[i] * 100);
std::cout << " " << std::setw(10) << names[i] << ": " << r[i]
<< " " << std::string(bar_len, '#') << "\n";
}
std::cout << " Sum = " << (r[0] + r[1] + r[2] + r[3]) << "\n\n";
}
// ============================================================================
// Demo 2: Ray Reflection in 3D -- Light Bouncing Off Mirrors
// -- Using dot product and cross product for geometric computation
// ============================================================================
static void demo_ray_reflection() {
std::cout << "============================================================\n";
std::cout << " Demo 2: Ray Reflection in 3D\n";
std::cout << "============================================================\n\n";
// Incident ray direction (pointing downward at 45 degrees)
StaticVector<double, 3> ray{1.0, -1.0, 0.0};
ray = ray.normalized();
// Mirror surface normals for 3 bounces
StaticVector<double, 3> normals[] = {
StaticVector<double, 3>{0.0, 1.0, 0.0}, // horizontal floor
StaticVector<double, 3>{-1.0, 1.0, 0.0}.normalized(), // tilted wall
StaticVector<double, 3>{0.0, 0.0, 1.0}, // vertical wall (z)
};
auto print_v3 = [](const char* label, const StaticVector<double, 3>& v) {
std::cout << " " << std::setw(16) << label << ": ("
<< std::setw(7) << v[0] << ", "
<< std::setw(7) << v[1] << ", "
<< std::setw(7) << v[2] << ")\n";
};
std::cout << std::fixed << std::setprecision(4);
print_v3("Initial ray", ray);
for (int bounce = 0; bounce < 3; ++bounce) {
const auto& n = normals[bounce];
// Reflection formula: r' = r - 2(r . n)n
double dn = dot(ray, n);
StaticVector<double, 3> reflected;
for (int i = 0; i < 3; ++i)
reflected[i] = ray[i] - 2.0 * dn * n[i];
// Angle of incidence
double angle = std::acos(-dn) * 180.0 / 3.14159265358979;
std::cout << "\n Bounce " << (bounce + 1) << ":\n";
print_v3("Surface normal", n);
std::cout << " Angle of incidence: " << angle << " degrees\n";
print_v3("Reflected ray", reflected);
ray = reflected;
}
std::cout << std::endl;
}
// ============================================================================
// Demo 3: Cosine Similarity -- How Similar Are Two Vectors?
// -- A fundamental operation in information retrieval and machine learning
// ============================================================================
static void demo_cosine_similarity() {
std::cout << "============================================================\n";
std::cout << " Demo 3: Cosine Similarity -- Document Comparison\n";
std::cout << "============================================================\n\n";
// Term frequency vectors for 5 documents
// Dimensions: [math, science, art, music, sports]
struct Doc {
const char* name;
Vector<double> tf;
};
Doc docs[] = {
{"Algebra Textbook", Vector<double>{9.0, 3.0, 0.0, 0.0, 0.0}},
{"Physics Paper", Vector<double>{5.0, 8.0, 0.0, 0.0, 1.0}},
{"Art History", Vector<double>{0.0, 0.0, 9.0, 2.0, 0.0}},
{"Music Theory", Vector<double>{2.0, 0.0, 3.0, 8.0, 0.0}},
{"Sports Analytics", Vector<double>{4.0, 2.0, 0.0, 0.0, 9.0}},
};
const int nd = 5;
std::cout << " Documents (term frequencies: [math, science, art, music, sports]):\n";
for (auto& d : docs) {
std::cout << " " << std::setw(20) << d.name << ": [";
for (size_t i = 0; i < d.tf.size(); ++i)
std::cout << (i ? ", " : "") << static_cast<int>(d.tf[i]);
std::cout << "]\n";
}
// Cosine similarity matrix
const char* abbr[] = {"Algebra", "Physics", "Art", "Music", "Sports"};
std::cout << "\n Cosine Similarity Matrix:\n\n";
std::cout << std::setw(22) << "";
for (int i = 0; i < nd; ++i) std::cout << std::setw(10) << abbr[i];
std::cout << "\n";
std::cout << std::fixed << std::setprecision(3);
for (int i = 0; i < nd; ++i) {
std::cout << " " << std::setw(18) << docs[i].name;
for (int j = 0; j < nd; ++j) {
double sim = dot(docs[i].tf, docs[j].tf) / (norm(docs[i].tf) * norm(docs[j].tf));
std::cout << std::setw(10) << sim;
}
std::cout << "\n";
}
std::cout << "\n Most similar pair: Algebra Textbook <-> Physics Paper\n";
std::cout << " Most different: Art History <-> Sports Analytics\n";
std::cout << std::endl;
}
// ============================================================================
// main
// ============================================================================
int main() {
std::cout << "###########################################################\n";
std::cout << "# calx Vector Demo #\n";
std::cout << "###########################################################\n\n";
demo_pagerank();
demo_ray_reflection();
demo_cosine_similarity();
std::cout << "###########################################################\n";
std::cout << "# All demos completed #\n";
std::cout << "###########################################################\n";
return 0;
}
For API details, see the Vector API Reference.
Build and Run
cd calx
mkdir build && cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release --target example-vector-demo
examples\Release\example-vector-demo.exe