BRAGA

02 Writing02-02 Notes02-02-214

Scalar Multiplication

Published 16 Apr 20267 min read
Contents
  1. 01Deep Breakdown
  2. 02Flowchart
  3. 03Real-world use
  4. 04The formula, piece by piece
  5. 05The formula in words
  6. 06Critical Concepts
  7. 07Step-by-step calculation (tiny example)
  8. 08Code examples
kv⃗=kv1i⃗+kv2j⃗+kv3k⃗k\vec{v} = kv_1\vec{i} + kv_2\vec{j} + kv_3\vec{k}
(1)

Deep Breakdown

What it tells me (Situation Awareness): Scalar multiplication scales every component of a vector by a constant kk: kv⃗=(kv1,kv2,kv3)k\vec{v} = (kv_1, kv_2, kv_3). Geometrically, it stretches or compresses the vector along its own direction (∣k∣>1|k|>1 stretches, 0<∣k∣<10<|k|<1 shrinks, k<0k<0 reverses direction, k=0k=0 collapses to the zero vector). This is one of the two core operations defining a vector space. In DA/DS: learning rate times gradient (α∇L\alpha \nabla L), normalizing vectors (dividing by norm = scalar multiplication by 1/∣v⃗∣1/|\vec{v}|), standardizing features (dividing by standard deviation), and scaling predictions.

Flowchart

k 10 < k < 1k < 0k = 0k = 1Input: scalar k,vector v = (v1,v2, v3)Multiply k byeach componentseparatelyk*v1, k*v2, k*v3Result: vector kvof samedimensionInterpret kVector stretched(same direction)Vectorcompressed(same direction)Vector reversedand scaledResult is zerovectorIdentity: vectorunchanged

Real-world use

Where it is used

Gradient descent step: w⃗t+1=w⃗t−α∇L\vec{w}_{t+1} = \vec{w}_t - \alpha \nabla L involves scalar multiplication (α\alpha scales the gradient vector). Normalizing a feature vector to unit length: v⃗^=v⃗/∣v⃗∣\hat{\vec{v}} = \vec{v}/|\vec{v}| is scalar multiplication by 1/∣v⃗∣1/|\vec{v}|. Min-max scaling: dividing by the range. Softmax temperature: dividing logits by temperature TT before softmax is scaling by 1/T1/T.

Problem it solves

Allows uniform rescaling of all dimensions simultaneously without changing direction (when k>0k>0). This is essential for normalization, regularization (penalizing λ⋅∥w⃗∥\lambda \cdot \|\vec{w}\| requires scaling), and controlling the step size in optimization without affecting the direction of the update.

How it solves the problem

The operation distributes over each component independently, preserving linear structure. This works because the basis vectors i⃗,j⃗,k⃗\vec{i}, \vec{j}, \vec{k} are independent: scaling one axis does not affect another. Key property: ∣kv⃗∣=∣k∣⋅∣v⃗∣|k\vec{v}| = |k| \cdot |\vec{v}| (magnitude scales by ∣k∣|k|), and the direction is unchanged when k>0k > 0 (reversed when k<0k < 0).

Example in a business

A DS trains a neural network and observes the gradients exploding (large magnitudes). They apply gradient clipping: if ∥∇∥>threshold\|\nabla\| > \text{threshold}, they scale the gradient: ∇←threshold∥∇∥⋅∇\nabla \leftarrow \frac{\text{threshold}}{\|\nabla\|} \cdot \nabla. This is scalar multiplication by the factor threshold/∥∇∥\text{threshold}/\|\nabla\|, which shrinks the gradient to a safe magnitude without changing its direction.

The formula, piece by piece

  • kk: the scalar multiplier; any real number
  • v⃗\vec{v}: the input vector; stays as a vector throughout
  • kv1,kv2,kv3kv_1, kv_2, kv_3: each component is independently multiplied by kk
  • kv⃗k\vec{v}: the result vector; same dimension as v⃗\vec{v}, scaled by ∣k∣|k|, direction preserved if k>0k>0, reversed if k<0k<0
  • Extension to nn dimensions: kv⃗=(kv1,kv2,…,kvn)k\vec{v} = (kv_1, kv_2, \ldots, kv_n)

The formula in words

