Complete Mathematical Reference

Trigonometry

Circles · Triangles · Angles · Cryptography · GNU Octave

Angles & Radians Unit Circle Triangles Identities Inverse Functions Waves & Signals Fourier Series Cryptography GNU Octave

§01 Angles & Measurement

An angle is formed by two rays sharing a common endpoint (the vertex). Trigonometry lives on the interplay between angles, arc lengths, and ratios — this section establishes the two primary units of angular measure.

Degrees

The full rotation of a circle is divided into 360°. This convention traces to Babylonian astronomy (~360-day calendar). A right angle is 90°, a straight angle 180°.

Radians

One radian is the angle subtended at the centre of a circle by an arc equal in length to the radius. A full circle contains 2π radians. Radians are dimensionless and are the natural unit for calculus and signal processing.

2π rad = 360° ⟹ 1 rad = 180°/π ≈ 57.2958°

Conversion Formulae

degrees → radians: rad = deg × π/180
radians → degrees: deg = rad × 180/π

Key Angle Reference

DegreesRadians (exact)Radians (decimal)Description
00.0000Zero angle
30°π/60.5236Sixth of half-circle
45°π/40.7854Eighth of full circle
60°π/31.0472Equilateral triangle
90°π/21.5708Right angle
120°2π/32.0944Interior angle of regular hexagon
135°3π/42.3562Obtuse
150°5π/62.6180Supplement of 30°
180°π3.1416Straight angle
270°3π/24.7124Three-quarter turn
360°6.2832Full rotation

Arc Length & Sector Area

For a circle of radius r and central angle θ (in radians):

Arc length: s = r·θ
Sector area: A = ½ r² θ

GNU Octave — Angles

GNU Octave
% ──── Angle Conversion in GNU Octave ────────────────────────────
% Octave works natively in RADIANS for trig functions

% Degrees to radians
degrees = [0, 30, 45, 60, 90, 180, 360];
radians = degrees .* (pi ./ 180);
printf("Degrees: "); disp(degrees);
printf("Radians: "); disp(radians);

% Octave built-in conversion
r1 = deg2rad(45);     % 0.7854
d1 = rad2deg(pi/4);   % 45.000

% Arc length and sector area
r = 5;           % radius = 5 units
theta = pi/3;   % 60 degrees
arc_len  = r * theta;              % s = r * θ
sec_area = 0.5 * r^2 * theta;     % A = ½r²θ
printf("Arc length : %.4f\n", arc_len);
printf("Sector area: %.4f\n", sec_area);

% Visualise angle conversion table
printf("\n%-10s %-15s %-15s\n", "Degrees", "Radians", "Fraction of π");
for d = [0,30,45,60,90,120,180,270,360]
  printf("%-10d %-15.6f %-15.6f\n", d, deg2rad(d), deg2rad(d)/pi);
endfor

§02 The Unit Circle

The unit circle is a circle of radius 1 centred at the origin (0,0) in the Cartesian plane. It is the foundational object of trigonometry — every trig function value for every angle can be read off it.

Equation of the unit circle: x² + y² = 1

For an angle θ measured counter-clockwise from the positive x-axis, the terminal point on the unit circle has coordinates:

x = cos θ
y = sin θ
Interactive Unit Circle — hover to see angle values

Special Angles on the Unit Circle

Angle (deg)Angle (rad)cos θsin θtan θ
0100
30°π/6√3/2 ≈ 0.8661/2 = 0.51/√3 ≈ 0.577
45°π/4√2/2 ≈ 0.707√2/2 ≈ 0.7071
60°π/31/2 = 0.5√3/2 ≈ 0.866√3 ≈ 1.732
90°π/201undefined
120°2π/3-1/2√3/2-√3
135°3π/4-√2/2√2/2-1
150°5π/6-√3/21/2-1/√3
180°π-100
210°7π/6-√3/2-1/21/√3
225°5π/4-√2/2-√2/21
240°4π/3-1/2-√3/2√3
270°3π/20-1undefined
300°5π/31/2-√3/2-√3
315°7π/4√2/2-√2/2-1
330°11π/6√3/2-1/2-1/√3
360°100

The Four Quadrants & Signs

Quadrant I (0° – 90°)

sin +, cos +, tan +
All functions positive.

Quadrant II (90° – 180°)

sin +, cos −, tan −
Sine is positive.

Quadrant III (180° – 270°)

sin −, cos −, tan +
Tan is positive.

Quadrant IV (270° – 360°)

sin −, cos +, tan −
Cos is positive.

Mnemonic: A S T C — "All Students Take Calculus" — Q1: All, Q2: Sin, Q3: Tan, Q4: Cos.

GNU Octave — Unit Circle

GNU Octave
% ──── Plot the Unit Circle with special angles ───────────────────
figure('Name', 'Unit Circle');
theta_fine = 0:0.01:2*pi;
plot(cos(theta_fine), sin(theta_fine), 'b-', 'LineWidth', 2); hold on;

% Draw axes
line([-1.3 1.3], [0 0], 'Color', 'k');
line([0 0], [-1.3 1.3], 'Color', 'k');

% Plot special angles
angles = [0, pi/6, pi/4, pi/3, pi/2, 2*pi/3, 3*pi/4, 5*pi/6, pi, ...
           7*pi/6, 5*pi/4, 4*pi/3, 3*pi/2, 5*pi/3, 7*pi/4, 11*pi/6];
labels = {'0','π/6','π/4','π/3','π/2','2π/3','3π/4','5π/6','π', ...
          '7π/6','5π/4','4π/3','3π/2','5π/3','7π/4','11π/6'};

for i = 1:length(angles)
  cx = cos(angles(i)); cy = sin(angles(i));
  plot(cx, cy, 'ro', 'MarkerSize', 6, 'MarkerFaceColor', 'r');
  line([0 cx], [0 cy], 'Color', [0.7 0.7 0.7], 'LineStyle', '--');
  text(cx*1.15, cy*1.15, labels{i}, 'FontSize', 9, 'HorizontalAlignment', 'center');
endfor

axis equal; axis([-1.5 1.5 -1.5 1.5]);
title('The Unit Circle'); xlabel('cos θ'); ylabel('sin θ');
grid on; hold off;

§03 Trigonometric Functions

The Six Functions — Definitions

For a right triangle with hypotenuse h, opposite side o, and adjacent side a relative to angle θ:

Primary Functions

sin θ = opposite / hypotenuse = o/h
cos θ = adjacent / hypotenuse = a/h
tan θ = opposite / adjacent = o/a

Reciprocal Functions

csc θ = 1/sin θ = h/o
sec θ = 1/cos θ = h/a
cot θ = 1/tan θ = a/o
Mnemonic for SOH-CAH-TOA: Sine = Opposite/Hypotenuse, Cosine = Adjacent/Hypotenuse, Tangent = Opposite/Adjacent.

Relating tan to sin and cos

tan θ = sin θ / cos θ
cot θ = cos θ / sin θ

Evaluating Trig Functions — Key Values

θsin θcos θtan θcsc θsec θcot θ
0101
30°½√3/21/√322/√3√3
45°√2/2√2/21√2√21
60°√3/2½√32/√321/√3
90°1010

GNU Octave — Evaluating All Six Functions

GNU Octave
% ──── Six Trig Functions in GNU Octave ───────────────────────────
theta_deg = 30;
theta     = deg2rad(theta_deg);

s  = sin(theta);        % sine
c  = cos(theta);        % cosine
t  = tan(theta);        % tangent
cs = 1/sin(theta);     % cosecant
se = 1/cos(theta);     % secant
co = 1/tan(theta);     % cotangent

printf("θ = %d° = %.4f rad\n", theta_deg, theta);
printf("sin = %.6f\ncos = %.6f\ntan = %.6f\n", s, c, t);
printf("csc = %.6f\nsec = %.6f\ncot = %.6f\n", cs, se, co);

% ──── Table for all key angles ────────────────────────────────────
printf("\n%-6s %-10s %-10s %-10s\n", "Deg", "sin", "cos", "tan");
for d = [0,30,45,60,90,120,135,150,180]
  r = deg2rad(d);
  if abs(cos(r)) < 1e-10
    printf("%-6d %-10.6f %-10.6f %-10s\n", d, sin(r), cos(r), "undef");
  else
    printf("%-6d %-10.6f %-10.6f %-10.6f\n", d, sin(r), cos(r), tan(r));
  endif
endfor

% ──── Verify Pythagorean identity: sin²+cos² = 1 ─────────────────
for d = [0:15:360]
  r   = deg2rad(d);
  val = sin(r)^2 + cos(r)^2;
  assert(val, 1, 1e-12);   % should not throw
endfor
disp("Pythagorean identity verified for all multiples of 15°");

§04 Triangles

Right Triangles — The Pythagorean Theorem

In a right triangle with legs a, b and hypotenuse c:

a² + b² = c²

Corollaries:

c = √(a² + b²)
a = √(c² − b²)
b = √(c² − a²)

Solving Right Triangles with SOH-CAH-TOA

Given one acute angle θ and one side, find all others:

Example: θ = 35°, hypotenuse c = 10

  • opposite = c · sin θ = 10 · sin 35° ≈ 10 × 0.5736 ≈ 5.736
  • adjacent = c · cos θ = 10 · cos 35° ≈ 10 × 0.8192 ≈ 8.192
  • other angle = 90° − 35° = 55°

Law of Sines

Valid for any triangle with sides a, b, c opposite to angles A, B, C:

a / sin A = b / sin B = c / sin C = 2R

where R is the circumradius of the triangle. Use when given: AAS, ASA, or SSA (with care).

Law of Cosines

Generalises the Pythagorean theorem to any triangle:

c² = a² + b² − 2ab cos C
cos C = (a² + b² − c²) / (2ab)

Use when given: SAS or SSS.

Law of Tangents

(a − b) / (a + b) = tan[(A−B)/2] / tan[(A+B)/2]

Area Formulae

Base × Height

A = ½ b h

Two Sides + Included Angle

A = ½ a b sin C

Heron's Formula (SSS)

s = (a+b+c)/2
A = √(s(s−a)(s−b)(s−c))

Special Triangles

30–60–90 Triangle

Sides in ratio: 1 : √3 : 2

If short leg = 1, then long leg = √3, hypotenuse = 2.

45–45–90 Triangle

Sides in ratio: 1 : 1 : √2

If legs = 1 each, hypotenuse = √2.

GNU Octave — Triangle Solver

GNU Octave
% ──── Right Triangle Solver ───────────────────────────────────────
function solve_right_triangle(theta_deg, hyp)
  theta = deg2rad(theta_deg);
  opp   = hyp * sin(theta);
  adj   = hyp * cos(theta);
  printf("θ=%.1f°  hyp=%.4f  opp=%.4f  adj=%.4f\n", theta_deg, hyp, opp, adj);
endfunction

solve_right_triangle(35, 10);
solve_right_triangle(60, 5);

% ──── Law of Cosines: find side c given a, b, C ───────────────────
function c = law_of_cosines(a, b, C_deg)
  C = deg2rad(C_deg);
  c = sqrt(a^2 + b^2 - 2*a*b*cos(C));
endfunction

c = law_of_cosines(7, 10, 45);
printf("Law of Cosines: c = %.6f\n", c);

% ──── Law of Sines: find angle B given a, b, A ────────────────────
function B_deg = law_of_sines_angle(a, b, A_deg)
  A   = deg2rad(A_deg);
  B   = asin(b * sin(A) / a);
  B_deg = rad2deg(B);
endfunction

B = law_of_sines_angle(8, 5, 50);
printf("Law of Sines: B = %.4f°\n", B);

% ──── Heron's Formula ────────────────────────────────────────────
function A = herons_area(a, b, c)
  s = (a + b + c) / 2;
  A = sqrt(s * (s-a) * (s-b) * (s-c));
endfunction

area = herons_area(5, 7, 9);
printf("Heron area of (5,7,9) triangle: %.6f\n", area);

% ──── Two-sided area formula ──────────────────────────────────────
area2 = 0.5 * 5 * 7 * sin(deg2rad(60));
printf("½ab·sinC area (a=5,b=7,C=60°): %.6f\n", area2);

§05 Trigonometric Identities

Identities are equations that hold for all values of θ (where defined). They are essential for simplifying expressions, solving equations, and proving results in both pure and applied mathematics.