"Take the scalar kk and multiply every single component of the vector by it. You get back a vector of the same dimension, but stretched or shrunk by factor ∣k∣|k|. If kk is negative, the vector also flips direction." Tiny example: k=3k = 3, v⃗=(1,−2,4)\vec{v} = (1, -2, 4). kv⃗=(3⋅1,3⋅(−2),3⋅4)=(3,−6,12)k\vec{v} = (3\cdot1, 3\cdot(-2), 3\cdot4) = (3, -6, 12). Magnitude check: ∣v⃗∣=1+4+16=21|\vec{v}| = \sqrt{1+4+16} = \sqrt{21}; ∣kv⃗∣=9+36+144=189=321=k∣v⃗∣|k\vec{v}| = \sqrt{9+36+144} = \sqrt{189} = 3\sqrt{21} = k|\vec{v}|. ✓\checkmark

Critical Concepts

  • Distributivity: k(u⃗+v⃗)=ku⃗+kv⃗k(\vec{u}+\vec{v}) = k\vec{u}+k\vec{v} and (k+m)v⃗=kv⃗+mv⃗(k+m)\vec{v} = k\vec{v}+m\vec{v}.
  • Associativity with scalars: (km)v⃗=k(mv⃗)(km)\vec{v} = k(m\vec{v}).
  • Unit scalar: 1⋅v⃗=v⃗1 \cdot \vec{v} = \vec{v} (identity element for scalar multiplication).
  • Zero scalar: 0⋅v⃗=0⃗0 \cdot \vec{v} = \vec{0}.
  • Normalization: dividing by the norm is scalar multiplication by 1/∣v⃗∣1/|\vec{v}|; produces a unit vector v⃗^\hat{\vec{v}} with magnitude 1.
  • Direction preservation: when k>0k > 0, kv⃗k\vec{v} and v⃗\vec{v} are parallel (same direction). When k<0k < 0, antiparallel (opposite direction).
  • In NumPy: simply k * v; Python applies broadcasting automatically.

Step-by-step calculation (tiny example)

Step 1: Identify the scalar and vector k=−2k = -2, v⃗=(3,1,−5)\vec{v} = (3, 1, -5).

Step 2: Multiply each component by k −2⋅3=−6-2 \cdot 3 = -6, −2⋅1=−2\quad -2 \cdot 1 = -2, −2⋅(−5)=10\quad -2 \cdot (-5) = 10.

Step 3: Write the result and verify direction reversal kv⃗=(−6,−2,10)k\vec{v} = (-6, -2, 10). Both components have flipped sign compared to v⃗\vec{v} because k<0k < 0. ∣v⃗∣=9+1+25=35|\vec{v}| = \sqrt{9+1+25}=\sqrt{35}; ∣kv⃗∣=36+4+100=140=235|k\vec{v}| = \sqrt{36+4+100}=\sqrt{140}=2\sqrt{35}. ✓\checkmark magnitude scaled by ∣k∣=2|k|=2.

Code examples

Beginner example (Python)

python
import numpy as np

# -- Scalar multiplication: scaling, normalizing ---
v = np.array([3.0, 1.0, -5.0])
k = -2.0
scaled = k * v
print(f"v = {v}")
print(f"k = {k}")
print(f"k * v = {scaled}")   # [-6. -2. 10.]
print(f"|v| = {np.linalg.norm(v):.4f}")
print(f"|k*v| = {np.linalg.norm(scaled):.4f}")
print(f"|k|*|v| = {abs(k)*np.linalg.norm(v):.4f}")
print(f"Magnitude scales by |k|: {np.isclose(np.linalg.norm(scaled), abs(k)*np.linalg.norm(v))}")

# Normalization (scalar multiplication by 1/|v|)
unit_v = v / np.linalg.norm(v)
print(f"\nUnit vector v/|v| = {unit_v.round(4)}")
print(f"|unit_v| = {np.linalg.norm(unit_v):.6f}")   # should be 1.0

Beginner example (R)

r
# -- Scalar multiplication and normalization ---
v <- c(3, 1, -5)
k <- -2
scaled <- k * v
cat("v :", v, "\n")
cat("k * v :", scaled, "\n")
cat(sprintf("|v| : %.4f\n", sqrt(sum(v^2))))
cat(sprintf("|k*v| : %.4f\n", sqrt(sum(scaled^2))))
cat(sprintf("|k|*|v| : %.4f\n", abs(k)*sqrt(sum(v^2))))

# Normalization
unit_v <- v / sqrt(sum(v^2))
cat("Unit v :", round(unit_v, 4), "\n")
cat(sprintf("|unit_v| = %.6f\n", sqrt(sum(unit_v^2))))

Professional example (Python)

python
import numpy as np
import pandas as pd
np.random.seed(42)

# -- Business scenario: gradient clipping and feature normalization ---
# Two common uses of scalar multiplication in a DS workflow:
# 1. Gradient clipping: scale gradient down if norm exceeds a threshold
# 2. Min-max normalization: scale feature vectors to [0, 1] range

# 1. Gradient clipping
MAX_GRAD_NORM = 1.0
gradient = np.random.randn(8)  # simulated gradient for 8 parameters
grad_norm = np.linalg.norm(gradient)
if grad_norm > MAX_GRAD_NORM:
    clip_factor = MAX_GRAD_NORM / grad_norm
    gradient_clipped = clip_factor * gradient  # scalar multiplication
    clipped = True
else:
    gradient_clipped = gradient
    clip_factor = 1.0
    clipped = False

print("=== Gradient Clipping ===")
print(f"Original gradient norm : {grad_norm:.4f}")
print(f"Clipping threshold : {MAX_GRAD_NORM}")
print(f"Clip factor (k) : {clip_factor:.4f}")
print(f"Clipped gradient norm : {np.linalg.norm(gradient_clipped):.4f}")
print(f"Direction preserved? : {np.isclose(np.dot(gradient, gradient_clipped), np.linalg.norm(gradient)*np.linalg.norm(gradient_clipped))}")

# 2. Feature normalization (min-max scaling)
print("\n=== Feature Normalization ===")
feature_names = ["age", "income", "tenure_months", "n_purchases"]
raw_features = np.array([[45, 85000, 36, 12], [28, 42000, 8, 3], [62, 120000, 72, 45], [34, 67000, 18, 7]], dtype=float)
col_min = raw_features.min(axis=0)
col_max = raw_features.max(axis=0)
col_range = col_max - col_min

# Min-max scaling: for each column, scale by 1/range (scalar mult), then shift
scaled_features = (raw_features - col_min) / col_range  # scalar mult per col
df_raw = pd.DataFrame(raw_features, columns=feature_names)
df_scaled = pd.DataFrame(scaled_features, columns=feature_names)
print("Raw features:\n", df_raw.to_string(index=False))
print("\nScaled features [0,1]:\n", df_scaled.round(4).to_string(index=False))

Professional example (R)

r
# Gradient clipping (scalar mult) and min-max feature scaling
set.seed(42)
MAX_GRAD_NORM <- 2.0
gradient <- rnorm(10, 0, 1.5)
grad_norm <- sqrt(sum(gradient^2))
clip_factor <- if (grad_norm > MAX_GRAD_NORM) MAX_GRAD_NORM / grad_norm else 1.0
gradient_clipped <- clip_factor * gradient
cat(sprintf("Gradient norm: %.4f Clipped: %.4f\n", grad_norm, sqrt(sum(gradient_clipped^2))))
raw_features <- matrix(c(45, 85000, 36, 12, 28, 42000, 8, 3, 62, 120000, 72, 45, 34, 67000, 18, 7), nrow = 4, byrow = TRUE)
col_min <- apply(raw_features, 2, min)
col_max <- apply(raw_features, 2, max)
scaled_features <- sweep(sweep(raw_features, 2, col_min, "-"), 2, col_max - col_min, "/")
cat("Scaled features [0,1]:\n")
print(round(scaled_features, 4))

Source: 1300 p. 130

#linear-algebra#vectors-and-dimensionality#vector-operations

Keyboard shortcuts

Single keys, ignored while typing in a field or with Cmd, Ctrl or Alt held.

0
Home
1 2 3 4
Work, Writing, Tools, About
j / k
Next / previous section on this page
n / p
Next / previous project or essay
u
Up one level
l
Deutsch
t
Light or dark theme
?
This list
Esc
Close