Pythagorean Identities

Fundamental sin²θ + cos²θ = 1
Tan form tan²θ + 1 = sec²θ
Cot form 1 + cot²θ = csc²θ

Even / Odd (Symmetry) Identities

Even cos(−θ) = cos θ
Even sec(−θ) = sec θ
Odd sin(−θ) = −sin θ
Odd tan(−θ) = −tan θ
Odd csc(−θ) = −csc θ
Odd cot(−θ) = −cot θ

Sum & Difference Identities

sin(A+B) sinA cosB + cosA sinB
sin(A−B) sinA cosB − cosA sinB
cos(A+B) cosA cosB − sinA sinB
cos(A−B) cosA cosB + sinA sinB
tan(A+B) (tanA+tanB)/(1−tanA tanB)
tan(A−B) (tanA−tanB)/(1+tanA tanB)

Double Angle Identities

sin 2θ 2 sin θ cos θ
cos 2θ (a) cos²θ − sin²θ
cos 2θ (b) 2cos²θ − 1
cos 2θ (c) 1 − 2sin²θ
tan 2θ 2 tanθ / (1 − tan²θ)

Half Angle Identities

sin(θ/2) ±√[(1 − cosθ)/2]
cos(θ/2) ±√[(1 + cosθ)/2]
tan(θ/2) ±√[(1−cosθ)/(1+cosθ)]
tan(θ/2) alt sinθ/(1+cosθ)
tan(θ/2) alt2 (1−cosθ)/sinθ

Product-to-Sum & Sum-to-Product

sinA sinB ½[cos(A−B) − cos(A+B)]
cosA cosB ½[cos(A−B) + cos(A+B)]
sinA cosB ½[sin(A+B) + sin(A−B)]
sinA+sinB 2 sin[(A+B)/2] cos[(A−B)/2]
sinA−sinB 2 cos[(A+B)/2] sin[(A−B)/2]
cosA+cosB 2 cos[(A+B)/2] cos[(A−B)/2]
cosA−cosB −2 sin[(A+B)/2] sin[(A−B)/2]

Co-function Identities

sin sin(π/2 − θ) = cos θ
cos cos(π/2 − θ) = sin θ
tan tan(π/2 − θ) = cot θ
csc csc(π/2 − θ) = sec θ

GNU Octave — Verifying Identities

GNU Octave
% ──── Verify trig identities numerically ─────────────────────────
t = pi/7;   % arbitrary test angle
A = pi/5;
B = pi/8;
tol = 1e-12;

% Pythagorean
assert(sin(t)^2 + cos(t)^2,     1,             tol);
assert(tan(t)^2 + 1,              1/cos(t)^2,    tol);
disp("Pythagorean identities: OK");

% Double angle
assert(sin(2*t), 2*sin(t)*cos(t), tol);
assert(cos(2*t), cos(t)^2 - sin(t)^2, tol);
disp("Double angle identities: OK");

% Sum identities
assert(sin(A+B), sin(A)*cos(B) + cos(A)*sin(B), tol);
assert(cos(A+B), cos(A)*cos(B) - sin(A)*sin(B), tol);
disp("Sum/difference identities: OK");

% Product-to-sum
assert(sin(A)*sin(B), 0.5*(cos(A-B) - cos(A+B)), tol);
assert(cos(A)*cos(B), 0.5*(cos(A-B) + cos(A+B)), tol);
disp("Product-to-sum identities: OK");

% Half-angle (for positive quadrant only)
t2 = pi/5;
assert(sin(t2/2), sqrt((1 - cos(t2))/2), tol);
disp("Half-angle identity: OK");

§06 Inverse Trigonometric Functions

Inverse trig functions recover the angle from a known ratio. Because trig functions are periodic and thus not one-to-one over their full domain, we restrict domains to obtain unique inverses (principal values).

FunctionNotationDomainRange (principal)
arcsinsin⁻¹(x) or asin(x)[−1, 1][−π/2, π/2]
arccoscos⁻¹(x) or acos(x)[−1, 1][0, π]
arctantan⁻¹(x) or atan(x)(−∞, ∞)(−π/2, π/2)
arccsccsc⁻¹(x)(−∞,−1]∪[1,∞)[−π/2,0)∪(0,π/2]
arcsecsec⁻¹(x)(−∞,−1]∪[1,∞)[0,π/2)∪(π/2,π]
arccotcot⁻¹(x)(−∞, ∞)(0, π)

atan2 — The Four-Quadrant Arctangent

The standard atan only returns values in (−π/2, π/2). The two-argument form atan2(y, x) returns the full-circle angle of the vector (x, y), handling all four quadrants correctly. This is critical in robotics, navigation, and signal processing.

atan2(y, x) ∈ (−π, π]

Useful Identities with Inverses

sin(arcsin x) = x, |x| ≤ 1
arcsin(sin θ) = θ, θ ∈ [−π/2, π/2]
arcsin(x) + arccos(x) = π/2
arctan(x) + arccot(x) = π/2
arcsin(−x) = −arcsin(x)
arccos(−x) = π − arccos(x)

GNU Octave — Inverse Functions

GNU Octave
% ──── Inverse Trig Functions in Octave ───────────────────────────
% asin, acos, atan return radians
x = 0.5;
a1 = asin(x);          % = π/6
a2 = acos(x);          % = π/3
a3 = atan(x);          % ≈ 0.4636

printf("asin(0.5) = %.6f rad = %.4f°\n", a1, rad2deg(a1));
printf("acos(0.5) = %.6f rad = %.4f°\n", a2, rad2deg(a2));
printf("atan(0.5) = %.6f rad = %.4f°\n", a3, rad2deg(a3));

% atan2 — four-quadrant version
printf("\natan2 examples:\n");
printf("atan2(1, 1)   = %.4f° (Q1)\n", rad2deg(atan2(1,1)));
printf("atan2(1,-1)   = %.4f° (Q2)\n", rad2deg(atan2(1,-1)));
printf("atan2(-1,-1)  = %.4f° (Q3)\n", rad2deg(atan2(-1,-1)));
printf("atan2(-1, 1)  = %.4f° (Q4)\n", rad2deg(atan2(-1,1)));

% Verify: arcsin(x) + arccos(x) = π/2
for x = -1:0.25:1
  assert(asin(x) + acos(x), pi/2, 1e-12);
endfor
disp("arcsin(x) + arccos(x) = π/2 verified");

% Plot inverse functions
figure('Name', 'Inverse Trig');
x1 = linspace(-1, 1, 500);
x2 = linspace(-5, 5, 500);
subplot(1,3,1); plot(x1, rad2deg(asin(x1))); title('arcsin'); grid on;
subplot(1,3,2); plot(x1, rad2deg(acos(x1))); title('arccos'); grid on;
subplot(1,3,3); plot(x2, rad2deg(atan(x2))); title('arctan'); grid on;

§07 Graphs, Waves & Transformations

The General Sinusoidal Form

y = A · sin(Bx + C) + D   or   y = A · cos(Bx + C) + D

Amplitude: A

Half the distance from min to max. |A| stretches/compresses vertically. Negative A reflects across x-axis.

Period: T = 2π/|B|

Length of one complete cycle. B > 1 compresses, 0 < B < 1 stretches.

Phase Shift: −C/B

Horizontal shift. C > 0 shifts left, C < 0 shifts right.

Vertical Shift: D

Moves the midline up (D > 0) or down (D < 0).

Sine & Cosine waves — amplitude, period, phase

Properties of the Six Trig Function Graphs

FunctionPeriodAmplitudeDomainRangeZeros
sin x1[−1, 1]
cos x1[−1, 1]π/2 + nπ
tan xπℝ \ {π/2+nπ}
csc xℝ \ {nπ}(−∞,−1]∪[1,∞)none
sec xℝ \ {π/2+nπ}(−∞,−1]∪[1,∞)none
cot xπℝ \ {nπ}π/2+nπ

GNU Octave — Wave Generation & Plotting

GNU Octave
% ──── Sinusoidal wave transformations ────────────────────────────
x = linspace(0, 4*pi, 1000);

% y = A·sin(Bx + C) + D
A = 3;  B = 2;  C = pi/4;  D = 1;
y1 = A * sin(B*x + C) + D;
y2 = sin(x);                  % reference
y3 = cos(x);

figure('Name', 'Wave Transformations');
plot(x, y2, 'b-', 'LineWidth', 1.5); hold on;
plot(x, y3, 'r-', 'LineWidth', 1.5);
plot(x, y1, 'g-', 'LineWidth', 2);
legend('sin(x)', 'cos(x)', '3sin(2x+π/4)+1');
title('Sinusoidal Transformations'); grid on; hold off;

% ──── Sound wave: 440 Hz A note ──────────────────────────────────
Fs = 44100;          % sample rate Hz
dur = 1;             % 1 second
t  = 0:1/Fs:dur;
f  = 440;             % 440 Hz = concert A
wave = sin(2*pi*f*t);

figure('Name', '440 Hz A Note');
plot(t(1:500), wave(1:500));  % show first ~11ms
title('440 Hz sine wave (Concert A)');
xlabel('Time (s)'); ylabel('Amplitude'); grid on;

% ──── Phase shift visualisation ──────────────────────────────────
x = linspace(0, 2*pi, 500);
figure('Name', 'Phase Shifts');
phases = [0, pi/6, pi/4, pi/3, pi/2];
colours = {'b', 'r', 'g', 'm', 'c'};
hold on;
for i = 1:length(phases)
  plot(x, sin(x + phases(i)), colours{i}, 'LineWidth', 1.5);
endfor
legend('φ=0','φ=π/6','φ=π/4','φ=π/3','φ=π/2');
title('Phase Shifted Sine Waves'); grid on; hold off;

§08 Circles & Polar Coordinates

Standard Circle Equations

Unit Circle (centre origin)

x² + y² = 1

Circle radius r, centre (h,k)

(x−h)² + (y−k)² = r²

Parametric form

x = h + r cos θ
y = k + r sin θ

Polar Coordinates

A point P in the plane can also be described by polar coordinates (r, θ) — distance r from the origin and angle θ from the positive x-axis.

x = r cos θ, y = r sin θ
r = √(x²+y²), θ = atan2(y, x)

Important Polar Curves

CurvePolar EquationDescription
Circler = aCircle of radius a
Cardioidr = a(1 + cos θ)Heart-shaped curve
Lemniscater² = a² cos 2θFigure-eight
Rose (n petals)r = a cos(nθ)n petals if n is odd, 2n if even
Archimedean Spiralr = aθEqual spacing between arms
Limaçonr = a + b cos θSnail shape

Euler's Formula — The Bridge to Complex Numbers

The most beautiful equation in mathematics links trigonometry to the complex exponential function:

e = cos θ + i sin θ

Euler's formula reveals that rotation in the complex plane is multiplication by e^(iθ). Setting θ = π gives Euler's identity: e^(iπ) + 1 = 0.

cos θ = (e^(iθ) + e^(−iθ)) / 2
sin θ = (e^(iθ) − e^(−iθ)) / (2i)

De Moivre's Theorem

For integer n:

(cos θ + i sin θ)ⁿ = cos(nθ) + i sin(nθ)

Used to find roots of complex numbers and to derive multiple-angle formulae.

GNU Octave — Circles, Polar & Euler

GNU Octave
% ──── Polar Curves ────────────────────────────────────────────────
theta = linspace(0, 2*pi, 1000);

% Cardioid: r = 1 + cos(θ)
r_card = 1 + cos(theta);
figure('Name', 'Polar Curves');
subplot(2,3,1);
polar(theta, r_card); title('Cardioid: r=1+cos θ');

% Rose curve (4 petals): r = cos(2θ)
r_rose = cos(2*theta);
subplot(2,3,2);
polar(theta, r_rose); title('Rose: r=cos(2θ)');

% Archimedean spiral: r = θ/(2π)
theta_sp = linspace(0, 6*pi, 1000);
r_sp = theta_sp / (2*pi);
subplot(2,3,3);
polar(theta_sp, r_sp); title('Spiral: r=θ/2π');

% ──── Euler's formula: visualise e^(iθ) path ─────────────────────
theta_e = linspace(0, 2*pi, 1000);
z = exp(1i * theta_e);         % complex unit circle
subplot(2,3,4);
plot(real(z), imag(z)); axis equal; grid on;
title('e^{iθ} in complex plane');

% Verify Euler's formula
t = pi/4;
lhs = exp(1i * t);
rhs = cos(t) + 1i*sin(t);
assert(abs(lhs - rhs), 0, 1e-14);
printf("Euler's formula verified: e^(iπ/4) = %.6f + %.6fi\n", real(lhs), imag(lhs));

% De Moivre's theorem: (cos θ + i sin θ)^n = cos(nθ) + i sin(nθ)
n = 5; t = pi/7;
lhs = (cos(t) + 1i*sin(t))^n;
rhs = cos(n*t) + 1i*sin(n*t);
printf("De Moivre error: %.2e\n", abs(lhs - rhs));

% Polar to Cartesian and back
r0 = 5; theta0 = pi/3;
x0 = r0 * cos(theta0);
y0 = r0 * sin(theta0);
r_check = sqrt(x0^2 + y0^2);
t_check = atan2(y0, x0);
printf("Round-trip: r=%.4f (orig %.4f), θ=%.4f (orig %.4f)\n", ...
       r_check, r0, t_check, theta0);

§09 Fourier Series & Signal Analysis

The French mathematician Joseph Fourier proved that virtually any periodic function can be decomposed into a (possibly infinite) sum of sinusoids. This is the fundamental theorem of signal processing.

Fourier Series

For a periodic function f(x) with period 2L:

f(x) = a₀/2 + Σₙ₌₁^∞ [ aₙ cos(nπx/L) + bₙ sin(nπx/L) ]
aₙ = (1/L) ∫₋ₗᴸ f(x) cos(nπx/L) dx
bₙ = (1/L) ∫₋ₗᴸ f(x) sin(nπx/L) dx

Discrete Fourier Transform (DFT)

For a sequence of N complex numbers x₀, x₁, …, x_{N−1}:

X_k = Σₙ₌₀^{N−1} xₙ · e^{−i 2π k n / N}

The DFT converts a time-domain signal to frequency-domain. The Fast Fourier Transform (FFT) computes this in O(N log N) instead of O(N²).

Applications of Fourier / Trig in Signal Processing

GNU Octave — Fourier Series & FFT

GNU Octave
% ──── Fourier Series: Square Wave Approximation ───────────────────
% A square wave can be built from odd harmonics of sine
x = linspace(0, 2*pi, 2000);
N_terms = [1, 3, 7, 15, 51];
figure('Name', 'Fourier Series');
for idx = 1:length(N_terms)
  N = N_terms(idx);
  y = zeros(1, length(x));
  for k = 1:2:N       % odd harmonics only
    y = y + (4/(pi*k)) * sin(k*x);
  endfor
  subplot(length(N_terms), 1, idx);
  plot(x, y); ylim([-1.5, 1.5]);
  title(sprintf('Square wave: %d terms', ceil(N/2)));
endfor

% ──── FFT Analysis ────────────────────────────────────────────────
Fs = 1000;                 % sampling frequency
T  = 1/Fs;                 % sample period
L  = 1000;                % signal length
t  = (0:L-1)*T;

% Signal = 50 Hz + 120 Hz components
S = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t);

Y  = fft(S);              % Octave FFT
P2 = abs(Y/L);
P1 = P2(1:L/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f  = Fs*(0:L/2)/L;

figure('Name', 'FFT');
subplot(2,1,1); plot(t(1:200), S(1:200));
title('Signal: 50 Hz + 120 Hz'); xlabel('t (s)'); grid on;
subplot(2,1,2); plot(f, P1);
title('Single-Sided Spectrum'); xlabel('f (Hz)'); ylabel('|P1(f)|'); grid on;

% ──── Discrete Cosine Transform (DCT) — basis of JPEG ────────────
N = 8;
function C = dct_matrix(N)
  C = zeros(N, N);
  for k = 0:N-1
    for n = 0:N-1
      if k == 0
        C(k+1,n+1) = 1/sqrt(N);
      else
        C(k+1,n+1) = sqrt(2/N) * cos(pi*k*(2*n+1)/(2*N));
      endif
    endfor
  endfor
endfunction

D = dct_matrix(8);
x_block = [52 55 61 66 70 61 64 73]; % 8-pixel block
X_dct   = D * x_block';
printf("DCT of 8-pixel block:\n"); disp(X_dct');

§10 Trigonometry in Cryptography

The connections between trigonometry and modern cryptography run deep — from the fundamental mathematics of modular arithmetic (which mirrors the periodic nature of trig functions) to stream ciphers, hash functions, and elliptic curve cryptography.

10.1 Periodicity as the Foundation of Security

The security of many cryptosystems rests on one-way functions that are easy to compute but hard to invert — exactly the same asymmetry seen in trigonometric identities. Just as you cannot easily recover θ from sin(θ) alone (because sine is many-to-one), discrete-log and factoring problems give attackers no easy inverse path.

sin(θ) = sin(π − θ) — many-to-one (periodic)
g^x mod p = g^(x + φ(p)) mod p — DLP periodicity

10.2 Linear Congruential Generator (LCG)

Historically important pseudo-random number generator; shares periodicity with trig. LCGs underpin older stream ciphers and OTP generation.

X_{n+1} = (a · X_n + c) mod m
GNU Octave
% ──── Linear Congruential Generator ─────────────────────────────
function seq = lcg(seed, a, c, m, N)
  seq = zeros(1, N);
  x   = seed;
  for i = 1:N
    x      = mod(a*x + c, m);
    seq(i) = x;
  endfor
endfunction

% Numerical Recipes parameters (32-bit)
a = 1664525; c = 1013904223; m = 2^32;
seq = lcg(42, a, c, m, 20);
normalised = seq / m;       % uniform [0,1)
printf("LCG sequence (first 5, normalised): ");
disp(normalised(1:5));

10.3 Trig in Stream Ciphers — XOR with Sinusoidal Mask

A simplified (educational) stream cipher uses a sinusoid to generate a pseudo-random keystream. Real stream ciphers (ChaCha20, Salsa20) use modular arithmetic, but the intuition of cyclically mixing data with a key is the same.

GNU Octave
% ──── Sinusoidal XOR Stream Cipher (educational demo) ────────────
% NOTE: This is NOT a secure cipher — for illustration only!

function cipher_text = sin_xor_encrypt(plaintext_bytes, key_freq, key_phase)
  n           = length(plaintext_bytes);
  t           = (0:n-1);
  keystream    = uint8(mod(floor(128 * (1 + sin(key_freq*t + key_phase))), 256));
  cipher_text  = bitxor(plaintext_bytes, keystream);
endfunction

msg     = uint8('Hello, Trig!');
freq    = 0.37;    % key frequency
phase   = 1.23;    % key phase

ciphertext  = sin_xor_encrypt(msg, freq, phase);
decrypted   = sin_xor_encrypt(ciphertext, freq, phase);  % XOR is its own inverse

printf("Original  : %s\n", char(msg));
printf("Encrypted : "); disp(ciphertext);
printf("Decrypted : %s\n", char(decrypted));
assert(all(decrypted == msg));
disp("Decryption verified!");

10.4 Diffie-Hellman Key Exchange (Modular Analogue)

DH is the "modular trigonometry" of cryptography. The discrete logarithm mirrors the many-to-one property of trig: g^a mod p is easy to compute, hard to invert (for large p).

DH Protocol

  1. Alice & Bob agree on public prime p and generator g
  2. Alice picks secret a, sends A = g^a mod p
  3. Bob picks secret b, sends B = g^b mod p
  4. Shared secret: K = B^a mod p = A^b mod p = g^(ab) mod p
GNU Octave
% ──── Diffie-Hellman Key Exchange Simulation ─────────────────────
function result = powmod(base, exp_val, modulus)
  % Modular exponentiation: base^exp_val mod modulus
  result = 1;
  base   = mod(base, modulus);
  while exp_val > 0
    if mod(exp_val, 2) == 1
      result = mod(result * base, modulus);
    endif
    exp_val = floor(exp_val / 2);
    base    = mod(base * base, modulus);
  endwhile
endfunction

% Public parameters
p = 23;   % prime modulus (small for demo; real DH uses 2048+ bit primes)
g = 5;    % generator (primitive root mod p)

% Alice's secret key
a = 6;
A = powmod(g, a, p);   % g^a mod p  (Alice sends this publicly)

% Bob's secret key
b = 15;
B = powmod(g, b, p);   % g^b mod p  (Bob sends this publicly)

% Compute shared secret
K_alice = powmod(B, a, p);   % B^a mod p
K_bob   = powmod(A, b, p);   % A^b mod p

printf("p=%d, g=%d\n", p, g);
printf("Alice: secret a=%d, public A=%d\n", a, A);
printf("Bob  : secret b=%d, public B=%d\n", b, B);
printf("Shared secret: Alice=%d, Bob=%d\n", K_alice, K_bob);
assert(K_alice, K_bob);
disp("Shared secrets match!");

10.5 RSA — Euler's Totient & Modular Inverses

RSA relies on Euler's theorem: a^φ(n) ≡ 1 (mod n) for gcd(a,n)=1. This cyclic return to 1 is the multiplicative analogue of cos(2π) = 1 — a full cycle. The period of the function x ↦ g^x mod n is φ(n), directly analogous to the period of a sinusoid.

GNU Octave
% ──── RSA Encryption / Decryption (educational toy key sizes) ────
function result = powmod(base, exp_val, modulus)
  result = 1; base = mod(base, modulus);
  while exp_val > 0
    if mod(exp_val,2)==1; result=mod(result*base,modulus); endif
    exp_val=floor(exp_val/2); base=mod(base*base,modulus);
  endwhile
endfunction

function inv = modinv(a, m)
  % Extended Euclidean algorithm
  [g, x, ~] = gcd(a, m);
  if g != 1; error('No inverse'); endif
  inv = mod(x, m);
endfunction

% Key generation
p = 61;  q = 53;     % small primes — use 1024+ bit primes in real RSA
n = p * q;                % n = 3233
phi_n = (p-1) * (q-1);  % Euler's totient = 3120
e = 17;                   % public exponent, gcd(e,φ(n)) must be 1
d = modinv(e, phi_n);     % private exponent

printf("RSA Keys:\n  n=%d  φ(n)=%d  e=%d  d=%d\n", n, phi_n, e, d);

% Encrypt / Decrypt a single character
M = 65;                   % 'A' in ASCII
C = powmod(M, e, n);      % ciphertext: M^e mod n
R = powmod(C, d, n);      % recovered:  C^d mod n

printf("Plaintext M=%d  Ciphertext C=%d  Recovered=%d\n", M, C, R);
assert(R, M);
disp("RSA encrypt/decrypt verified!");

% Verify Euler's theorem: M^φ(n) ≡ 1 (mod n) when gcd(M,n)=1
assert(powmod(M, phi_n, n), 1);
disp("Euler's theorem verified: M^φ(n) ≡ 1 (mod n)");

10.6 Elliptic Curve Cryptography (ECC) & Trig

Elliptic curves over finite fields are described by equations of the form y² = x³ + ax + b. The parametric curves traced are closely related to trigonometric and hyperbolic functions through the Weierstrass ℘-function.

The "point addition" operation on an elliptic curve is a group operation with a structure analogous to angle addition in the unit circle. ECDSA (used in Bitcoin, TLS 1.3, SSH) exploits this structure.

GNU Octave
% ──── Elliptic Curve Point Addition (over ℝ, for visualisation) ──
function [x3, y3] = ec_add(x1, y1, x2, y2, a)
  % Add two points on y² = x³ + ax + b
  if x1 == x2
    m = (3*x1^2 + a) / (2*y1);   % tangent (point doubling)
  else
    m = (y2 - y1) / (x2 - x1);    % secant slope
  endif
  x3 = m^2 - x1 - x2;
  y3 = m*(x1 - x3) - y1;
endfunction

% Curve: y² = x³ − x (a=−1, b=0)
a = -1;  b = 0;
x_curve = linspace(-1.5, 2, 500);
figure('Name', 'Elliptic Curve');
y_sq = x_curve.^3 + a*x_curve + b;
y_pos = sqrt(max(y_sq, 0));
plot(x_curve, y_pos, 'b-', x_curve, -y_pos, 'b-');
hold on;

% Two points on the curve
x1 = -0.5; y1 = sqrt(x1^3 + a*x1 + b);
x2 = 1.5;  y2 = sqrt(x2^3 + a*x2 + b);
[x3, y3] = ec_add(x1, y1, x2, y2, a);

plot([x1 x2 x3], [y1 y2 -y3], 'ro', 'MarkerSize', 8, 'MarkerFaceColor', 'r');
plot([x1 x3], [y1 y2], 'g--');
title('Elliptic Curve y²=x³−x: Point Addition');
grid on; axis([-1.8 2.2 -3 3]); hold off;

10.7 Trigonometric Hash Functions & CORDIC

CORDIC (COordinate Rotation DIgital Computer) is an algorithm that computes sine, cosine, arctan, and hyperbolic functions using only integer addition and bit shifts — no multiplication required. It is the backbone of hardware FPU implementations and embedded systems.

CORDIC rotation: xᵢ₊₁ = xᵢ − dᵢ·yᵢ·2^{−i},   yᵢ₊₁ = yᵢ + dᵢ·xᵢ·2^{−i}

where dᵢ ∈ {−1, +1} is chosen to rotate towards the target angle.

GNU Octave
% ──── CORDIC Algorithm for sin/cos ───────────────────────────────
function [s, c] = cordic(angle_rad, iterations)
  % Precompute arctangent table
  atan_table = atan(2.^(-(0:iterations-1)));

  % CORDIC gain factor
  K = prod(cos(atan_table));

  x = 1; y = 0; z = angle_rad;

  for i = 0:iterations-1
    d = 1;
    if z < 0; d = -1; endif
    x_new = x - d * y * 2^(-i);
    y_new = y + d * x * 2^(-i);
    z_new = z - d * atan_table(i+1);
    x = x_new; y = y_new; z = z_new;
  endfor

  c = K * x;   % cosine
  s = K * y;   % sine
endfunction

angles = [0, pi/6, pi/4, pi/3, pi/2];
printf("\nCORDIC vs Built-in (16 iterations):\n");
printf("%-10s %-12s %-12s %-12s %-12s\n", "Angle", "CORDIC sin", "Exact sin", "CORDIC cos", "Exact cos");
for a = angles
  [s, c] = cordic(a, 16);
  printf("%-10.4f %-12.8f %-12.8f %-12.8f %-12.8f\n", a, s, sin(a), c, cos(a));
endfor

§11 GNU Octave Laboratory

This section collects comprehensive Octave examples that tie together multiple trigonometric concepts into practical, runnable programs.

Lab 1 — Complete Trig Toolkit

GNU Octave
% ──── trig_toolkit.m — all six functions + inverse + checks ──────
function trig_report(theta_deg)
  t  = deg2rad(theta_deg);
  printf("─────────────────────────────────────────────\n");
  printf("θ = %g° = %.6f rad\n", theta_deg, t);
  printf("sin   = %+.8f\n", sin(t));
  printf("cos   = %+.8f\n", cos(t));
  if abs(cos(t)) > 1e-10
    printf("tan   = %+.8f\n", tan(t));
    printf("sec   = %+.8f\n", 1/cos(t));
  else
    printf("tan   = undefined\n");
    printf("sec   = undefined\n");
  endif
  if abs(sin(t)) > 1e-10
    printf("csc   = %+.8f\n", 1/sin(t));
    printf("cot   = %+.8f\n", cos(t)/sin(t));
  else
    printf("csc   = undefined\n");
    printf("cot   = undefined\n");
  endif
  printf("sin²+cos² = %.15f\n", sin(t)^2+cos(t)^2);
  printf("Quadrant  = %d\n", ceil(mod(theta_deg,360)/90 + 1e-9));
endfunction

trig_report(30);
trig_report(135);
trig_report(210);
trig_report(315);

Lab 2 — Navigation & Bearing Calculator

GNU Octave
% ──── Haversine Formula: great-circle distance on a sphere ───────
function d = haversine(lat1, lon1, lat2, lon2)
  % Inputs in degrees; output in km
  R  = 6371;            % Earth radius km
  phi1 = deg2rad(lat1); phi2 = deg2rad(lat2);
  dphi = deg2rad(lat2 - lat1);
  dlam = deg2rad(lon2 - lon1);
  a = sin(dphi/2)^2 + cos(phi1)*cos(phi2)*sin(dlam/2)^2;
  c = 2 * atan2(sqrt(a), sqrt(1-a));
  d = R * c;
endfunction

% New York (40.71°N, 74.01°W) to London (51.51°N, 0.13°W)
d = haversine(40.71, -74.01, 51.51, -0.13);
printf("NYC → London: %.1f km\n", d);   % ~5570 km

% ──── Bearing between two coordinates ────────────────────────────
function bearing = initial_bearing(lat1, lon1, lat2, lon2)
  phi1 = deg2rad(lat1); phi2 = deg2rad(lat2);
  dlam = deg2rad(lon2 - lon1);
  y    = sin(dlam) * cos(phi2);
  x    = cos(phi1)*sin(phi2) - sin(phi1)*cos(phi2)*cos(dlam);
  bearing = mod(rad2deg(atan2(y, x)), 360);
endfunction

b = initial_bearing(40.71, -74.01, 51.51, -0.13);
printf("NYC → London bearing: %.2f°\n", b);   % ~51°

Lab 3 — Lissajous Figures

GNU Octave
% ──── Lissajous Figures: parametric x=sin(at+δ), y=sin(bt) ──────
t = linspace(0, 2*pi, 5000);
params = [1,1; 1,2; 1,3; 2,3; 3,4; 3,5];
delta = pi/4;
figure('Name', 'Lissajous Figures');
for i = 1:6
  a = params(i,1); b = params(i,2);
  x = sin(a*t + delta);
  y = sin(b*t);
  subplot(2,3,i);
  plot(x, y, 'b-', 'LineWidth', 0.8);
  axis equal; axis([-1.2 1.2 -1.2 1.2]);
  title(sprintf('a=%d, b=%d', a, b));
  grid on;
endfor

Lab 4 — 3D Parametric Surfaces

GNU Octave
% ──── Torus: parametric surface using trig ────────────────────────
R = 3;  r = 1;      % major and minor radii
u = linspace(0, 2*pi, 80);
v = linspace(0, 2*pi, 80);
[U, V] = meshgrid(u, v);

X = (R + r*cos(V)) .* cos(U);
Y = (R + r*cos(V)) .* sin(U);
Z = r * sin(V);

figure('Name', 'Torus');
surf(X, Y, Z, 'EdgeAlpha', 0.1); colormap hsv;
title('Torus: R=3, r=1'); axis equal; shading interp;

% ──── Sphere ─────────────────────────────────────────────────────
theta_s = linspace(-pi/2, pi/2, 60);
phi_s   = linspace(-pi, pi, 60);
[TH, PH] = meshgrid(theta_s, phi_s);
Xs = cos(TH) .* cos(PH);
Ys = cos(TH) .* sin(PH);
Zs = sin(TH);
figure('Name', 'Sphere');
surf(Xs, Ys, Zs); axis equal; title('Unit Sphere'); shading interp;

Lab 5 — Solving Trig Equations

GNU Octave
% ──── Numerical solution of trig equations ───────────────────────
% Solve: sin(x) = 0.6  in [0, 2π]
val = 0.6;
x1  = asin(val);                 % principal solution in [−π/2, π/2]
x2  = pi - x1;                   % second solution in [0, 2π]
printf("sin(x)=0.6  →  x = %.4f° or %.4f°\n", rad2deg(x1), rad2deg(x2));

% Solve: 2cos²(x) − cos(x) − 1 = 0  (substitution u=cos x)
% → (2u+1)(u−1) = 0  → u = −½ or u = 1
sol1_deg = rad2deg(acos(-0.5));  % 120°
sol2_deg = rad2deg(acos(1));      %   0°
printf("2cos²x−cosx−1=0 →  x = %.1f°, %.1f° (and coterminals)\n", sol1_deg, sol2_deg);

% ──── Plot to verify ─────────────────────────────────────────────
x = linspace(0, 2*pi, 1000);
y = 2*cos(x).^2 - cos(x) - 1;
figure('Name', 'Trig Equation');
plot(x, y, 'b-', 'LineWidth', 2);
hold on; yline(0, 'r--');
title('2cos²x − cos x − 1 = 0'); xlabel('x (rad)'); grid on; hold off;

Lab 6 — Phase-Locked Loop (PLL) Simulation

GNU Octave
% ──── Simplified PLL: sin × sin product as phase detector ────────
% PD output: sin(θ_ref) × sin(θ_vco) = ½[cos(θ_ref−θ_vco) − cos(θ_ref+θ_vco)]
% Lowpass filter removes the sum term; ½cos(Δθ) drives VCO correction
Fs      = 1e5;
t       = 0:1/Fs:0.01;
f_ref   = 1000;
f_vco   = 1020;    % slight offset
ref_sig = sin(2*pi*f_ref*t);
vco_sig = sin(2*pi*f_vco*t);
pd_out  = ref_sig .* vco_sig;   % phase detector

% Simple moving-average LPF (approximate)
win = round(Fs / f_ref / 4);
lp  = conv(pd_out, ones(1,win)/win, 'same');

figure('Name', 'PLL Demo');
subplot(3,1,1); plot(t(1:500), ref_sig(1:500)); title('Reference 1kHz'); grid on;
subplot(3,1,2); plot(t(1:500), vco_sig(1:500)); title('VCO 1020Hz'); grid on;
subplot(3,1,3); plot(t, lp); title('Phase Detector LPF Output (∝ cos Δθ)'); grid on;

Lab 7 — Spherical Trigonometry

GNU Octave
% ──── Spherical Law of Cosines ────────────────────────────────────
% For a spherical triangle with sides a,b,c (arcs) and angles A,B,C:
% cos(c) = cos(a)cos(b) + sin(a)sin(b)cos(C)
function c = spherical_law_of_cosines(a_deg, b_deg, C_deg)
  a = deg2rad(a_deg); b = deg2rad(b_deg); C = deg2rad(C_deg);
  c = acos(cos(a)*cos(b) + sin(a)*sin(b)*cos(C));
  c = rad2deg(c);
endfunction

% Triangle on Earth's surface:
% Pole → Equator/0° → Equator/90°E
c_arc = spherical_law_of_cosines(90, 90, 90);
printf("Spherical LOC: third arc = %.4f°\n", c_arc); % should be 90°

% ──── Solar Altitude Angle ────────────────────────────────────────
function alt = solar_altitude(lat_deg, decl_deg, hour_angle_deg)
  lat    = deg2rad(lat_deg);
  decl   = deg2rad(decl_deg);
  ha     = deg2rad(hour_angle_deg);
  sin_alt = sin(lat)*sin(decl) + cos(lat)*cos(decl)*cos(ha);
  alt     = rad2deg(asin(sin_alt));
endfunction

% Solar altitude at noon (hour_angle=0) at latitude 40°N on summer solstice (decl=23.5°)
alt_noon = solar_altitude(40, 23.5, 0);
printf("Solar altitude at noon (lat=40°N, summer solstice): %.2f°\n", alt_noon);
QUICK REFERENCE

REF Essential Formulae Card

Pythagorean Identities

sin²θ + cos²θ = 1
1 + tan²θ = sec²θ
1 + cot²θ = csc²θ

Sum Formulae

sin(A±B) = sinA cosB ± cosA sinB
cos(A±B) = cosA cosB ∓ sinA sinB

Double Angle

sin 2θ = 2 sinθ cosθ
cos 2θ = cos²θ − sin²θ
tan 2θ = 2tanθ/(1−tan²θ)

Laws of Triangles

sin: a/sinA = b/sinB = c/sinC
cos: c² = a²+b² − 2ab cosC

Euler & Complex

e^(iθ) = cosθ + i sinθ
e^(iπ) + 1 = 0
(cosθ+i sinθ)ⁿ = cos(nθ)+i sin(nθ)

Area Formulae

K = ½ a b sinC
K = √(s(s−a)(s−b)(s−c))

Inverse Ranges

arcsin: [−π/2, π/2]
arccos: [0, π]
arctan: (−π/2, π/2)

Polar Coords

x = r cosθ, y = r sinθ
r = √(x²+y²), θ = atan2(y,x)