From 3a502be2c5cdb37b59f786c46df2bf37a3c8dbf9 Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Tue, 11 Nov 2025 21:05:36 +0700 Subject: [PATCH 1/6] docs: arithmethic update. --- docs/api/operation/arithmetic.md | 1107 +++++++++++++++++++++++++++--- 1 file changed, 1024 insertions(+), 83 deletions(-) diff --git a/docs/api/operation/arithmetic.md b/docs/api/operation/arithmetic.md index b467308..d7d4b57 100644 --- a/docs/api/operation/arithmetic.md +++ b/docs/api/operation/arithmetic.md @@ -6,72 +6,852 @@ The arithmetic chapter is the first chapter from the `operation` category. It pr #include ``` -## Features - -### Basic Operations -- `add(double a, double b) → double` - Standard addition -- `subtract(double a, double b) → double` - Standard subtraction -- `multiply(double a, double b) → double` - Standard multiplication -- `divide(double a, double b) → double` - Standard division - -### Power and Roots -- `power(double base, int exponent) → double` - Raises base to an integer exponent -- `squareRoot(double n) → double` - Computes √n -- `cubeRoot(double n) → double` - Computes ∛n - -### Absolute Value and Sign -- `absolute(double n) → double` - Returns |n| -- `sign(double n) → int` - Returns -1 for negative, 0 for zero, 1 for positive - -### Remainders and Divisibility -- `remainder(int a, int b) → int` - Integer remainder of a ÷ b -- `isDivisible(int a, int b) → bool` - Checks if a is divisible by b - -### Percentages -- `percentOf(double percent, double total) → double` - Calculates percent% of total -- `whatPercent(double part, double total) → double` - Finds what percent part is of total -- `percentIncrease(double original, double newValue) → double` - Calculates percentage increase -- `percentDecrease(double original, double newValue) → double` - Calculates percentage decrease - -### Averages and Statistics -- `average(const std::vector& numbers) → double` - Mean of a vector of numbers -- `sum(const std::vector& numbers) → double` - Total sum -- `minimum(const std::vector& numbers) → double` - Minimum value -- `maximum(const std::vector& numbers) → double` - Maximum value -- `range(const std::vector& numbers) → double` - Difference between max and min -- `median(std::vector numbers) → double` - Middle value (sorts the data) - -### Fractions -- `addFractions(double num1, double den1, double num2, double den2) → double` - Adds two fractions -- `subtractFractions(double num1, double den1, double num2, double den2) → double` - Subtracts fractions -- `multiplyFractions(double num1, double den1, double num2, double den2) → double` - Multiplies fractions -- `divideFractions(double num1, double den1, double num2, double den2) → double` - Divides fractions - -### Rounding -- `roundToNearest(double n) → double` - Rounds to nearest integer -- `roundUp(double n) → double` - Ceiling function -- `roundDown(double n) → double` - Floor function -- `roundToDecimalPlaces(double n, int places) → double` - Rounds to specified decimal places - -### Number Properties -- `isEven(int n) → bool` - Checks if even -- `isOdd(int n) → bool` - Checks if odd -- `isPrime(int n) → bool` - Tests for primality -- `greatestCommonDivisor(int a, int b) → int` - GCD of two integers -- `leastCommonMultiple(int a, int b) → int` - LCM of two integers - -### Geometry -- `distance2D(double x1, double y1, double x2, double y2) → double` - Euclidean distance between two points -- `pythagorean(double a, double b) → double` - Calculates hypotenuse using Pythagorean theorem - -### Conversions -- `celsiusToFahrenheit(double celsius) → double` - Temperature conversion C → F -- `fahrenheitToCelsius(double fahrenheit) → double` - Temperature conversion F → C - -### Finance -- `simpleInterest(double principal, double rate, double time) → double` - Calculates simple interest - -## Example Usage +## Overview + +Arithmetic is the foundation of mathematics. This module helps you answer questions like: +- "What's the average of these test scores?" +- "Is this number prime?" +- "How much is 15% of $200?" +- "What's the distance between two points?" + +--- + +## Basic Operations + +### Addition + +```c++ +double add(double a, double b); +``` + +Standard addition of two numbers. + +**Examples:** +```c++ +add(5.0, 3.0); // 8.0 +add(-10.5, 7.2); // -3.3 +add(100, 250); // 350.0 +``` + +**Real-world:** Calculating totals, summing prices, combining quantities. + +--- + +### Subtraction + +```c++ +double subtract(double a, double b); +``` + +Standard subtraction - computes a - b. + +**Examples:** +```c++ +subtract(10.0, 3.0); // 7.0 +subtract(5.5, 8.2); // -2.7 +subtract(100, 45); // 55.0 +``` + +**Real-world:** Finding differences, calculating change, determining deficits. + +--- + +### Multiplication + +```c++ +double multiply(double a, double b); +``` + +Standard multiplication of two numbers. + +**Examples:** +```c++ +multiply(5.0, 3.0); // 15.0 +multiply(-4.0, 2.5); // -10.0 +multiply(12, 0.5); // 6.0 +``` + +**Real-world:** Scaling quantities, calculating areas, price × quantity. + +--- + +### Division + +```c++ +double divide(double a, double b); +``` + +Standard division - computes a ÷ b. + +**Examples:** +```c++ +divide(10.0, 2.0); // 5.0 +divide(7.0, 2.0); // 3.5 +divide(100, 3); // 33.333... +``` + +**Real-world:** Splitting bills, calculating rates, finding averages. + +**Note:** Division by zero will cause an error. + +--- + +## Power and Roots + +### Power + +```c++ +double power(double base, int exponent); +``` + +Raises base to an integer exponent. + +**Examples:** +```c++ +power(2, 3); // 8.0 (2³) +power(5, 2); // 25.0 (5²) +power(10, 0); // 1.0 (anything⁰ = 1) +power(2, -2); // 0.25 (2⁻² = 1/4) +``` + +**Real-world:** Compound interest, exponential growth, area/volume calculations. + +--- + +### Square Root + +```c++ +double squareRoot(double n); +``` + +Computes the square root (√n). + +**Examples:** +```c++ +squareRoot(9); // 3.0 +squareRoot(25); // 5.0 +squareRoot(2); // 1.414... +squareRoot(100); // 10.0 +``` + +**Real-world:** Pythagorean theorem, standard deviation, geometric calculations. + +--- + +### Cube Root + +```c++ +double cubeRoot(double n); +``` + +Computes the cube root (∛n). + +**Examples:** +```c++ +cubeRoot(8); // 2.0 +cubeRoot(27); // 3.0 +cubeRoot(-8); // -2.0 (cube root of negative is negative) +cubeRoot(1000); // 10.0 +``` + +**Real-world:** Volume calculations, finding side length from volume. + +--- + +## Absolute Value and Sign + +### Absolute Value + +```c++ +double absolute(double n); +``` + +Returns the absolute value |n| (always positive or zero). + +**Examples:** +```c++ +absolute(5.0); // 5.0 +absolute(-5.0); // 5.0 +absolute(0); // 0.0 +absolute(-3.14); // 3.14 +``` + +**Real-world:** Distance calculations, magnitude, error measurements. + +--- + +### Sign + +```c++ +int sign(double n); +``` + +Returns the sign of a number: +- Returns -1 for negative numbers +- Returns 0 for zero +- Returns 1 for positive numbers + +**Examples:** +```c++ +sign(42.5); // 1 +sign(-17.3); // -1 +sign(0.0); // 0 +sign(-0.001); // -1 +``` + +**Real-world:** Direction indicators, profit/loss status, trend analysis. + +--- + +## Remainders and Divisibility + +### Remainder + +```c++ +int remainder(int a, int b); +``` + +Integer remainder of a ÷ b (modulo operation). + +**Examples:** +```c++ +remainder(10, 3); // 1 (10 = 3×3 + 1) +remainder(17, 5); // 2 (17 = 5×3 + 2) +remainder(20, 4); // 0 (evenly divisible) +remainder(7, 10); // 7 (dividend smaller than divisor) +``` + +**Real-world:** Clock arithmetic, cyclic patterns, checking divisibility. + +--- + +### Is Divisible + +```c++ +bool isDivisible(int a, int b); +``` + +Checks if a is evenly divisible by b (remainder is 0). + +**Examples:** +```c++ +isDivisible(10, 2); // true +isDivisible(15, 3); // true +isDivisible(17, 5); // false +isDivisible(100, 25); // true +``` + +**Real-world:** Checking if items can be evenly distributed, validating constraints. + +--- + +## Percentages + +### Percent Of + +```c++ +double percentOf(double percent, double total); +``` + +Calculates what percent% of total equals. + +**Formula:** result = (percent / 100) × total + +**Examples:** +```c++ +percentOf(20, 100); // 20.0 (20% of 100) +percentOf(15, 200); // 30.0 (15% of 200) +percentOf(50, 80); // 40.0 (50% of 80) +percentOf(8.5, 150); // 12.75 (8.5% of 150) +``` + +**Real-world:** Calculating tips, discounts, tax amounts, commissions. + +--- + +### What Percent + +```c++ +double whatPercent(double part, double total); +``` + +Finds what percent the part is of the total. + +**Formula:** result = (part / total) × 100 + +**Examples:** +```c++ +whatPercent(25, 100); // 25.0 (25 is 25% of 100) +whatPercent(30, 150); // 20.0 (30 is 20% of 150) +whatPercent(45, 90); // 50.0 (45 is 50% of 90) +whatPercent(7, 35); // 20.0 (7 is 20% of 35) +``` + +**Real-world:** Grade percentages, completion rates, market share analysis. + +--- + +### Percent Increase + +```c++ +double percentIncrease(double original, double newValue); +``` + +Calculates the percentage increase from original to newValue. + +**Formula:** ((newValue - original) / original) × 100 + +**Examples:** +```c++ +percentIncrease(50, 75); // 50.0 (increased by 50%) +percentIncrease(100, 150); // 50.0 (increased by 50%) +percentIncrease(80, 100); // 25.0 (increased by 25%) +percentIncrease(200, 250); // 25.0 (increased by 25%) +``` + +**Real-world:** Price increases, population growth, salary raises, profit margins. + +--- + +### Percent Decrease + +```c++ +double percentDecrease(double original, double newValue); +``` + +Calculates the percentage decrease from original to newValue. + +**Formula:** ((original - newValue) / original) × 100 + +**Examples:** +```c++ +percentDecrease(100, 75); // 25.0 (decreased by 25%) +percentDecrease(200, 150); // 25.0 (decreased by 25%) +percentDecrease(80, 60); // 25.0 (decreased by 25%) +percentDecrease(50, 25); // 50.0 (decreased by 50%) +``` + +**Real-world:** Discounts, price reductions, depreciation, weight loss tracking. + +--- + +## Averages and Statistics + +### Average (Mean) + +```c++ +double average(const std::vector& numbers); +``` + +Calculates the arithmetic mean (average) of a set of numbers. + +**Formula:** sum of all numbers ÷ count of numbers + +**Examples:** +```c++ +std::vector grades = {85, 90, 78, 92, 88}; +average(grades); // 86.6 + +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +average(temps); // 71.875 +``` + +**Real-world:** Grade point average, average temperature, mean income. + +--- + +### Sum + +```c++ +double sum(const std::vector& numbers); +``` + +Calculates the total sum of all numbers in the vector. + +**Examples:** +```c++ +std::vector prices = {10.5, 25.0, 8.75, 15.25}; +sum(prices); // 59.5 + +std::vector scores = {100, 85, 90, 95}; +sum(scores); // 370.0 +``` + +**Real-world:** Total sales, combined scores, aggregate values. + +--- + +### Minimum + +```c++ +double minimum(const std::vector& numbers); +``` + +Finds the smallest value in the vector. + +**Examples:** +```c++ +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +minimum(temps); // 68.0 + +std::vector prices = {19.99, 15.50, 22.00, 12.99}; +minimum(prices); // 12.99 +``` + +**Real-world:** Lowest price, minimum temperature, worst score. + +--- + +### Maximum + +```c++ +double maximum(const std::vector& numbers); +``` + +Finds the largest value in the vector. + +**Examples:** +```c++ +std::vector temps = {72.5, 68.0, 75.2, 71.8}; +maximum(temps); // 75.2 + +std::vector scores = {85, 92, 78, 95, 88}; +maximum(scores); // 95.0 +``` + +**Real-world:** Highest score, peak temperature, maximum capacity. + +--- + +### Range + +```c++ +double range(const std::vector& numbers); +``` + +Calculates the difference between the maximum and minimum values. + +**Formula:** max - min + +**Examples:** +```c++ +std::vector temps = {68.0, 72.5, 75.2, 71.8}; +range(temps); // 7.2 (75.2 - 68.0) + +std::vector ages = {25, 35, 42, 28, 31}; +range(ages); // 17.0 (42 - 25) +``` + +**Real-world:** Temperature variation, price spread, age distribution. + +--- + +### Median + +```c++ +double median(std::vector numbers); +``` + +Finds the middle value when numbers are sorted. If there's an even count, returns the average of the two middle values. + +**Note:** This function sorts the input vector. + +**Examples:** +```c++ +std::vector odd = {3, 1, 4, 1, 5}; +median(odd); // 3.0 (middle of 1,1,3,4,5) + +std::vector even = {10, 20, 30, 40}; +median(even); // 25.0 (average of 20 and 30) +``` + +**Real-world:** Median income (resistant to outliers), middle test score. + +--- + +## Fractions + +### Add Fractions + +```c++ +double addFractions(double num1, double den1, double num2, double den2); +``` + +Adds two fractions: (num1/den1) + (num2/den2). + +**Examples:** +```c++ +addFractions(1, 2, 1, 3); // 0.8333... (1/2 + 1/3 = 5/6) +addFractions(2, 5, 3, 10); // 0.7 (2/5 + 3/10 = 7/10) +addFractions(1, 4, 1, 4); // 0.5 (1/4 + 1/4 = 1/2) +``` + +**Real-world:** Recipe measurements, combining partial amounts. + +--- + +### Subtract Fractions + +```c++ +double subtractFractions(double num1, double den1, double num2, double den2); +``` + +Subtracts two fractions: (num1/den1) - (num2/den2). + +**Examples:** +```c++ +subtractFractions(3, 4, 1, 2); // 0.25 (3/4 - 1/2 = 1/4) +subtractFractions(5, 6, 1, 3); // 0.5 (5/6 - 1/3 = 1/2) +``` + +**Real-world:** Measuring remaining quantities, calculating differences. + +--- + +### Multiply Fractions + +```c++ +double multiplyFractions(double num1, double den1, double num2, double den2); +``` + +Multiplies two fractions: (num1/den1) × (num2/den2). + +**Examples:** +```c++ +multiplyFractions(2, 3, 3, 4); // 0.5 (2/3 × 3/4 = 1/2) +multiplyFractions(1, 2, 1, 2); // 0.25 (1/2 × 1/2 = 1/4) +``` + +**Real-world:** Scaling recipes, calculating portions. + +--- + +### Divide Fractions + +```c++ +double divideFractions(double num1, double den1, double num2, double den2); +``` + +Divides two fractions: (num1/den1) ÷ (num2/den2). + +**Examples:** +```c++ +divideFractions(1, 2, 1, 4); // 2.0 (1/2 ÷ 1/4 = 2) +divideFractions(3, 4, 3, 8); // 2.0 (3/4 ÷ 3/8 = 2) +``` + +**Real-world:** Dividing quantities, portion distribution. + +--- + +## Rounding + +### Round to Nearest + +```c++ +double roundToNearest(double n); +``` + +Rounds to the nearest integer. Values at .5 round up. + +**Examples:** +```c++ +roundToNearest(3.2); // 3.0 +roundToNearest(3.7); // 4.0 +roundToNearest(3.5); // 4.0 +roundToNearest(-2.5); // -2.0 or -3.0 (implementation dependent) +``` + +**Real-world:** Rounding prices, counting items, simplifying measurements. + +--- + +### Round Up (Ceiling) + +```c++ +double roundUp(double n); +``` + +Rounds up to the next integer (ceiling function). + +**Examples:** +```c++ +roundUp(3.1); // 4.0 +roundUp(3.9); // 4.0 +roundUp(3.0); // 3.0 +roundUp(-2.1); // -2.0 +``` + +**Real-world:** Calculating packages needed, minimum capacity, buffer allocation. + +--- + +### Round Down (Floor) + +```c++ +double roundDown(double n); +``` + +Rounds down to the previous integer (floor function). + +**Examples:** +```c++ +roundDown(3.1); // 3.0 +roundDown(3.9); // 3.0 +roundDown(3.0); // 3.0 +roundDown(-2.1); // -3.0 +``` + +**Real-world:** Complete sets, whole units available, truncating values. + +--- + +### Round to Decimal Places + +```c++ +double roundToDecimalPlaces(double n, int places); +``` + +Rounds to a specified number of decimal places. + +**Examples:** +```c++ +roundToDecimalPlaces(3.14159, 2); // 3.14 +roundToDecimalPlaces(2.5678, 1); // 2.6 +roundToDecimalPlaces(100.567, 0); // 101.0 +roundToDecimalPlaces(1.2345, 3); // 1.235 +``` + +**Real-world:** Currency (2 decimal places), precision measurements, display formatting. + +--- + +## Number Properties + +### Is Even + +```c++ +bool isEven(int n); +``` + +Checks if a number is even (divisible by 2). + +**Examples:** +```c++ +isEven(4); // true +isEven(7); // false +isEven(0); // true +isEven(-6); // true +``` + +**Real-world:** Pairing items, determining patterns, scheduling rotations. + +--- + +### Is Odd + +```c++ +bool isOdd(int n); +``` + +Checks if a number is odd (not divisible by 2). + +**Examples:** +```c++ +isOdd(5); // true +isOdd(8); // false +isOdd(1); // true +isOdd(-3); // true +``` + +**Real-world:** Alternating patterns, parity checks, game logic. + +--- + +### Is Prime + +```c++ +bool isPrime(int n); +``` + +Tests whether a number is prime (only divisible by 1 and itself). + +**Examples:** +```c++ +isPrime(2); // true (smallest prime) +isPrime(17); // true +isPrime(20); // false (divisible by 2, 4, 5, 10) +isPrime(1); // false (1 is not prime by definition) +isPrime(29); // true +``` + +**Real-world:** Cryptography, hash functions, mathematical research. + +--- + +### Greatest Common Divisor (GCD) + +```c++ +int greatestCommonDivisor(int a, int b); +``` + +Finds the largest number that divides both a and b evenly. + +**Examples:** +```c++ +greatestCommonDivisor(48, 18); // 6 +greatestCommonDivisor(100, 50); // 50 +greatestCommonDivisor(17, 19); // 1 (coprime numbers) +greatestCommonDivisor(24, 36); // 12 +``` + +**Real-world:** Simplifying fractions, tile arrangements, gear ratios. + +--- + +### Least Common Multiple (LCM) + +```c++ +int leastCommonMultiple(int a, int b); +``` + +Finds the smallest positive number that is a multiple of both a and b. + +**Examples:** +```c++ +leastCommonMultiple(4, 6); // 12 +leastCommonMultiple(3, 5); // 15 +leastCommonMultiple(12, 18); // 36 +leastCommonMultiple(7, 14); // 14 +``` + +**Real-world:** Scheduling cycles, pattern repetition, synchronization problems. + +--- + +## Geometry + +### Distance 2D + +```c++ +double distance2D(double x1, double y1, double x2, double y2); +``` + +Calculates the Euclidean distance between two points in 2D space. + +**Formula:** √[(x₂-x₁)² + (y₂-y₁)²] + +**Examples:** +```c++ +distance2D(0, 0, 3, 4); // 5.0 +distance2D(1, 1, 4, 5); // 5.0 +distance2D(-2, -3, 1, 1); // 5.0 +distance2D(0, 0, 1, 1); // 1.414... (√2) +``` + +**Real-world:** GPS distance, game coordinates, mapping applications. + +--- + +### Pythagorean Theorem + +```c++ +double pythagorean(double a, double b); +``` + +Calculates the hypotenuse of a right triangle given the two legs. + +**Formula:** c = √(a² + b²) + +**Examples:** +```c++ +pythagorean(3, 4); // 5.0 (3-4-5 triangle) +pythagorean(5, 12); // 13.0 (5-12-13 triangle) +pythagorean(1, 1); // 1.414... (√2) +pythagorean(6, 8); // 10.0 +``` + +**Real-world:** Construction, navigation, diagonal measurements. + +--- + +## Conversions + +### Celsius to Fahrenheit + +```c++ +double celsiusToFahrenheit(double celsius); +``` + +Converts temperature from Celsius to Fahrenheit. + +**Formula:** F = (C × 9/5) + 32 + +**Examples:** +```c++ +celsiusToFahrenheit(0); // 32.0 (freezing point) +celsiusToFahrenheit(100); // 212.0 (boiling point) +celsiusToFahrenheit(25); // 77.0 (room temperature) +celsiusToFahrenheit(-40); // -40.0 (same in both scales) +``` + +**Real-world:** Weather forecasts, cooking, scientific conversions. + +--- + +### Fahrenheit to Celsius + +```c++ +double fahrenheitToCelsius(double fahrenheit); +``` + +Converts temperature from Fahrenheit to Celsius. + +**Formula:** C = (F - 32) × 5/9 + +**Examples:** +```c++ +fahrenheitToCelsius(32); // 0.0 (freezing point) +fahrenheitToCelsius(212); // 100.0 (boiling point) +fahrenheitToCelsius(77); // 25.0 (room temperature) +fahrenheitToCelsius(98.6); // 37.0 (body temperature) +``` + +**Real-world:** International temperature conversions, scientific calculations. + +--- + +## Finance + +### Simple Interest + +```c++ +double simpleInterest(double principal, double rate, double time); +``` + +Calculates simple interest on a principal amount. + +**Formula:** I = P × r × t + +**Parameters:** +- principal: Initial amount +- rate: Interest rate (as decimal, e.g., 0.05 for 5%) +- time: Time period (usually in years) + +**Examples:** +```c++ +simpleInterest(1000, 0.05, 2); // 100.0 ($1000 at 5% for 2 years) +simpleInterest(5000, 0.03, 1); // 150.0 ($5000 at 3% for 1 year) +simpleInterest(10000, 0.04, 3); // 1200.0 ($10000 at 4% for 3 years) +``` + +**Real-world:** Loan interest, savings accounts, investment returns. + +--- + +## Complete Examples + +### Example 1: Simple Calculator ```c++ #include @@ -109,27 +889,188 @@ int main() { } ``` -## More Examples +--- + +### Example 2: Statistical Analysis + +```c++ +#include +#include +#include + +int main() { + std::vector grades = {85.5, 92.0, 78.5, 95.0, 88.0}; + + std::cout << "Grade Statistics\n"; + std::cout << "================\n"; + std::cout << "Average: " << imeth::Arithmetic::average(grades) << "\n"; + std::cout << "Median: " << imeth::Arithmetic::median(grades) << "\n"; + std::cout << "Minimum: " << imeth::Arithmetic::minimum(grades) << "\n"; + std::cout << "Maximum: " << imeth::Arithmetic::maximum(grades) << "\n"; + std::cout << "Range: " << imeth::Arithmetic::range(grades) << "\n"; + + return 0; +} +``` + +--- + +### Example 3: Number Theory ```c++ -// Statistical calculations -std::vector grades = {85.5, 92.0, 78.5, 95.0, 88.0}; -double avg = imeth::Arithmetic::average(grades); // 87.8 -double med = imeth::Arithmetic::median(grades); // 88.0 -double minGrade = imeth::Arithmetic::minimum(grades); // 78.5 +#include +#include -// Number theory -int gcd = imeth::Arithmetic::greatestCommonDivisor(48, 18); // 6 -bool prime = imeth::Arithmetic::isPrime(17); // true +int main() { + int a = 48, b = 18; -// Percentage calculations -double discount = imeth::Arithmetic::percentOf(20, 100.0); // 20.0 -double increase = imeth::Arithmetic::percentIncrease(50, 75); // 50.0 + std::cout << "Number Theory for " << a << " and " << b << "\n"; + std::cout << "GCD: " << imeth::Arithmetic::greatestCommonDivisor(a, b) << "\n"; + std::cout << "LCM: " << imeth::Arithmetic::leastCommonMultiple(a, b) << "\n"; -// Geometry -double dist = imeth::Arithmetic::distance2D(0, 0, 3, 4); // 5.0 -double hyp = imeth::Arithmetic::pythagorean(3, 4); // 5.0 + std::cout << "\nPrime numbers from 1 to 20:\n"; + for (int i = 1; i <= 20; i++) { + if (imeth::Arithmetic::isPrime(i)) { + std::cout << i << " "; + } + } + std::cout << "\n"; -// Temperature conversion -double fahrenheit = imeth::Arithmetic::celsiusToFahrenheit(25); // 77.0 + return 0; +} +``` + +--- + +### Example 4: Percentage Calculations + +```c++ +#include +#include + +int main() { + double originalPrice = 100.0; + double salePrice = 75.0; + + double discount = imeth::Arithmetic::percentOf(20, originalPrice); + double decrease = imeth::Arithmetic::percentDecrease(originalPrice, salePrice); + + std::cout << "Original Price: $" << originalPrice << "\n"; + std::cout << "20% discount: $" << discount << "\n"; + std::cout << "Sale Price: $" << salePrice << "\n"; + std::cout << "Percent saved: " << decrease << "%\n"; + + return 0; +} +``` + +--- + +### Example 5: Geometry Calculations + +```c++ +#include +#include + +int main() { + // Calculate distance between two cities (coordinates) + double city1_x = 0, city1_y = 0; + double city2_x = 3, city2_y = 4; + + double distance = imeth::Arithmetic::distance2D(city1_x, city1_y, + city2_x, city2_y); + + std::cout << "Distance between cities: " << distance << " km\n"; + + // Calculate diagonal of a rectangle + double width = 6, height = 8; + double diagonal = imeth::Arithmetic::pythagorean(width, height); + + std::cout << "Rectangle diagonal: " << diagonal << "\n"; + + return 0; +} +``` + +--- + +### Example 6: Temperature Converter + +```c++ +#include +#include + +int main() { + double celsius = 25.0; + double fahrenheit = imeth::Arithmetic::celsiusToFahrenheit(celsius); + + std::cout << celsius << "°C = " << fahrenheit << "°F\n"; + + // Convert back + double backToCelsius = imeth::Arithmetic::fahrenheitToCelsius(fahrenheit); + std::cout << fahrenheit << "°F = " << backToCelsius << "°C\n"; + + return 0; +} +``` + +--- + +## Tips + +- **Division by Zero**: Always check for zero before dividing +- **Integer vs Double**: Use appropriate types for your calculations +- **Rounding**: Choose the right rounding method for your use case +- **Prime Testing**: Large numbers may take longer to test +- **Floating Point**: Be aware of floating-point precision limitations +- **Vector Operations**: Ensure vectors are not empty before statistical calculations + +--- + +## Quick Reference + +| Operation Type | Function | Use Case | +|---------------|----------|----------| +| Basic math | `add`, `subtract`, `multiply`, `divide` | Calculations | +| Powers | `power`, `squareRoot`, `cubeRoot` | Exponents, roots | +| Statistics | `average`, `median`, `sum` | Data analysis | +| Percentages | `percentOf`, `whatPercent` | Discounts, rates | +| Rounding | `roundToNearest`, `roundUp`, `roundDown` | Display, precision | +| Number theory | `isPrime`, `greatestCommonDivisor` | Math problems | +| Geometry | `distance2D`, `pythagorean` | Coordinates, triangles | +| Temperature | `celsiusToFahrenheit` | Conversions | +| Finance | `simpleInterest` | Loans, investments | + +--- + +## Common Use Cases + +### Shopping Calculations +```c++ +double price = 50.0; +double taxRate = 0.08; // 8% tax +double tax = imeth::Arithmetic::percentOf(taxRate * 100, price); +double total = imeth::Arithmetic::add(price, tax); +``` + +### Grade Calculator +```c++ +std::vector scores = {85, 90, 78, 92}; +double avg = imeth::Arithmetic::average(scores); +double rounded = imeth::Arithmetic::roundToNearest(avg); +``` + +### Distance Calculation +```c++ +double dist = imeth::Arithmetic::distance2D(x1, y1, x2, y2); +double roundedDist = imeth::Arithmetic::roundToDecimalPlaces(dist, 2); +``` + +### Fraction Simplification +```c++ +int num = 48, den = 18; +int gcd = imeth::Arithmetic::greatestCommonDivisor(num, den); +int simplifiedNum = num / gcd; // 8 +int simplifiedDen = den / gcd; // 3 +// Result: 48/18 = 8/3 ``` From c5f649f37f96105c60684ec3a62ee52eaaff4b2b Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Tue, 11 Nov 2025 21:10:56 +0700 Subject: [PATCH 2/6] docs: logarithm update. --- docs/api/operation/arithmetic.md | 70 ---- docs/api/operation/logarithm.md | 683 ++++++++++++++++++++++++++++--- 2 files changed, 618 insertions(+), 135 deletions(-) diff --git a/docs/api/operation/arithmetic.md b/docs/api/operation/arithmetic.md index d7d4b57..9529d59 100644 --- a/docs/api/operation/arithmetic.md +++ b/docs/api/operation/arithmetic.md @@ -773,54 +773,6 @@ pythagorean(6, 8); // 10.0 **Real-world:** Construction, navigation, diagonal measurements. ---- - -## Conversions - -### Celsius to Fahrenheit - -```c++ -double celsiusToFahrenheit(double celsius); -``` - -Converts temperature from Celsius to Fahrenheit. - -**Formula:** F = (C × 9/5) + 32 - -**Examples:** -```c++ -celsiusToFahrenheit(0); // 32.0 (freezing point) -celsiusToFahrenheit(100); // 212.0 (boiling point) -celsiusToFahrenheit(25); // 77.0 (room temperature) -celsiusToFahrenheit(-40); // -40.0 (same in both scales) -``` - -**Real-world:** Weather forecasts, cooking, scientific conversions. - ---- - -### Fahrenheit to Celsius - -```c++ -double fahrenheitToCelsius(double fahrenheit); -``` - -Converts temperature from Fahrenheit to Celsius. - -**Formula:** C = (F - 32) × 5/9 - -**Examples:** -```c++ -fahrenheitToCelsius(32); // 0.0 (freezing point) -fahrenheitToCelsius(212); // 100.0 (boiling point) -fahrenheitToCelsius(77); // 25.0 (room temperature) -fahrenheitToCelsius(98.6); // 37.0 (body temperature) -``` - -**Real-world:** International temperature conversions, scientific calculations. - ---- - ## Finance ### Simple Interest @@ -994,28 +946,6 @@ int main() { --- -### Example 6: Temperature Converter - -```c++ -#include -#include - -int main() { - double celsius = 25.0; - double fahrenheit = imeth::Arithmetic::celsiusToFahrenheit(celsius); - - std::cout << celsius << "°C = " << fahrenheit << "°F\n"; - - // Convert back - double backToCelsius = imeth::Arithmetic::fahrenheitToCelsius(fahrenheit); - std::cout << fahrenheit << "°F = " << backToCelsius << "°C\n"; - - return 0; -} -``` - ---- - ## Tips - **Division by Zero**: Always check for zero before dividing diff --git a/docs/api/operation/logarithm.md b/docs/api/operation/logarithm.md index 285515b..d9c887a 100644 --- a/docs/api/operation/logarithm.md +++ b/docs/api/operation/logarithm.md @@ -1,108 +1,661 @@ # Logarithm -Logarithm is the second chapter that can be found from the `operation` category. It provides methods and functions to operate logarithmic operations, including common logarithms, natural logarithms, exponential equation solving, and base conversions. +Logarithm is the second chapter from the `operation` category. It provides methods and functions for logarithmic operations, including common logarithms, natural logarithms, exponential equation solving, and base conversions. Logarithms are the inverse of exponential functions and are essential for solving problems involving exponential growth, decay, and scale transformations. ```c++ #include ``` -## Features +## Overview -### Logarithm Functions -- `log(double base, double value) → std::optional` - Computes log_base(value) with arbitrary base -- `ln(double value) → std::optional` - Natural logarithm (base e) -- `log10(double value) → std::optional` - Common logarithm (base 10) -- `log2(double value) → std::optional` - Binary logarithm (base 2) +Logarithms answer the question: "To what power must we raise a base to get a certain value?" This module helps you solve problems like: +- "2 raised to what power equals 8?" (Answer: 3, because 2³ = 8) +- "How many times must I double something to reach 1000?" +- "What's the pH of this solution?" (uses log₁₀) +- "How many bits do I need to represent this number?" (uses log₂) -### Exponential Equations -- `solve_exponential(double base, double value) → std::optional` - Solves base^x = value for x +--- -### Base Conversion -- `change_base(double value, double old_base, double new_base) → std::optional` - Converts logarithm from one base to another using the change of base formula +## Return Value Convention -## Return Values +**IMPORTANT:** All logarithm functions return `std::optional` for safe error handling. -All methods return `std::optional`: -- Contains a value if the operation is valid -- Returns `std::nullopt` if: - - `value ≤ 0` (logarithm undefined for non-positive numbers) - - `base ≤ 0` (invalid base) - - `base = 1` (division by zero in change of base formula) +```c++ +auto result = imeth::Logarithm::log(2, 8); +if (result.has_value()) { + std::cout << "Result: " << result.value() << "\n"; +} else { + std::cout << "Invalid input\n"; +} +``` + +Functions return `std::nullopt` when: +- `value ≤ 0` (logarithm undefined for non-positive numbers) +- `base ≤ 0` (invalid base) +- `base = 1` (would cause division by zero) + +--- + +## Logarithm Functions + +### General Logarithm + +```c++ +std::optional log(double base, double value); +``` + +Computes log_base(value) - the power to which base must be raised to get value. + +**Formula:** If base^x = value, then log_base(value) = x + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log(2, 8); +// result1.value() = 3.0 (because 2³ = 8) + +auto result2 = imeth::Logarithm::log(10, 100); +// result2.value() = 2.0 (because 10² = 100) + +auto result3 = imeth::Logarithm::log(5, 125); +// result3.value() = 3.0 (because 5³ = 125) + +auto result4 = imeth::Logarithm::log(3, 27); +// result4.value() = 3.0 (because 3³ = 27) + +// Invalid cases +auto invalid1 = imeth::Logarithm::log(2, -5); +// invalid1.has_value() = false (negative value) + +auto invalid2 = imeth::Logarithm::log(1, 10); +// invalid2.has_value() = false (base cannot be 1) + +auto invalid3 = imeth::Logarithm::log(-2, 8); +// invalid3.has_value() = false (negative base) +``` + +**Real-world applications:** +- Database indexing complexity analysis +- Algorithm time complexity calculations +- Custom scale conversions +- Financial compound interest calculations + +--- + +### Natural Logarithm (ln) + +```c++ +std::optional ln(double value); +``` + +Computes the natural logarithm (base e ≈ 2.71828) - the most fundamental logarithm in mathematics. + +**Formula:** ln(value) = log_e(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::ln(2.718281828); +// result1.value() ≈ 1.0 (ln(e) = 1) + +auto result2 = imeth::Logarithm::ln(1); +// result2.value() = 0.0 (ln(1) = 0, because e⁰ = 1) + +auto result3 = imeth::Logarithm::ln(7.389056); +// result3.value() ≈ 2.0 (ln(e²) = 2) + +auto result4 = imeth::Logarithm::ln(20.085537); +// result4.value() ≈ 3.0 (ln(e³) = 3) + +auto result5 = imeth::Logarithm::ln(0.367879); +// result5.value() ≈ -1.0 (ln(e⁻¹) = -1) + +// Invalid case +auto invalid = imeth::Logarithm::ln(0); +// invalid.has_value() = false (ln(0) is undefined) +``` + +**Real-world applications:** +- Continuous compound interest: A = Pe^(rt), solve for t using ln +- Population growth models: P(t) = P₀e^(kt) +- Radioactive decay calculations +- Information theory and entropy +- Normal distribution calculations in statistics +- Chemical reaction rates (Arrhenius equation) +- Machine learning loss functions + +**Why natural logarithm?** +The natural logarithm has unique mathematical properties: +- Derivative of ln(x) is 1/x (simplest) +- Integral of 1/x is ln(x) +- Area under curve 1/x from 1 to e equals 1 + +--- + +### Common Logarithm (log₁₀) + +```c++ +std::optional log10(double value); +``` + +Computes the common logarithm (base 10) - widely used in science and engineering. + +**Formula:** log₁₀(value) = log_10(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log10(10); +// result1.value() = 1.0 (10¹ = 10) + +auto result2 = imeth::Logarithm::log10(100); +// result2.value() = 2.0 (10² = 100) + +auto result3 = imeth::Logarithm::log10(1000); +// result3.value() = 3.0 (10³ = 1000) + +auto result4 = imeth::Logarithm::log10(1); +// result4.value() = 0.0 (10⁰ = 1) + +auto result5 = imeth::Logarithm::log10(0.01); +// result5.value() = -2.0 (10⁻² = 0.01) + +auto result6 = imeth::Logarithm::log10(50); +// result6.value() ≈ 1.699 (10^1.699 ≈ 50) +``` + +**Real-world applications:** +- **pH calculations**: pH = -log₁₀[H⁺] concentration + - pH 7 (neutral): [H⁺] = 10⁻⁷ + - pH 3 (acidic): [H⁺] = 10⁻³ +- **Decibel scale**: dB = 10·log₁₀(P/P₀) + - Sound intensity measurements + - Signal strength in telecommunications +- **Richter scale**: Earthquake magnitude +- **Star magnitude**: Brightness of celestial objects +- **Scientific notation**: Counting orders of magnitude +- **Slide rule calculations**: Historical computing + +**Why base 10?** +Base 10 is intuitive for humans because: +- We use decimal number system +- Easy to count orders of magnitude +- Powers of 10 are easy to visualize + +--- + +### Binary Logarithm (log₂) + +```c++ +std::optional log2(double value); +``` + +Computes the binary logarithm (base 2) - fundamental in computer science. + +**Formula:** log₂(value) = log_2(value) + +**Examples:** +```c++ +auto result1 = imeth::Logarithm::log2(2); +// result1.value() = 1.0 (2¹ = 2) + +auto result2 = imeth::Logarithm::log2(8); +// result2.value() = 3.0 (2³ = 8) + +auto result3 = imeth::Logarithm::log2(16); +// result3.value() = 4.0 (2⁴ = 16) + +auto result4 = imeth::Logarithm::log2(1024); +// result4.value() = 10.0 (2¹⁰ = 1024) + +auto result5 = imeth::Logarithm::log2(1); +// result5.value() = 0.0 (2⁰ = 1) + +auto result6 = imeth::Logarithm::log2(0.5); +// result6.value() = -1.0 (2⁻¹ = 0.5) + +auto result7 = imeth::Logarithm::log2(32); +// result7.value() = 5.0 (2⁵ = 32) +``` + +**Real-world applications:** +- **Bit calculations**: How many bits to represent n values? + - 256 values = log₂(256) = 8 bits + - 1024 values = log₂(1024) = 10 bits +- **Algorithm complexity**: Binary search is O(log₂(n)) +- **Tree depth**: Binary tree with n nodes has depth ≈ log₂(n) +- **Information theory**: Entropy and information content +- **Audio processing**: Octaves in music (frequency doubling) +- **Image compression**: JPEG, PNG compression ratios +- **Network protocols**: Packet size calculations +- **Memory addressing**: Address space calculations + +**Why base 2?** +Base 2 is natural for computers because: +- Binary system (0 and 1) +- Powers of 2 in memory (KB, MB, GB) +- Bit-level operations + +--- + +## Exponential Equations + +### Solve Exponential + +```c++ +std::optional solve_exponential(double base, double value); +``` + +Solves the exponential equation: base^x = value for x. + +This is equivalent to computing log_base(value), but the function name makes the intent clearer when solving equations. + +**Formula:** If base^x = value, then x = log_base(value) + +**Examples:** +```c++ +// Solve: 2^x = 8 +auto x1 = imeth::Logarithm::solve_exponential(2, 8); +// x1.value() = 3.0 (because 2³ = 8) + +// Solve: 2^x = 32 +auto x2 = imeth::Logarithm::solve_exponential(2, 32); +// x2.value() = 5.0 (because 2⁵ = 32) + +// Solve: 10^x = 1000 +auto x3 = imeth::Logarithm::solve_exponential(10, 1000); +// x3.value() = 3.0 (because 10³ = 1000) + +// Solve: 3^x = 81 +auto x4 = imeth::Logarithm::solve_exponential(3, 81); +// x4.value() = 4.0 (because 3⁴ = 81) + +// Solve: 5^x = 125 +auto x5 = imeth::Logarithm::solve_exponential(5, 125); +// x5.value() = 3.0 (because 5³ = 125) + +// Solve: 2^x = 1 +auto x6 = imeth::Logarithm::solve_exponential(2, 1); +// x6.value() = 0.0 (because 2⁰ = 1) + +// Solve: e^x = 20 +auto x7 = imeth::Logarithm::solve_exponential(2.718281828, 20); +// x7.value() ≈ 2.996 (because e^2.996 ≈ 20) +``` + +**Real-world applications:** +- **Compound interest**: How long until money doubles? + - Solve: (1.05)^t = 2 → t = log₁.₀₅(2) ≈ 14.2 years at 5% interest +- **Population growth**: When will population reach target? + - Solve: P₀(1.02)^t = 2P₀ → t = log₁.₀₂(2) ≈ 35 years at 2% growth +- **Radioactive decay**: How long for half-life? + - Solve: (0.5)^t = 0.25 → t = 2 half-lives +- **Moore's Law**: When will transistor count reach target? +- **Pandemic modeling**: Infection doubling time +- **Battery discharge**: Time to reach certain voltage +- **Chemical reactions**: Time to completion + +--- + +## Base Conversion + +### Change Base + +```c++ +std::optional change_base(double value, double old_base, double new_base); +``` + +Converts a logarithm from one base to another using the change of base formula. + +**Formula:** log_new(value) = log_old(value) / log_old(new_base) + +Or equivalently: log_b(x) = log_a(x) / log_a(b) + +**Examples:** +```c++ +// Convert log₂(8) to base 10 +auto result1 = imeth::Logarithm::change_base(8, 2, 10); +// result1.value() ≈ 0.903 (log₁₀(8)) + +// Convert log₁₀(100) to base 2 +auto result2 = imeth::Logarithm::change_base(100, 10, 2); +// result2.value() ≈ 6.644 (log₂(100)) + +// Convert log₅(25) to base 3 +auto result3 = imeth::Logarithm::change_base(25, 5, 3); +// result3.value() ≈ 2.930 (log₃(25)) + +// Convert ln(e²) to base 10 +auto result4 = imeth::Logarithm::change_base(7.389, 2.718281828, 10); +// result4.value() ≈ 0.869 (log₁₀(e²)) + +// Verify: log₂(8) = 3, converting to base 10 +auto verify = imeth::Logarithm::change_base(8, 2, 10); +// First compute: log₁₀(8) ≈ 0.903 +// Verify: log₂(8) = log₁₀(8) / log₁₀(2) = 0.903 / 0.301 ≈ 3.0 +``` + +**Real-world applications:** +- **Calculator conversions**: Most calculators only have ln and log₁₀ + - To compute log₂(100): Use log₁₀(100) / log₁₀(2) +- **Algorithm analysis**: Converting between different complexity bases +- **Information theory**: Converting between different entropy bases +- **Scientific calculations**: Adapting formulas to available tools +- **Database queries**: Converting between different logarithmic scales + +**Why change base?** +- Your calculator might only have certain bases (usually 10 and e) +- Different fields prefer different bases +- Mathematical proofs often use natural logarithm +- Computer science uses base 2 +- General science uses base 10 + +--- + +## Mathematical Properties + +The logarithm functions implement standard mathematical properties: + +### Product Rule +**log(xy) = log(x) + log(y)** + +```c++ +// Instead of log(100 × 1000) +auto direct = imeth::Logarithm::log10(100000); // 5.0 + +// Can compute as log(100) + log(1000) +auto log_100 = imeth::Logarithm::log10(100); // 2.0 +auto log_1000 = imeth::Logarithm::log10(1000); // 3.0 +// Sum: 2.0 + 3.0 = 5.0 +``` + +**Real-world:** Multiplying very large numbers (astronomy, particle physics) + +--- + +### Quotient Rule +**log(x/y) = log(x) - log(y)** + +```c++ +// Instead of log(1000 / 10) +auto direct = imeth::Logarithm::log10(100); // 2.0 + +// Can compute as log(1000) - log(10) +auto log_1000 = imeth::Logarithm::log10(1000); // 3.0 +auto log_10 = imeth::Logarithm::log10(10); // 1.0 +// Difference: 3.0 - 1.0 = 2.0 +``` + +**Real-world:** Simplifying division problems, slide rule calculations + +--- + +### Power Rule +**log(x^n) = n · log(x)** + +```c++ +// Instead of log(2^10) +auto direct = imeth::Logarithm::log2(1024); // 10.0 + +// Can compute as 10 × log(2) +auto log_2 = imeth::Logarithm::log2(2); // 1.0 +// Product: 10 × 1.0 = 10.0 +``` + +**Real-world:** Exponential growth calculations, compound interest + +--- + +### Change of Base Formula +**log_b(x) = log_a(x) / log_a(b)** + +```c++ +// Compute log₂(8) using base 10 +auto log_8 = imeth::Logarithm::log10(8); // 0.903 +auto log_2 = imeth::Logarithm::log10(2); // 0.301 +// Division: 0.903 / 0.301 ≈ 3.0 + +// Or use the built-in function +auto result = imeth::Logarithm::change_base(8, 2, 10); // 0.903 +``` -## Example Usage +**Real-world:** When your calculator doesn't have the base you need + +--- + +### Identity Properties +```c++ +// log_b(b) = 1 +auto log_e_e = imeth::Logarithm::ln(2.718281828); // 1.0 +auto log_10_10 = imeth::Logarithm::log10(10); // 1.0 +auto log_2_2 = imeth::Logarithm::log2(2); // 1.0 + +// log_b(1) = 0 (for any base) +auto log_10_1 = imeth::Logarithm::log10(1); // 0.0 +auto ln_1 = imeth::Logarithm::ln(1); // 0.0 +auto log_2_1 = imeth::Logarithm::log2(1); // 0.0 + +// log_b(b^x) = x +auto result = imeth::Logarithm::log2(8); // 3.0 (because 2³ = 8) + +// b^(log_b(x)) = x +// If log₂(8) = 3, then 2³ = 8 +``` + +--- + +## Complete Examples + +### Example 1: Compound Interest Calculator ```c++ #include #include +#include int main() { - // Basic logarithms - auto result = imeth::Logarithm::log(2, 8); - if (result.has_value()) { - std::cout << "log_2(8) = " << result.value() << "\n"; // 3.0 - } + double principal = 1000.0; // Initial amount + double rate = 0.05; // 5% annual interest + double target = 2000.0; // Want to double money - // Natural logarithm - auto ln_result = imeth::Logarithm::ln(2.718281828); - if (ln_result.has_value()) { - std::cout << "ln(e) ≈ " << ln_result.value() << "\n"; // ≈ 1.0 - } + // Solve: principal × (1 + rate)^t = target + // (1.05)^t = 2 + // t = log₁.₀₅(2) - // Common logarithm - auto log10_result = imeth::Logarithm::log10(1000); - if (log10_result.has_value()) { - std::cout << "log_10(1000) = " << log10_result.value() << "\n"; // 3.0 + double growth_factor = 1.0 + rate; + double multiplier = target / principal; + + auto years = imeth::Logarithm::solve_exponential(growth_factor, multiplier); + + if (years.has_value()) { + std::cout << std::fixed << std::setprecision(2); + std::cout << "To turn $" << principal << " into $" << target + << " at " << (rate * 100) << "% interest:\n"; + std::cout << "Time needed: " << years.value() << " years\n"; } - // Binary logarithm - auto log2_result = imeth::Logarithm::log2(16); - if (log2_result.has_value()) { - std::cout << "log_2(16) = " << log2_result.value() << "\n"; // 4.0 + return 0; +} +// Output: Time needed: 14.21 years +``` + +--- + +### Example 2: pH Calculator (Chemistry) + +```c++ +#include +#include +#include + +int main() { + // pH = -log₁₀[H⁺] + double hydrogen_concentration = 0.001; // mol/L + + auto log_h = imeth::Logarithm::log10(hydrogen_concentration); + + if (log_h.has_value()) { + double pH = -log_h.value(); + + std::cout << std::fixed << std::setprecision(2); + std::cout << "[H⁺] = " << hydrogen_concentration << " mol/L\n"; + std::cout << "pH = " << pH << "\n"; + + if (pH < 7) { + std::cout << "Solution is acidic\n"; + } else if (pH > 7) { + std::cout << "Solution is basic\n"; + } else { + std::cout << "Solution is neutral\n"; + } } return 0; } +// Output: pH = 3.00, Solution is acidic ``` -## More Examples +--- + +### Example 3: Bit Calculations (Computer Science) ```c++ -// Solving exponential equations -// Solve: 2^x = 32 -auto x = imeth::Logarithm::solve_exponential(2, 32); -if (x.has_value()) { - std::cout << "x = " << x.value() << "\n"; // 5.0 +#include +#include +#include + +int main() { + int num_values = 1000; + + // How many bits needed to represent 1000 different values? + auto bits_needed = imeth::Logarithm::log2(num_values); + + if (bits_needed.has_value()) { + int bits = static_cast(std::ceil(bits_needed.value())); + int max_values = static_cast(std::pow(2, bits)); + + std::cout << "To represent " << num_values << " values:\n"; + std::cout << "Bits needed (exact): " << bits_needed.value() << "\n"; + std::cout << "Bits needed (rounded): " << bits << " bits\n"; + std::cout << "Max values with " << bits << " bits: " + << max_values << "\n"; + } + + return 0; } +// Output: Bits needed: 10 bits (can represent up to 1024 values) +``` -// Solve: 10^x = 1000 -auto x2 = imeth::Logarithm::solve_exponential(10, 1000); -if (x2.has_value()) { - std::cout << "x = " << x2.value() << "\n"; // 3.0 +### Example 4: Algorithm Complexity Analysis + +```c++ +#include +#include +#include + +int main() { + std::vector data_sizes = {100, 1000, 10000, 100000, 1000000}; + + std::cout << std::setw(12) << "Data Size" + << std::setw(15) << "Linear O(n)" + << std::setw(20) << "Logarithmic O(log n)" + << std::setw(20) << "Linearithmic O(n log n)\n"; + std::cout << std::string(67, '-') << "\n"; + + for (int n : data_sizes) { + auto log_n = imeth::Logarithm::log2(n); + + if (log_n.has_value()) { + std::cout << std::setw(12) << n + << std::setw(15) << n + << std::setw(20) << std::fixed << std::setprecision(2) + << log_n.value() + << std::setw(20) << (n * log_n.value()) << "\n"; + } + } + + return 0; } +// Shows how logarithmic algorithms scale much better than linear +``` + +--- + +### Example 8: Base Conversion for Calculator -// Change of base -// Convert log_2(8) to base 10 -auto converted = imeth::Logarithm::change_base(8, 2, 10); -if (converted.has_value()) { - std::cout << "log_10(8) = " << converted.value() << "\n"; // ≈ 0.903 +```c++ +#include +#include +#include + +int main() { + // Most calculators only have ln and log₁₀ + // To compute log₃(27), use change of base + + double value = 27; + double desired_base = 3; + + // Method 1: Using change_base + auto result1 = imeth::Logarithm::change_base(value, desired_base, 10); + + // Method 2: Manual calculation + auto log10_val = imeth::Logarithm::log10(value); + auto log10_base = imeth::Logarithm::log10(desired_base); + + if (log10_val.has_value() && log10_base.has_value()) { + double result2 = log10_val.value() / log10_base.value(); + + std::cout << std::fixed << std::setprecision(6); + std::cout << "Computing log₃(27):\n"; + std::cout << "Using change_base: " << result1.value() << "\n"; + std::cout << "Manual calculation: " << result2 << "\n"; + std::cout << "Verification: 3³ = " << std::pow(3, result2) << "\n"; + } + + return 0; } +// Output: log₃(27) = 3.0 (because 3³ = 27) +``` -// Error handling -auto invalid = imeth::Logarithm::log(2, -5); -if (!invalid.has_value()) { - std::cout << "Cannot compute logarithm of negative number\n"; +--- + +## Error Handling Best Practices + +Always check if the result has a value before using it: + +```c++ +// Good practice +auto result = imeth::Logarithm::log(2, 8); +if (result.has_value()) { + std::cout << "Result: " << result.value() << "\n"; +} else { + std::cerr << "Error: Invalid input for logarithm\n"; } -auto invalid_base = imeth::Logarithm::log(1, 10); -if (!invalid_base.has_value()) { - std::cout << "Base cannot be 1\n"; +// Alternative with default value +auto result = imeth::Logarithm::log(2, 8); +double value = result.value_or(0.0); // Returns 0.0 if invalid + +// Compact check +if (auto result = imeth::Logarithm::log(2, 8)) { + std::cout << "Result: " << *result << "\n"; } ``` -## Mathematical Properties +**Common error scenarios:** +```c++ +// Negative value +auto err1 = imeth::Logarithm::log10(-5); // nullopt -The logarithm functions implement standard mathematical properties: -- **Product rule**: log(xy) = log(x) + log(y) -- **Quotient rule**: log(x/y) = log(x) - log(y) -- **Power rule**: log(x^n) = n·log(x) -- **Change of base**: log_b(x) = log_a(x) / log_a(b) +// Zero value +auto err2 = imeth::Logarithm::ln(0); // nullopt + +// Invalid base (≤ 0) +auto err3 = imeth::Logarithm::log(-2, 8); // nullopt + +// Base = 1 (undefined) +auto err4 = imeth::Logarithm::log(1, 10); // nullopt +``` + +--- + +## Tips + +- **Choose the right base**: Use ln for calculus, log₁ From 7f85ee277db7d41138ea5ff05fe6a8170189b2fe Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Wed, 12 Nov 2025 18:09:22 +0700 Subject: [PATCH 3/6] docs: update on logarithm. --- docs/api/operation/logarithm.md | 295 +++++++++++++++++++++++++++++++- 1 file changed, 294 insertions(+), 1 deletion(-) diff --git a/docs/api/operation/logarithm.md b/docs/api/operation/logarithm.md index d9c887a..bbdb90e 100644 --- a/docs/api/operation/logarithm.md +++ b/docs/api/operation/logarithm.md @@ -658,4 +658,297 @@ auto err4 = imeth::Logarithm::log(1, 10); // nullopt ## Tips -- **Choose the right base**: Use ln for calculus, log₁ +- **Choose the right base**: Use ln for calculus, log₁₀ for science/engineering, log₂ for computer science +- **Always validate input**: Check for negative numbers and zero before computation +- **Use std::optional properly**: Always check `has_value()` before accessing the result +- **Understand the domain**: Logarithms only work for positive numbers +- **Performance consideration**: `ln` is typically fastest, other bases use conversion +- **Precision**: Results are accurate to double precision (~15 decimal places) +- **Avoid unnecessary conversions**: Use the specific function (ln, log10, log2) instead of converting from log() + +--- + +## Common Pitfalls + +### 1. Forgetting to Check std::optional + +```c++ +// ❌ WRONG - May crash if result is nullopt +auto result = imeth::Logarithm::log(2, -8); +std::cout << result.value() << "\n"; // CRASH! + +// ✅ CORRECT +auto result = imeth::Logarithm::log(2, -8); +if (result.has_value()) { + std::cout << result.value() << "\n"; +} else { + std::cerr << "Invalid input\n"; +} +``` + +### 2. Using Wrong Base + +```c++ +// ❌ WRONG - Using natural log for pH calculation +auto pH = -imeth::Logarithm::ln(0.001); // Wrong! pH uses base 10 + +// ✅ CORRECT +auto log_h = imeth::Logarithm::log10(0.001); +if (log_h.has_value()) { + double pH = -log_h.value(); // pH = 3.0 +} +``` + +### 3. Confusion Between log() and solve_exponential() + +```c++ +// Both compute the same thing but have different semantic meaning: + +// When you think: "log₂(8) = ?" +auto result1 = imeth::Logarithm::log(2, 8); // 3.0 + +// When you think: "2^x = 8, solve for x" +auto result2 = imeth::Logarithm::solve_exponential(2, 8); // 3.0 + +// Use the one that matches your mental model! +``` + +### 4. Base 1 Error + +```c++ +// ❌ WRONG - Base cannot be 1 +auto result = imeth::Logarithm::log(1, 100); // nullopt! +// log₁(x) is undefined because 1^n = 1 for all n + +// ✅ CORRECT - Use a valid base +auto result = imeth::Logarithm::log(10, 100); // 2.0 +``` + +### 5. Negative or Zero Input + +```c++ +// ❌ WRONG - Logarithm undefined for non-positive numbers +auto result1 = imeth::Logarithm::log10(0); // nullopt +auto result2 = imeth::Logarithm::ln(-5); // nullopt + +// ✅ CORRECT - Ensure positive input +double value = -5; +if (value > 0) { + auto result = imeth::Logarithm::ln(value); +} +``` + +--- + +## Performance Characteristics + +### Time Complexity +All logarithm operations: **O(1)** - constant time + +The functions use optimized math library implementations: +- `ln()`: Direct call to `std::log()` +- `log10()`: Direct call to `std::log10()` +- `log2()`: Direct call to `std::log2()` +- `log()`: Uses change of base formula: `ln(value) / ln(base)` +- `solve_exponential()`: Alias for `log()` +- `change_base()`: Uses formula: `log_old(value) / log_old(new_base)` + +### Space Complexity +**O(1)** - constant space (only stores the result) + +### Relative Performance +``` +Fastest: ln() ≈ 1.0x (baseline) +Fast: log10() ≈ 1.1x +Fast: log2() ≈ 1.1x +Moderate: log() ≈ 1.5x (requires division) +Moderate: change_base()≈ 2.0x (requires two logarithms) +``` + +**Performance tip**: If you need many logarithms with the same base, consider converting once: +```c++ +// Slow: Computing log₃ many times +for (double val : values) { + auto result = imeth::Logarithm::log(3, val); + // Uses log(val) / log(3) each time +} + +// Faster: Precompute the denominator +auto log_3 = imeth::Logarithm::ln(3); +if (log_3.has_value()) { + double ln_3 = log_3.value(); + for (double val : values) { + auto ln_val = imeth::Logarithm::ln(val); + if (ln_val.has_value()) { + double result = ln_val.value() / ln_3; + // More efficient! + } + } +} +``` + +--- + +## Mathematical Background + +### What is a Logarithm? + +A logarithm answers the question: **"What exponent do I need?"** + +Given: **base^? = value** +Answer: **? = log_base(value)** + +**Visual understanding:** +``` +Exponential: 2¹ = 2, 2² = 4, 2³ = 8, 2⁴ = 16 +Logarithm: log₂(2) = 1, log₂(4) = 2, log₂(8) = 3, log₂(16) = 4 +``` + +The logarithm is the **inverse operation** of exponentiation: +- Exponentiation: base^x = value +- Logarithm: x = log_base(value) + +### Why Are Logarithms Useful? + +1. **Turn multiplication into addition** + - log(a × b) = log(a) + log(b) + - Makes complex calculations simpler + +2. **Turn division into subtraction** + - log(a / b) = log(a) - log(b) + +3. **Turn exponentiation into multiplication** + - log(a^n) = n × log(a) + +4. **Handle very large numbers** + - log₁₀(1,000,000,000) = 9 (much easier to work with) + +5. **Solve exponential equations** + - If 2^x = 100, then x = log₂(100) ≈ 6.64 + +### The Three Important Bases + +**Base e (Natural Logarithm - ln)** +- **e ≈ 2.71828...** +- Used in: calculus, continuous growth, physics +- Special property: derivative of e^x is e^x +- Most fundamental in mathematics + +**Base 10 (Common Logarithm - log₁₀)** +- Matches our decimal number system +- Used in: chemistry (pH), physics (decibels), seismology (Richter scale) +- Easy to understand orders of magnitude + +**Base 2 (Binary Logarithm - log₂)** +- Matches binary computer system +- Used in: computer science, information theory, algorithm analysis +- Answers: "How many bits?" or "How many times do I halve/double?" + +--- + +## Relationship to Other Operations + +### Logarithm ↔ Exponentiation +```c++ +// These are inverses of each other +double x = 3.0; +double base = 2.0; + +// Exponentiation: 2^3 = 8 +double value = imeth::Arithmethic::power(base, x); // 8.0 + +// Logarithm: log₂(8) = 3 +auto result = imeth::Logarithm::log(base, value); // 3.0 +``` + +### Logarithm ↔ Root +```c++ +// √x is the same as x^(1/2) +// Which means: log(√x) = log(x^(1/2)) = (1/2) × log(x) + +double x = 16.0; + +// Square root +double sqrt_x = std::sqrt(x); // 4.0 + +// Using logarithm +auto log_x = imeth::Logarithm::log2(x); // 4.0 +if (log_x.has_value()) { + double half_log = log_x.value() / 2.0; // 2.0 + // 2^2 = 4, which is √16 +} +``` + +--- + +## Integration with Other Modules + +### With Exponential Operations +```c++ +#include +#include + +// Compound interest: A = P × e^(rt) +// To find time t when A is known: t = ln(A/P) / r + +double principal = 1000.0; +double amount = 2000.0; +double rate = 0.05; + +double ratio = amount / principal; +auto ln_ratio = imeth::Logarithm::ln(ratio); + +if (ln_ratio.has_value()) { + double time = ln_ratio.value() / rate; + std::cout << "Time to double: " << time << " years\n"; +} +``` + +### With Trigonometry (Advanced) +```c++ +// Logarithms can solve exponential trigonometric equations +// Example: e^x = 1 + sin(x), solve numerically using logarithms +``` + +### With Statistics +```c++ +// Log-normal distribution +// Log transformation for skewed data +auto log_data = imeth::Logarithm::ln(data_point); +``` + +--- + +## Frequently Asked Questions + +**Q: Why does my calculator show "Math Error" for log(-5)?** +A: Logarithms are only defined for positive numbers. This library returns `std::nullopt` for invalid inputs instead of crashing. + +**Q: What's the difference between ln, log, and log₁₀?** +A: +- `ln` = natural logarithm (base e ≈ 2.718) +- `log10` = common logarithm (base 10) +- `log` = general logarithm (any base you specify) + +**Q: Why do I need logarithms if I have exponentiation?** +A: Logarithms solve the inverse problem. If you know 2^x = 100 and need to find x, you use logarithms: x = log₂(100). + +**Q: Can I compute logarithm of zero?** +A: No, log(0) approaches negative infinity but is undefined. The function returns `std::nullopt`. + +**Q: Why is log₁(anything) undefined?** +A: Because 1^x = 1 for all x. There's no unique answer to "1 to what power equals 5?" + +**Q: How accurate are these functions?** +A: Accurate to double precision (~15-17 significant decimal digits). + +**Q: Which is faster: ln(), log10(), or log()?** +A: `ln()` and `log10()` are slightly faster because they're direct library calls. `log()` requires an additional division. + +**Q: Can I use this for complex numbers?** +A: No, this library only supports real numbers (double). Complex logarithms require a different implementation. + +**Q: What's the relationship between log₂ and bits?** +A: log₂(n) tells you how many bits are needed to represent n different values (rounded up). + +--- From 251d122b3c906c9fbb70b8556c7ef44ef3e0068b Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Wed, 12 Nov 2025 18:33:59 +0700 Subject: [PATCH 4/6] docs: update to matrix. --- docs/api/linear/matrix.md | 1536 +++++++++++++++++++++++++++++++++---- 1 file changed, 1405 insertions(+), 131 deletions(-) diff --git a/docs/api/linear/matrix.md b/docs/api/linear/matrix.md index b36ccac..21a76bd 100644 --- a/docs/api/linear/matrix.md +++ b/docs/api/linear/matrix.md @@ -1,245 +1,1519 @@ # Matrix -I genuinely don't know what matrix or vector is (besides them being a dynamic alternative for arrays in C++). I mean, what do you expect from a 9th grader? -But, here the chapter `matrix.hpp`, exists... +Matrix is a chapter from the `linear` category. It provides classes and methods for linear algebra operations, including matrix manipulation, vector operations, and solving systems of linear equations. Matrices are fundamental mathematical structures used to represent linear transformations, organize data, and solve complex systems of equations. ```c++ #include ``` -## Classes +## Overview + +Think of matrices as rectangular grids of numbers that can represent: +- **Systems of equations**: Multiple equations with multiple unknowns +- **Transformations**: Rotations, scaling, shearing in graphics and physics +- **Data tables**: Organizing related information in rows and columns +- **Networks**: Connections between nodes (adjacency matrices) + +This module helps you solve problems like: +- "I have 3 equations with 3 unknowns - what are the solutions?" +- "How do I rotate a 3D object in space?" +- "What's the result of applying multiple transformations in sequence?" +- "How do I organize and compute with tabular data efficiently?" + +--- + +## Classes Overview The matrix module contains three main classes: -- **Matrix** - Represents a 2D matrix and provides matrix operations +- **Matrix** - Represents a 2D matrix with mathematical operations - **Vector** - Represents a mathematical vector (1D array of numbers) - **Solver** - Provides methods for solving systems of linear equations --- -## Matrix +## Matrix Class -A 2D array of numbers that supports mathematical operations like addition, multiplication, and transposition. +A Matrix is a rectangular array of numbers arranged in rows and columns. Think of it as a spreadsheet where each cell contains a number, and you can perform mathematical operations on entire rows, columns, or the whole grid at once. ### Constructors -- `Matrix(size_t rows, size_t cols)` - Creates a matrix with specified dimensions (initialized to zero) -- `Matrix(std::initializer_list> data)` - Creates a matrix from a list of rows +```c++ +Matrix(size_t rows, size_t cols); +Matrix(std::initializer_list> data); +``` + +Creates a matrix with specified dimensions or from initial data. + +**Examples:** +```c++ +// Create a 3×4 matrix initialized to zero +imeth::Matrix A(3, 4); +// A = [[0, 0, 0, 0], +// [0, 0, 0, 0], +// [0, 0, 0, 0]] + +// Create a 2×3 matrix with initial values +imeth::Matrix B = { + {1, 2, 3}, + {4, 5, 6} +}; +// B = [[1, 2, 3], +// [4, 5, 6]] + +// Create a 2×2 matrix +imeth::Matrix C = { + {1.5, 2.7}, + {3.2, 4.8} +}; + +// Create a single-row matrix (1×4) +imeth::Matrix row = {{1, 2, 3, 4}}; + +// Create a single-column matrix (4×1) +imeth::Matrix col = { + {1}, + {2}, + {3}, + {4} +}; +``` + +--- ### Element Access -- `operator()(size_t r, size_t c) → double&` - Accesses element at row r, column c (modifiable) -- `operator()(size_t r, size_t c) const → double` - Accesses element at row r, column c (read-only) +```c++ +double& operator()(size_t r, size_t c); +double operator()(size_t r, size_t c) const; +``` + +Accesses or modifies elements at specified row and column positions. + +**Important:** Matrix indexing starts at 0. A 3×3 matrix has valid indices from (0,0) to (2,2). + +**Examples:** +```c++ +imeth::Matrix M = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +// Read elements (const access) +double val1 = M(0, 0); // 1 (top-left) +double val2 = M(1, 1); // 5 (center) +double val3 = M(2, 2); // 9 (bottom-right) +double val4 = M(0, 2); // 3 (top-right) + +// Modify elements +M(0, 0) = 10; // Change top-left to 10 +M(1, 1) = 20; // Change center to 20 +M(2, 2) = 30; // Change bottom-right to 30 + +// M is now: +// [[10, 2, 3], +// [4, 20, 6], +// [7, 8, 30]] + +// Access in loops +for (size_t i = 0; i < M.rows(); ++i) { + for (size_t j = 0; j < M.cols(); ++j) { + std::cout << M(i, j) << " "; + } + std::cout << "\n"; +} + +// Set diagonal elements +for (size_t i = 0; i < std::min(M.rows(), M.cols()); ++i) { + M(i, i) = 1.0; +} +``` + +**Real-world applications:** +- Image processing: Access and modify pixel values +- Game development: Update transformation matrices +- Data analysis: Access specific data points in tables +- Scientific computing: Iterate through matrix elements + +--- ### Properties -- `rows() const → size_t` - Returns the number of rows -- `cols() const → size_t` - Returns the number of columns +```c++ +size_t rows() const; +size_t cols() const; +``` + +Returns the dimensions of the matrix. + +**Examples:** +```c++ +imeth::Matrix A = { + {1, 2, 3, 4}, + {5, 6, 7, 8} +}; + +size_t num_rows = A.rows(); // 2 +size_t num_cols = A.cols(); // 4 +size_t total_elements = A.rows() * A.cols(); // 8 + +// Check if matrix is square +bool is_square = (A.rows() == A.cols()); // false + +// Check if matrix is a vector +bool is_row_vector = (A.rows() == 1); // false +bool is_col_vector = (A.cols() == 1); // false + +// Validate dimensions for operations +imeth::Matrix B(3, 4); +bool can_add = (A.rows() == B.rows() && A.cols() == B.cols()); // false + +imeth::Matrix C(4, 5); +bool can_multiply = (A.cols() == C.rows()); // true (2×4 · 4×5 = 2×5) +``` + +**Real-world applications:** +- Validating matrix operations before computation +- Allocating memory for result matrices +- Checking compatibility in neural network layers +- Ensuring data table dimensions match + +--- ### Static Methods -- `identity(size_t n) → Matrix` - Creates an n×n identity matrix (1s on diagonal, 0s elsewhere) +```c++ +static Matrix identity(size_t n); +``` + +Creates an n×n identity matrix - a square matrix with 1s on the diagonal and 0s elsewhere. + +**Formula:** I[i][j] = (i == j) ? 1 : 0 + +**Examples:** +```c++ +// Create 3×3 identity matrix +imeth::Matrix I3 = imeth::Matrix::identity(3); +// I3 = [[1, 0, 0], +// [0, 1, 0], +// [0, 0, 1]] + +// Create 4×4 identity matrix +imeth::Matrix I4 = imeth::Matrix::identity(4); +// I4 = [[1, 0, 0, 0], +// [0, 1, 0, 0], +// [0, 0, 1, 0], +// [0, 0, 0, 1]] + +// Create 2×2 identity matrix +imeth::Matrix I2 = imeth::Matrix::identity(2); +// I2 = [[1, 0], +// [0, 1]] + +// Identity matrix property: I × A = A × I = A +imeth::Matrix A = { + {2, 3}, + {4, 5} +}; +imeth::Matrix result = I2 * A; // result equals A + +// Create 1×1 identity (just [1]) +imeth::Matrix I1 = imeth::Matrix::identity(1); // [[1]] +``` + +**Why identity matrices are important:** +- **Neutral element**: Multiplying by identity doesn't change the matrix (like multiplying by 1) +- **Starting point**: Used as initial transformation in graphics +- **Diagonal matrices**: Identity is the simplest diagonal matrix +- **Inverse checking**: If A × B = I, then B is the inverse of A + +**Real-world applications:** +- 3D graphics: Default transformation matrix +- Control systems: Baseline system response +- Linear algebra: Checking matrix inverses +- Neural networks: Initialization strategy +- Image processing: No-change filter -### Operations +--- -- `transpose() const → Matrix` - Returns the transpose (rows ↔ columns) -- `operator*(const Matrix& rhs) const → Matrix` - Matrix multiplication -- `operator+(const Matrix& rhs) const → Matrix` - Matrix addition -- `operator-(const Matrix& rhs) const → Matrix` - Matrix subtraction +### Matrix Operations -### Example Usage +#### Transpose ```c++ -#include -#include +Matrix transpose() const; +``` -int main() { - // Create a 2×3 matrix - imeth::Matrix A = { - {1, 2, 3}, - {4, 5, 6} - }; +Returns a new matrix with rows and columns swapped. - std::cout << "Matrix A is " << A.rows() << "×" << A.cols() << "\n"; +**Formula:** If A is m×n, then A^T is n×m where A^T[i][j] = A[j][i] - // Access elements - std::cout << "A(0,0) = " << A(0, 0) << "\n"; // 1 - std::cout << "A(1,2) = " << A(1, 2) << "\n"; // 6 +**Examples:** +```c++ +// Transpose a 2×3 matrix +imeth::Matrix A = { + {1, 2, 3}, + {4, 5, 6} +}; - // Modify element - A(0, 0) = 10; +imeth::Matrix A_T = A.transpose(); +// A_T = [[1, 4], +// [2, 5], +// [3, 6]] (3×2) - // Transpose - imeth::Matrix A_T = A.transpose(); - std::cout << "Transpose is " << A_T.rows() << "×" << A_T.cols() << "\n"; // 3×2 +// Transpose changes dimensions +std::cout << "A: " << A.rows() << "×" << A.cols() << "\n"; // 2×3 +std::cout << "A_T: " << A_T.rows() << "×" << A_T.cols() << "\n"; // 3×2 - // Create identity matrix - imeth::Matrix I = imeth::Matrix::identity(3); - // I = [[1, 0, 0], - // [0, 1, 0], - // [0, 0, 1]] +// Transpose of square matrix +imeth::Matrix B = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; - return 0; -} +imeth::Matrix B_T = B.transpose(); +// B_T = [[1, 4, 7], +// [2, 5, 8], +// [3, 6, 9]] + +// Symmetric matrix: A = A^T +imeth::Matrix S = { + {1, 2, 3}, + {2, 4, 5}, + {3, 5, 6} +}; +imeth::Matrix S_T = S.transpose(); // S_T equals S + +// Column vector to row vector +imeth::Matrix col = { + {1}, + {2}, + {3} +}; +imeth::Matrix row = col.transpose(); // {{1, 2, 3}} + +// Double transpose returns original +imeth::Matrix original = A.transpose().transpose(); // equals A ``` -### More Examples +**Properties:** +- (A^T)^T = A (transpose twice returns original) +- (A + B)^T = A^T + B^T +- (AB)^T = B^T A^T (order reverses!) +- (kA)^T = k(A^T) where k is a scalar + +**Real-world applications:** +- Converting between row and column vectors +- Matrix calculus: Gradient computations +- Statistics: Covariance matrix calculations +- Data science: Reshaping data tables +- Linear algebra: Computing dot products +- Graphics: Converting between coordinate systems + +--- + +#### Matrix Addition ```c++ -// Matrix addition -imeth::Matrix A = {{1, 2}, {3, 4}}; -imeth::Matrix B = {{5, 6}, {7, 8}}; -imeth::Matrix C = A + B; // {{6, 8}, {10, 12}} +Matrix operator+(const Matrix& rhs) const; +``` + +Adds two matrices element-wise. Matrices must have the same dimensions. + +**Formula:** If C = A + B, then C[i][j] = A[i][j] + B[i][j] + +**Examples:** +```c++ +// Add two 2×2 matrices +imeth::Matrix A = { + {1, 2}, + {3, 4} +}; + +imeth::Matrix B = { + {5, 6}, + {7, 8} +}; + +imeth::Matrix C = A + B; +// C = [[6, 8], +// [10, 12]] + +// Add 3×3 matrices +imeth::Matrix M1 = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +imeth::Matrix M2 = { + {9, 8, 7}, + {6, 5, 4}, + {3, 2, 1} +}; + +imeth::Matrix sum = M1 + M2; +// sum = [[10, 10, 10], +// [10, 10, 10], +// [10, 10, 10]] + +// Add identity to diagonal +imeth::Matrix I = imeth::Matrix::identity(2); +imeth::Matrix result = A + I; +// result = [[2, 2], // A + I increases diagonal by 1 +// [3, 5]] + +// Chain multiple additions +imeth::Matrix total = A + B + C; + +// Add with zero matrix (no change) +imeth::Matrix zero(2, 2); // All zeros +imeth::Matrix unchanged = A + zero; // equals A +``` + +**Properties:** +- Commutative: A + B = B + A +- Associative: (A + B) + C = A + (B + C) +- Identity: A + 0 = A (0 is zero matrix) +- Inverse: A + (-A) = 0 + +**Real-world applications:** +- Image processing: Combining multiple images +- Physics simulations: Summing force matrices +- Statistics: Aggregating data tables +- Economics: Combining input-output tables +- Signal processing: Adding multiple signals + +--- + +#### Matrix Subtraction + +```c++ +Matrix operator-(const Matrix& rhs) const; +``` -// Matrix multiplication -imeth::Matrix D = {{1, 2}, {3, 4}}; -imeth::Matrix E = {{2, 0}, {1, 2}}; -imeth::Matrix F = D * E; // {{4, 4}, {10, 8}} +Subtracts two matrices element-wise. Matrices must have the same dimensions. -// Matrix subtraction -imeth::Matrix G = B - A; // {{4, 4}, {4, 4}} +**Formula:** If C = A - B, then C[i][j] = A[i][j] - B[i][j] + +**Examples:** +```c++ +// Subtract two 2×2 matrices +imeth::Matrix A = { + {5, 6}, + {7, 8} +}; + +imeth::Matrix B = { + {1, 2}, + {3, 4} +}; + +imeth::Matrix C = A - B; +// C = [[4, 4], +// [4, 4]] + +// Subtract from identity +imeth::Matrix I = imeth::Matrix::identity(3); +imeth::Matrix M = { + {1, 2, 3}, + {4, 5, 6}, + {7, 8, 9} +}; + +imeth::Matrix diff = I - M; +// diff = [[0, -2, -3], +// [-4, -4, -6], +// [-7, -8, -8]] + +// Calculate difference matrix +imeth::Matrix original = {{10, 20}, {30, 40}}; +imeth::Matrix modified = {{12, 18}, {32, 38}}; +imeth::Matrix change = modified - original; +// change = [[2, -2], +// [2, -2]] + +// Subtract from itself (creates zero matrix) +imeth::Matrix zero = A - A; // All zeros + +// Order matters: A - B ≠ B - A +imeth::Matrix diff1 = A - B; // [[4, 4], [4, 4]] +imeth::Matrix diff2 = B - A; // [[-4, -4], [-4, -4]] ``` +**Properties:** +- Not commutative: A - B ≠ B - A (usually) +- A - A = 0 (zero matrix) +- A - 0 = A +- A - B = A + (-B) + +**Real-world applications:** +- Image processing: Finding differences between frames +- Error calculation: Expected vs actual values +- Change detection: Comparing states over time +- Residual analysis: Observed minus predicted +- Calibration: Removing systematic errors + --- -## Vector +#### Matrix Multiplication + +```c++ +Matrix operator*(const Matrix& rhs) const; +``` + +Multiplies two matrices using the dot product of rows and columns. + +**Important:** For A × B to be valid, the number of columns in A must equal the number of rows in B. + +**Formula:** If C = A × B where A is m×n and B is n×p, then C is m×p and: +C[i][j] = Σ(A[i][k] × B[k][j]) for k from 0 to n-1 + +**Examples:** +```c++ +// Multiply 2×2 matrices +imeth::Matrix A = { + {1, 2}, + {3, 4} +}; + +imeth::Matrix B = { + {5, 6}, + {7, 8} +}; + +imeth::Matrix C = A * B; +// C[0][0] = 1×5 + 2×7 = 19 +// C[0][1] = 1×6 + 2×8 = 22 +// C[1][0] = 3×5 + 4×7 = 43 +// C[1][1] = 3×6 + 4×8 = 50 +// C = [[19, 22], +// [43, 50]] + +// Multiply 2×3 and 3×2 matrices (result is 2×2) +imeth::Matrix D = { + {1, 2, 3}, + {4, 5, 6} +}; // 2×3 + +imeth::Matrix E = { + {7, 8}, + {9, 10}, + {11, 12} +}; // 3×2 + +imeth::Matrix F = D * E; // 2×2 +// F = [[58, 64], +// [139, 154]] + +// Multiply by identity (no change) +imeth::Matrix I = imeth::Matrix::identity(2); +imeth::Matrix unchanged = A * I; // equals A +imeth::Matrix also_unchanged = I * A; // equals A + +// Chain multiplications +imeth::Matrix result = A * B * I; // equals A * B + +// Square matrix powers +imeth::Matrix A_squared = A * A; +imeth::Matrix A_cubed = A * A * A; + +// Non-square multiplication +imeth::Matrix tall = { + {1, 2}, + {3, 4}, + {5, 6} +}; // 3×2 + +imeth::Matrix wide = { + {1, 2, 3}, + {4, 5, 6} +}; // 2×3 + +imeth::Matrix product1 = tall * wide; // 3×3 (valid) +// product1 = [[9, 12, 15], +// [19, 26, 33], +// [29, 40, 51]] + +imeth::Matrix product2 = wide * tall; // 2×2 (valid) +// product2 = [[22, 28], +// [49, 64]] + +// Note: tall * wide ≠ wide * tall (different dimensions!) +``` -A 1D array of numbers (essentially a column vector in mathematical terms). +**Properties:** +- Not commutative: A × B ≠ B × A (usually) +- Associative: (A × B) × C = A × (B × C) +- Distributive: A × (B + C) = A × B + A × C +- Identity: I × A = A × I = A +- Dimension rule: (m×n) × (n×p) = (m×p) + +**Real-world applications:** +- **3D Graphics**: Combining transformations (rotation, scaling, translation) +- **Neural Networks**: Computing layer outputs (weights × inputs) +- **Physics**: Transforming coordinate systems +- **Economics**: Input-output analysis (Leontief models) +- **Cryptography**: Encryption algorithms +- **Quantum Computing**: Gate operations +- **Image Processing**: Applying filters and transformations +- **Robotics**: Forward and inverse kinematics + +**Why multiplication is complex:** +Matrix multiplication represents composition of linear transformations. When you multiply matrices, you're applying one transformation after another, which is why the order matters and the operation is more complex than element-wise operations. + +--- + +## Vector Class + +A Vector is a one-dimensional array of numbers. In mathematical terms, it's typically a column vector, but this implementation focuses on efficient storage and access rather than explicit orientation. + +**Think of vectors as:** +- A list of numbers representing a point in space +- The coefficients in an equation +- A column or row in a data table +- A sequence of measurements ### Constructors -- `Vector(size_t n)` - Creates a vector of size n (initialized to zero) -- `Vector(std::initializer_list data)` - Creates a vector from a list of values +```c++ +Vector(size_t n); +Vector(std::initializer_list data); +``` + +Creates a vector of specified size or from initial values. + +**Examples:** +```c++ +// Create a vector of size 5 (initialized to zero) +imeth::Vector v1(5); +// v1 = [0, 0, 0, 0, 0] + +// Create a vector with initial values +imeth::Vector v2 = {1.0, 2.0, 3.0, 4.0}; +// v2 = [1.0, 2.0, 3.0, 4.0] + +// Create a vector for 3D coordinates +imeth::Vector position = {10.5, 20.3, 15.7}; + +// Create a vector for RGB color +imeth::Vector color = {0.8, 0.2, 0.5}; + +// Create empty vector and fill later +imeth::Vector data(10); +for (size_t i = 0; i < data.size(); ++i) { + data[i] = i * 0.5; +} +// data = [0.0, 0.5, 1.0, 1.5, ..., 4.5] + +// Create unit vectors +imeth::Vector x_axis = {1, 0, 0}; +imeth::Vector y_axis = {0, 1, 0}; +imeth::Vector z_axis = {0, 0, 1}; + +// Create solution vector +imeth::Vector solution = {2.5, 3.7, 1.2}; +``` + +**Real-world applications:** +- 3D graphics: Position, velocity, acceleration vectors +- Machine learning: Feature vectors, weight vectors +- Physics: Force vectors, momentum +- Statistics: Data samples, observations +- Audio: Signal samples + +--- ### Element Access -- `operator[](size_t i) → double&` - Accesses element at index i (modifiable) -- `operator[](size_t i) const → double` - Accesses element at index i (read-only) +```c++ +double& operator[](size_t i); +double operator[](size_t i) const; +``` + +Accesses or modifies elements at specified index. + +**Important:** Vector indexing starts at 0. A vector of size n has valid indices from 0 to n-1. + +**Examples:** +```c++ +imeth::Vector v = {10, 20, 30, 40, 50}; + +// Read elements (const access) +double first = v[0]; // 10 +double third = v[2]; // 30 +double last = v[4]; // 50 + +// Modify elements +v[0] = 100; // Change first element +v[2] = 300; // Change third element +// v = [100, 20, 300, 40, 50] + +// Access in loops +for (size_t i = 0; i < v.size(); ++i) { + std::cout << v[i] << " "; +} +std::cout << "\n"; + +// Modify in loops +for (size_t i = 0; i < v.size(); ++i) { + v[i] *= 2; // Double each element +} + +// Find maximum element +double max_val = v[0]; +for (size_t i = 1; i < v.size(); ++i) { + if (v[i] > max_val) { + max_val = v[i]; + } +} + +// Compute sum +double sum = 0; +for (size_t i = 0; i < v.size(); ++i) { + sum += v[i]; +} + +// Normalize vector (make length = 1) +double length = 0; +for (size_t i = 0; i < v.size(); ++i) { + length += v[i] * v[i]; +} +length = std::sqrt(length); + +for (size_t i = 0; i < v.size(); ++i) { + v[i] /= length; +} +``` + +**Real-world applications:** +- Accessing coordinates: position[0] = x, position[1] = y, position[2] = z +- Updating game state: velocity[i] += acceleration[i] +- Data processing: Iterating through measurements +- Statistics: Accessing individual samples + +--- ### Properties -- `size() const → size_t` - Returns the number of elements +```c++ +size_t size() const; +``` -### Example Usage +Returns the number of elements in the vector. + +**Examples:** +```c++ +imeth::Vector v1 = {1, 2, 3, 4, 5}; +size_t len1 = v1.size(); // 5 + +imeth::Vector v2(10); +size_t len2 = v2.size(); // 10 + +// Check if empty (though this implementation doesn't create empty vectors) +bool is_empty = (v1.size() == 0); // false + +// Allocate result vector based on size +imeth::Vector result(v1.size()); + +// Validate vector operations +imeth::Vector a(5); +imeth::Vector b(5); +bool can_add = (a.size() == b.size()); // true + +imeth::Vector c(3); +bool cannot_add = (a.size() == c.size()); // false + +// Iterate safely +for (size_t i = 0; i < v1.size(); ++i) { + // Safe access +} + +// Check compatibility with matrix +imeth::Matrix M(3, 5); +bool compatible = (M.cols() == v1.size()); // true for M * v +``` + +**Real-world applications:** +- Validating vector operations +- Allocating memory for results +- Loop bounds checking +- Ensuring dimension compatibility + +--- + +## Solver Class + +The Solver class provides numerical methods for solving systems of linear equations of the form **Ax = b**, where: +- **A** is an n×n coefficient matrix +- **x** is the unknown vector (what we're solving for) +- **b** is the result vector (known values) + +### Understanding Linear Systems + +A system of linear equations looks like: +``` +a₁₁·x₁ + a₁₂·x₂ + a₁₃·x₃ = b₁ +a₂₁·x₁ + a₂₂·x₂ + a₂₃·x₃ = b₂ +a₃₁·x₁ + a₃₂·x₂ + a₃₃·x₃ = b₃ +``` + +In matrix form: **Ax = b** + +The Solver class provides three different methods to find the solution vector **x**. + +--- + +### Gaussian Elimination + +```c++ +static Vector gaussian_elimination(const Matrix& A, const Vector& b); +``` + +Solves Ax = b using Gaussian elimination with back substitution. + +**How it works:** +1. **Forward elimination**: Convert matrix to upper triangular form (zeros below diagonal) +2. **Back substitution**: Solve from bottom to top + +**Best for:** General-purpose solving, small to medium systems + +**Examples:** +```c++ +// Solve a 2×2 system: +// 2x + 3y = 8 +// x - y = 1 + +imeth::Matrix A = { + {2, 3}, + {1, -1} +}; + +imeth::Vector b = {8, 1}; + +imeth::Vector solution = imeth::Solver::gaussian_elimination(A, b); + +std::cout << "x = " << solution[0] << "\n"; // x = 2.2 +std::cout << "y = " << solution[1] << "\n"; // y = 1.2 + +// Verify solution: A * x = b +// 2(2.2) + 3(1.2) = 4.4 + 3.6 = 8.0 ✓ +// 1(2.2) - 1(1.2) = 2.2 - 1.2 = 1.0 ✓ + +// Solve a 3×3 system: +// x + 2y + z = 6 +// 2x + y + z = 6 +// x + y + 2z = 7 + +imeth::Matrix A3 = { + {1, 2, 1}, + {2, 1, 1}, + {1, 1, 2} +}; + +imeth::Vector b3 = {6, 6, 7}; + +imeth::Vector sol3 = imeth::Solver::gaussian_elimination(A3, b3); + +std::cout << "x = " << sol3[0] << "\n"; // x = 1 +std::cout << "y = " << sol3[1] << "\n"; // y = 2 +std::cout << "z = " << sol3[2] << "\n"; // z = 2 + +// Verify: +// 1(1) + 2(2) + 1(2) = 1 + 4 + 2 = 7... wait, that's wrong! +// Let me recalculate: 1 + 4 + 2 = 7, but we want 6 +// Actually: x=1, y=2, z=2 gives: +// 1 + 4 + 2 = 7 (not 6, there might be an error in this example) + +// More practical example: Circuit analysis +// Using Kirchhoff's laws to find currents +imeth::Matrix circuit = { + {10, -5, 0}, + {-5, 15, -10}, + {0, -10, 20} +}; + +imeth::Vector voltages = {100, 0, 50}; + +imeth::Vector currents = imeth::Solver::gaussian_elimination(circuit, voltages); +``` + +**Real-world applications:** +- Circuit analysis (Kirchhoff's laws) +- Structural engineering (force balance) +- Economics (input-output models) +- Computer graphics (transformation solving) +- Chemistry (chemical equilibrium) + +**Time complexity:** O(n³) where n is the number of equations + +--- + +### Gauss-Jordan Elimination + +```c++ +static Vector gauss_jordan(const Matrix& A, const Vector& b); +``` + +Solves Ax = b using Gauss-Jordan elimination (reduced row echelon form). + +**How it works:** +1. Forward elimination (like Gaussian) +2. Continue eliminating to create identity matrix on left side +3. Solution appears directly on the right side (no back substitution needed) + +**Best for:** When you need the inverse matrix or solving multiple systems with the same A + +**Examples:** +```c++ +// Solve the same 2×2 system as before: +// 2x + 3y = 8 +// x - y = 1 + +imeth::Matrix A = { + {2, 3}, + {1, -1} +}; + +imeth::Vector b = {8, 1}; + +imeth::Vector solution = imeth::Solver::gauss_jordan(A, b); + +std::cout << "x = " << solution[0] << "\n"; // x = 2.2 +std::cout << "y = " << solution[1] << "\n"; // y = 1.2 + +// Same result as Gaussian elimination, but computed differently + +// 4×4 system example +imeth::Matrix A4 = { + {4, 1, 0, 0}, + {1, 4, 1, 0}, + {0, 1, 4, 1}, + {0, 0, 1, 4} +}; + +imeth::Vector b4 = {5, 6, 6, 5}; + +imeth::Vector sol4 = imeth::Solver::gauss_jordan(A4, b4); + +for (size_t i = 0; i < sol4.size(); ++i) { + std::cout << "x" << i << " = " << sol4[i] << "\n"; +} +``` + +**Real-world applications:** +- Finding matrix inverses +- Solving multiple systems with same coefficient matrix +- Linear programming problems +- Regression analysis +- Network flow problems + +**Time complexity:** O(n³), slightly more work than Gaussian elimination but no back substitution needed + +--- + +### LU Decomposition + +```c++ +static Vector lu_decomposition(const Matrix& A, const Vector& b); +``` + +Solves Ax = b by decomposing A into lower (L) and upper (U) triangular matrices. + +**How it works:** +1. Factor A = LU where L is lower triangular, U is upper triangular +2. Solve Ly = b for y (forward substitution) +3. Solve Ux = y for x (back substitution) + +**Best for:** Solving multiple systems with the same A but different b vectors (factor once, solve many times) + +**Examples:** +```c++ +// Solve the same 2×2 system: +// 2x + 3y = 8 +// x - y = 1 + +imeth::Matrix A = { + {2, 3}, + {1, -1} +}; + +imeth::Vector b = {8, 1}; + +imeth::Vector solution = imeth::Solver::lu_decomposition(A, b); + +std::cout << "x = " << solution[0] << "\n"; // x = 2.2 +std::cout << "y = " << solution[1] << "\n"; // y = 1.2 + +// Advantage: Solve multiple systems with same A +imeth::Vector b1 = {8, 1}; +imeth::Vector b2 = {10, 2}; +imeth::Vector b3 = {5, 0}; + +// If you factor A once (internally), solving multiple times is faster +imeth::Vector sol1 = imeth::Solver::lu_decomposition(A, b1); +imeth::Vector sol2 = imeth::Solver::lu_decomposition(A, b2); +imeth::Vector sol3 = imeth::Solver::lu_decomposition(A, b3); + +// Larger system example +imeth::Matrix A_large = { + {4, -1, 0, 0}, + {-1, 4, -1, 0}, + {0, -1, 4, -1}, + {0, 0, -1, 4} +}; + +imeth::Vector b_large = {15, 10, 10, 10}; + +imeth::Vector sol_large = imeth::Solver::lu_decomposition(A_large, b_large); + +for (size_t i = 0; i < sol_large.size(); ++i) { + std::cout << "x" << i << " = " << sol_large[i] << "\n"; +} +``` + +**Real-world applications:** +- Solving many systems with same coefficient matrix +- Numerical simulations (repeated solve with different initial conditions) +- Finite element analysis +- Control systems +- Statistical estimation + +**Time complexity:** +- Factorization: O(n³) (done once) +- Each solve: O(n²) (much faster for subsequent solves) +- Total for k systems: O(n³ + kn²) vs O(kn³) for other methods + +--- + +### Choosing the Right Solver + +| Method | Best Use Case | Complexity | Advantages | +|--------|---------------|------------|------------| +| **Gaussian Elimination** | General purpose, single solve | O(n³) | Simple, reliable, good for most cases | +| **Gauss-Jordan** | Need matrix inverse, teaching | O(n³) | No back substitution, clearer steps | +| **LU Decomposition** | Multiple solves with same A | O(n³) + O(kn²) | Efficient for repeated solving | + +**When to use each:** +```c++ +// Single solve: Use Gaussian elimination (simplest) +auto sol = imeth::Solver::gaussian_elimination(A, b); + +// Multiple solves: Use LU decomposition (most efficient) +for (const auto& b_vec : multiple_b_vectors) { + auto sol = imeth::Solver::lu_decomposition(A, b_vec); + // Process solution... +} + +// Educational purposes: Use Gauss-Jordan (easiest to understand steps) +auto sol = imeth::Solver::gauss_jordan(A, b); +``` + +--- + +## Complete Examples + +### Example 1: Traffic Flow Analysis ```c++ #include #include +#include int main() { - // Create a vector - imeth::Vector v = {1.0, 2.0, 3.0, 4.0}; - - std::cout << "Vector size: " << v.size() << "\n"; // 4 + // Traffic intersection with 4 roads + // Conservation law: flow in = flow out at each intersection + + // x1 + x2 = 100 (Intersection 1) + // x2 + x3 = 150 (Intersection 2) + // x3 + x4 = 80 (Intersection 3) + // x4 + x1 = 130 (Intersection 4) + + imeth::Matrix A = { + {1, 1, 0, 0}, + {0, 1, 1, 0}, + {0, 0, 1, 1}, + {1, 0, 0, 1} + }; + + imeth::Vector b = {100, 150, 80, 130}; + + imeth::Vector flow = imeth::Solver::gaussian_elimination(A, b); + + std::cout << std::fixed << std::setprecision(1); + std::cout << "Traffic Flow (vehicles/hour):\n"; + std::cout << "Road 1: " << flow[0] << "\n"; + std::cout << "Road 2: " << flow[1] << "\n"; + std::cout << "Road 3: " << flow[2] << "\n"; + std::cout << "Road 4: " << flow[3] << "\n"; + + return 0; +} +``` - // Access elements - std::cout << "v[0] = " << v[0] << "\n"; // 1.0 - std::cout << "v[2] = " << v[2] << "\n"; // 3.0 +--- - // Modify element - v[1] = 5.0; +### Example 2: 3D Graphics Transformation - // Create empty vector and fill it - imeth::Vector u(5); - for (size_t i = 0; i < u.size(); ++i) { - u[i] = i * 2.0; - } +```c++ +#include +#include +#include +int main() { + // Rotate a point (1, 0, 0) by 90° around Z-axis + + double angle = M_PI / 2; // 90 degrees in radians + + // 3D rotation matrix around Z-axis + imeth::Matrix rotation = { + {std::cos(angle), -std::sin(angle), 0}, + {std::sin(angle), std::cos(angle), 0}, + {0, 0, 1} + }; + + // Original point + imeth::Matrix point = { + {1}, + {0}, + {0} + }; + + // Apply rotation + imeth::Matrix rotated = rotation * point; + + std::cout << "Original point: (" << point(0,0) << ", " + << point(1,0) << ", " << point(2,0) << ")\n"; + + std::cout << "Rotated point: (" << rotated(0,0) << ", " + << rotated(1,0) << ", " << rotated(2,0) << ")\n"; + // Result: (0, 1, 0) - rotated 90° from X-axis to Y-axis + return 0; } ``` --- -## Solver +### Example 3: Chemical Equation Balancing -Provides numerical methods for solving systems of linear equations Ax = b, where A is a matrix, x is the unknown vector, and b is the result vector. +```c++ +#include +#include -### Methods +int main() { + // Balance: C₂H₆ + O₂ → CO₂ + H₂O + // Variables: a·C₂H₆ + b·O₂ → c·CO₂ + d·H₂O + + // Carbon: 2a = c + // Hydrogen: 6a = 2d + // Oxygen: 2b = 2c + d + // Constraint: a = 1 (normalize) + + imeth::Matrix A = { + {2, 0, -1, 0}, // Carbon balance + {6, 0, 0, -2}, // Hydrogen balance + {0, 2, -2, -1} // Oxygen balance + }; + + imeth::Vector b = {0, 0, 0}; + + // This system needs special handling for balancing + // (simplified example - real balancing is more complex) + + std::cout << "Balanced equation: 2C₂H₆ + 7O₂ → 4CO₂ + 6H₂O\n"; + + return 0; +} +``` -- `gaussian_elimination(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using Gaussian elimination with back substitution -- `gauss_jordan(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using Gauss-Jordan elimination (reduced row echelon form) -- `lu_decomposition(const Matrix& A, const Vector& b) → Vector` - Solves Ax = b using LU decomposition (factors A = LU) +--- -### Example Usage +### Example 4: Portfolio Optimization ```c++ #include #include +#include int main() { - // Solve the system: - // 2x + 3y = 8 - // x - y = 1 + // Allocate $10,000 across 3 investments + // Constraints: + // - Total investment = $10,000 + // - Expected return = 8% + // - Risk balance equation + + imeth::Matrix constraints = { + {1, 1, 1}, // x1 + x2 + x3 = 10000 + {0.05, 0.08, 0.12}, // Expected return + {1, -2, 1} // Risk balance + }; + + imeth::Vector targets = {10000, 800, 0}; + + imeth::Vector allocation = imeth::Solver::gauss_jordan(constraints, targets); + + std::cout << std::fixed << std::setprecision(2); + std::cout << "Portfolio Allocation:\n"; + std::cout << "Investment 1: $" << allocation[0] << "\n"; + std::cout << "Investment 2: $" << allocation[1] << "\n"; + std::cout << "Investment 3: $" << allocation[2] << "\n"; + + return 0; +} +``` - imeth::Matrix A = { - {2, 3}, - {1, -1} +--- + +### Example 5: Network Flow Problem + +```c++ +#include +#include + +int main() { + // Water distribution network + // 4 nodes, conservation of flow at each node + + imeth::Matrix network = { + {1, -1, 0, 0}, + {0, 1, -1, 0}, + {0, 0, 1, -1}, + {-1, 0, 0, 1} }; + + imeth::Vector supply = {50, 30, -40, -40}; + // Positive = source, Negative = sink + + imeth::Vector flow = imeth::Solver::lu_decomposition(network, supply); + + std::cout << "Pipe flows (liters/min):\n"; + for (size_t i = 0; i < flow.size(); ++i) { + std::cout << "Pipe " << (i+1) << ": " << flow[i] << "\n"; + } + + return 0; +} +``` - imeth::Vector b = {8, 1}; +--- - // Method 1: Gaussian elimination - imeth::Vector x1 = imeth::Solver::gaussian_elimination(A, b); - std::cout << "Solution (Gaussian): x = " << x1[0] << ", y = " << x1[1] << "\n"; +## Mathematical Properties - // Method 2: Gauss-Jordan - imeth::Vector x2 = imeth::Solver::gauss_jordan(A, b); - std::cout << "Solution (Gauss-Jordan): x = " << x2[0] << ", y = " << x2[1] << "\n"; +### Matrix Properties - // Method 3: LU decomposition - imeth::Vector x3 = imeth::Solver::lu_decomposition(A, b); - std::cout << "Solution (LU): x = " << x3[0] << ", y = " << x3[1] << "\n"; +**Transpose Properties:** +- (A^T)^T = A +- (A + B)^T = A^T + B^T +- (AB)^T = B^T A^T (order reverses!) +- (kA)^T = k(A^T) - return 0; +**Addition Properties:** +- Commutative: A + B = B + A +- Associative: (A + B) + C = A + (B + C) +- Identity: A + 0 = A +- Inverse: A + (-A) = 0 + +**Multiplication Properties:** +- Associative: (AB)C = A(BC) +- Distributive: A(B + C) = AB + AC +- Identity: AI = IA = A +- NOT commutative: AB ≠ BA (usually) + +**Identity Matrix Properties:** +- I · A = A · I = A +- I^n = I (any power) +- I^T = I (symmetric) +- det(I) = 1 + +--- + +## Common Pitfalls + +### 1. Dimension Mismatch in Operations + +```c++ +// ❌ WRONG - Cannot add matrices of different sizes +imeth::Matrix A(2, 3); +imeth::Matrix B(3, 2); +// auto C = A + B; // ERROR! Dimensions don't match + +// ✅ CORRECT - Check dimensions first +if (A.rows() == B.rows() && A.cols() == B.cols()) { + auto C = A + B; } ``` -### More Examples +### 2. Invalid Matrix Multiplication ```c++ -// Solve a 3×3 system: -// x + 2y + z = 6 -// 2x + y + z = 6 -// x + y + 2z = 7 +// ❌ WRONG - Columns of A must equal rows of B +imeth::Matrix A(2, 3); // 2×3 +imeth::Matrix B(4, 5); // 4×5 +// auto C = A * B; // ERROR! 3 ≠ 4 + +// ✅ CORRECT - Ensure dimensions match +imeth::Matrix A(2, 3); // 2×3 +imeth::Matrix B(3, 5); // 3×5 +auto C = A * B; // OK! Result is 2×5 +``` + +### 3. Confusing Indices + +```c++ +// ❌ WRONG - Indices start at 0, not 1 +imeth::Matrix M(3, 3); +// double val = M(3, 3); // ERROR! Valid range is (0,0) to (2,2) + +// ✅ CORRECT - Use 0-based indexing +double val = M(2, 2); // Last element +``` + +### 4. Assuming Matrix Multiplication is Commutative +```c++ +// ❌ WRONG ASSUMPTION - A*B ≠ B*A +imeth::Matrix A = {{1, 2}, {3, 4}}; +imeth::Matrix B = {{5, 6}, {7, 8}}; + +auto AB = A * B; // [[19, 22], [43, 50]] +auto BA = B * A; // [[23, 34], [31, 46]] +// AB ≠ BA! + +// ✅ CORRECT - Order matters in matrix multiplication +// Always multiply in the correct order +``` + +### 5. Forgetting to Check Solution Validity + +```c++ +// ❌ WRONG - Not all systems have solutions imeth::Matrix A = { - {1, 2, 1}, - {2, 1, 1}, - {1, 1, 2} + {1, 2}, + {2, 4} // Second row is 2× first row (linearly dependent) }; +imeth::Vector b = {3, 7}; +// auto sol = imeth::Solver::gaussian_elimination(A, b); +// This system has no solution or infinitely many! -imeth::Vector b = {6, 6, 7}; +// ✅ CORRECT - Check if system is solvable +// (This library doesn't provide built-in validation yet, +// but be aware of singular/ill-conditioned systems) +``` -imeth::Vector solution = imeth::Solver::gaussian_elimination(A, b); +### 6. Modifying Temporary Results -std::cout << "x = " << solution[0] << "\n"; // x = 1 -std::cout << "y = " << solution[1] << "\n"; // y = 2 -std::cout << "z = " << solution[2] << "\n"; // z = 2 +```c++ +// ❌ WRONG - Cannot modify temporary +// (A + B)(0, 0) = 5; // ERROR! (A+B) is temporary -// Verify solution: A * x = b -for (size_t i = 0; i < A.rows(); ++i) { - double result = 0; - for (size_t j = 0; j < A.cols(); ++j) { - result += A(i, j) * solution[j]; - } - std::cout << "Row " << i << " check: " << result << " = " << b[i] << "\n"; +// ✅ CORRECT - Store result first +imeth::Matrix C = A + B; +C(0, 0) = 5; // OK +``` + +--- + +## Performance Characteristics + +### Time Complexity + +**Matrix Operations:** +- Element access: O(1) +- Addition/Subtraction: O(mn) where m×n is matrix size +- Multiplication: O(mnp) for (m×n) × (n×p) matrices +- Transpose: O(mn) + +**Solver Methods:** +- Gaussian Elimination: O(n³) +- Gauss-Jordan: O(n³) +- LU Decomposition: O(n³) for factorization + O(n²) per solve + +### Space Complexity + +**Matrix Storage:** O(mn) for m×n matrix +**Vector Storage:** O(n) for size n vector +**Solver Intermediate:** O(n²) for working matrices + +### Optimization Tips + +```c++ +// Slow: Multiple temporary matrices +auto result = (A + B) * (C + D) * E; + +// Better: Minimize temporaries (though compiler may optimize) +auto temp1 = A + B; +auto temp2 = C + D; +auto temp3 = temp1 * temp2; +auto result = temp3 * E; + +// For repeated solves with same A: Use LU decomposition +// Factor once: O(n³) +// Solve many times: O(n²) each + +// Avoid unnecessary copies +const imeth::Matrix& ref = large_matrix; // Use reference +// auto copy = large_matrix; // Avoid copying if not needed +``` + +--- + +## Integration with Other Modules + +### With Algebra Module + +```c++ +#include +#include + +// Solve 2×2 system using both approaches +imeth::Matrix A = {{2, 3}, {1, -1}}; +imeth::Vector b = {8, 1}; + +// Method 1: Matrix solver +auto sol1 = imeth::Solver::gaussian_elimination(A, b); + +// Method 2: LinearAlgebra (for 2 variables only) +auto sol2 = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); + +if (sol2.has_value()) { + auto [x, y] = sol2.value(); + std::cout << "x = " << x << ", y = " << y << "\n"; } ``` -## Mathematical Background +### With Logarithm Module + +```c++ +#include +#include -**Matrix** - A rectangular array of numbers arranged in rows and columns. Matrices are used to represent linear transformations and systems of equations. +// Apply logarithmic transformation to matrix elements +imeth::Matrix data = { + {100, 1000}, + {10000, 100000} +}; -**Vector** - A one-dimensional array of numbers. In this context, it represents either the coefficients on the right side of equations (vector b) or the solution values (vector x). +imeth::Matrix log_data(data.rows(), data.cols()); -**System of Linear Equations** - Multiple equations like: +for (size_t i = 0; i < data.rows(); ++i) { + for (size_t j = 0; j < data.cols(); ++j) { + auto log_val = imeth::Logarithm::log10(data(i, j)); + if (log_val.has_value()) { + log_data(i, j) = log_val.value(); + } + } +} +// log_data = [[2, 3], +// [4, 5]] ``` -a₁₁x₁ + a₁₂x₂ + ... = b₁ -a₂₁x₁ + a₂₂x₂ + ... = b₂ -... + +--- + +## Tips and Best Practices + +### Matrix Operations +- **Always check dimensions** before operations +- **Use const references** for large matrices to avoid copying +- **Prefer specialized functions** (ln, log10) over general log when possible +- **Store intermediate results** if used multiple times +- **Use identity matrix** as baseline for transformations + +### Solving Systems +- **Choose the right solver** based on your use case +- **Gaussian elimination** for single solves +- **LU decomposition** for multiple solves with same coefficient matrix +- **Check solution** by substituting back into original equations +- **Be aware of singular matrices** (determinant = 0, no unique solution) + +### Code Organization +- **Validate inputs** before expensive computations +- **Use meaningful variable names** (coefficients, solution, not A, x) +- **Comment complex matrix operations** +- **Verify results** with test cases + +### Memory Management +- **Avoid unnecessary copies** of large matrices +- **Reuse matrices** when possible +- **Clear unused matrices** in long-running programs +- **Consider memory layout** for cache efficiency + +--- + +## Frequently Asked Questions + +**Q: What's the difference between a Matrix and a Vector?** +A: A Matrix is 2D (rows and columns), while a Vector is 1D (just elements). Mathematically, a vector is often represented as a column matrix (n×1), but this implementation treats them separately for efficiency. + +**Q: Why do matrix indices start at 0?** +A: Following C++ convention. Matrix(0, 0) is the top-left element. In mathematics, matrices often use 1-based indexing, but programming uses 0-based. + +**Q: Can I multiply matrices of any size?** +A: No. For A × B, the number of columns in A must equal the number of rows in B. A (m×n) matrix can only multiply a (n×p) matrix, giving an (m×p) result. + +**Q: Why is A × B ≠ B × A?** +A: Matrix multiplication represents composition of transformations, which depends on order. Also, A × B and B × A might not even have the same dimensions! + +**Q: Which solver method should I use?** +A: For single solves, use Gaussian elimination (simplest and efficient). For multiple solves with the same coefficient matrix, use LU decomposition. Use Gauss-Jordan mainly for educational purposes or when you need the matrix inverse. + +**Q: What happens if the system has no solution?** +A: The current implementation doesn't have built-in detection for singular or ill-conditioned matrices. It's the user's responsibility to ensure the system is solvable. Future versions may add validation. + +**Q: How do I create a zero matrix?** +A: Use the constructor: `imeth::Matrix zero(rows, cols);` - it initializes all elements to 0. + +**Q: Can I solve non-square systems (more/fewer equations than unknowns)?** +A: The current Solver class requires square matrices (n equations, n unknowns). For over/under-determined systems, you'd need least-squares or other specialized methods. + +**Q: How accurate are the solutions?** +A: Solutions are computed using double precision (~15-17 significant digits), but numerical stability depends on the condition number of the matrix. Ill-conditioned matrices may have large errors. + +**Q: What's the transpose used for?** +A: Converting between row and column vectors, computing dot products (A^T × B), symmetric matrix operations, and many matrix calculus operations. + +--- + +## Summary + +The Matrix module provides: +- ✅ **Matrix class**: 2D arrays with mathematical operations +- ✅ **Vector class**: 1D arrays for equation coefficients and solutions +- ✅ **Solver class**: Three methods for solving linear systems +- ✅ **Complete operations**: Addition, subtraction, multiplication, transpose +- ✅ **Efficient implementations**: O(n³) for solving, O(1) for access +- ✅ **Real-world ready**: Suitable for graphics, engineering, ML, and more + +**Quick Reference:** +```c++ +// Create matrices +imeth::Matrix A = {{1, 2}, {3, 4}}; +imeth::Matrix I = imeth::Matrix::identity(2); + +// Access elements +double val = A(0, 1); // 2 +A(1, 1) = 5; + +// Operations +imeth::Matrix sum = A + I; +imeth::Matrix diff = A - I; +imeth::Matrix product = A * I; +imeth::Matrix transposed = A.transpose(); + +// Create vectors +imeth::Vector v = {1, 2, 3}; +double element = v[0]; // 1 +v[2] = 5; + +// Solve systems: Ax = b +imeth::Vector x1 = imeth::Solver::gaussian_elimination(A, b); +imeth::Vector x2 = imeth::Solver::gauss_jordan(A, b); +imeth::Vector x3 = imeth::Solver::lu_decomposition(A, b); ``` -**Solving Methods:** -- **Gaussian Elimination** - Transforms the system to upper triangular form, then uses back substitution -- **Gauss-Jordan** - Reduces the matrix to reduced row echelon form (identity matrix) -- **LU Decomposition** - Factors matrix A into lower (L) and upper (U) triangular matrices +**Remember:** +- Matrix operations require compatible dimensions +- Indices start at 0 +- Matrix multiplication order matters (A×B ≠ B×A) +- Choose appropriate solver for your use case \ No newline at end of file From c551dc2a644cd4cbeb060260e01e7daf94de717d Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Wed, 12 Nov 2025 20:09:23 +0700 Subject: [PATCH 5/6] docs: update to algebra. --- docs/api/linear/algebra.md | 377 ++++++++++++++++++++++++++++--------- 1 file changed, 292 insertions(+), 85 deletions(-) diff --git a/docs/api/linear/algebra.md b/docs/api/linear/algebra.md index de4e834..b97066e 100644 --- a/docs/api/linear/algebra.md +++ b/docs/api/linear/algebra.md @@ -1,16 +1,17 @@ # Algebra -Ah, yes, algebra, my favorite subject. This chapter exists in the `linear` category and provides tools for solving linear equations, systems of linear equations, and quadratic equations. +The algebra chapter provides essential tools for solving linear and quadratic equations. This module is fundamental for mathematical computations involving equations with one or two variables, and quadratic problems. ```c++ #include ``` -## Classes +## Overview -The algebra module contains two main classes: -- **`LinearAlgebra`** - Solves linear equations and systems of linear equations -- **`QuadraticEquation`** - Solves quadratic equations using the quadratic formula +Algebra is the mathematics of solving equations. This module helps you answer questions like: +- "What value of x makes this equation true?" +- "Where do these two lines intersect?" +- "What are the roots of this quadratic equation?" --- @@ -18,151 +19,357 @@ The algebra module contains two main classes: Provides methods for solving linear equations in one or two variables. -### Features +### Single Variable Linear Equations -#### Single Variable Linear Equations -- `solve_1v(double a, double b) → std::optional` - Solves ax + b = 0 for x - - Returns `std::nullopt` if no solution exists (when a = 0 and b ≠ 0) +```c++ +static std::optional solve_1v(double a, double b); +``` -#### System of Two Linear Equations -- `solve_2v(double a1, double b1, double c1, double a2, double b2, double c2) → std::optional>` - Solves the system: - ``` - a1·x + b1·y = c1 - a2·x + b2·y = c2 - ``` - - Returns `std::pair` containing (x, y) if a unique solution exists - - Returns `std::nullopt` if the system has no solution or infinitely many solutions +Solves equations of the form ax + b = 0 for x. -### Example Usage +**Formula:** x = -b/a (when a ≠ 0) +**Examples:** ```c++ -#include -#include +// Solve: 2x + 6 = 0 +auto result = imeth::LinearAlgebra::solve_1v(2, 6); +if (result.has_value()) { + std::cout << "x = " << result.value() << "\n"; // x = -3 +} -int main() { - // Solve: 2x + 6 = 0 - auto result = imeth::LinearAlgebra::solve_1v(2, 6); - if (result.has_value()) { - std::cout << "x = " << result.value() << "\n"; // x = -3 - } +// Solve: 5x - 15 = 0 +auto x = imeth::LinearAlgebra::solve_1v(5, -15); // x = 3 - // Solve system: - // 2x + 3y = 8 - // x - y = 1 - auto system = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); - if (system.has_value()) { - auto [x, y] = system.value(); - std::cout << "x = " << x << ", y = " << y << "\n"; // x = 2.2, y = 1.2 - } +// No solution case: 0x + 5 = 0 +auto no_solution = imeth::LinearAlgebra::solve_1v(0, 5); +if (!no_solution.has_value()) { + std::cout << "No solution exists\n"; +} +``` - return 0; +**Real-world:** +- Simple cost equations: "If total cost = 2x + 6, when is cost zero?" +- Distance problems: "At what time does position equal zero?" +- Break-even analysis + +**Returns:** `std::optional` containing the solution, or `std::nullopt` if no solution exists (when a = 0 and b ≠ 0) + +--- + +### System of Two Linear Equations + +```c++ +static std::optional> solve_2v( + double a1, double b1, double c1, + double a2, double b2, double c2 +); +``` + +Solves systems of two linear equations with two variables: +``` +a1·x + b1·y = c1 +a2·x + b2·y = c2 +``` + +**Examples:** +```c++ +// Solve system: +// 2x + 3y = 8 +// x - y = 1 +auto system = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); +if (system.has_value()) { + auto [x, y] = system.value(); + std::cout << "x = " << x << ", y = " << y << "\n"; // x = 2.2, y = 1.2 +} + +// Solve system: +// 3x + 2y = 7 +// 2x + y = 4 +auto result = imeth::LinearAlgebra::solve_2v(3, 2, 7, 2, 1, 4); // x = 1, y = 2 + +// Parallel lines (no solution) +// x + y = 1 +// x + y = 2 +auto parallel = imeth::LinearAlgebra::solve_2v(1, 1, 1, 1, 1, 2); +if (!parallel.has_value()) { + std::cout << "No solution (parallel lines)\n"; +} + +// Infinite solutions (same line) +// 2x + 4y = 6 +// x + 2y = 3 +auto infinite = imeth::LinearAlgebra::solve_2v(2, 4, 6, 1, 2, 3); +if (!infinite.has_value()) { + std::cout << "Infinite solutions (same line)\n"; } ``` +**Real-world:** +- Finding intersection points of two lines +- Supply and demand equilibrium +- Mixture problems (two unknowns) +- Resource allocation with constraints + +**Returns:** `std::optional>` containing (x, y) if a unique solution exists, or `std::nullopt` if the system has no solution or infinitely many solutions + --- ## QuadraticEquation Solves quadratic equations of the form ax² + bx + c = 0 using the quadratic formula. -### Features +### Solution Type -#### Solution Type ```c++ using Solution = std::variant>; ``` -The `Solution` type can represent three possible outcomes: +The `Solution` type represents three possible outcomes: - `std::monostate` - No real solutions (complex roots, discriminant < 0) - `double` - One solution / repeated root (discriminant = 0) -- `std::pair` - Two distinct real solutions (discriminant > 0), where first ≤ second +- `std::pair` - Two distinct real solutions (discriminant > 0), ordered ascending -#### Solving Quadratic Equations -- `solve(double a, double b, double c) → Solution` - Solves ax² + bx + c = 0 - - Uses the quadratic formula: x = (-b ± √(b² - 4ac)) / 2a - - Handles degenerate cases (when a = 0, reduces to linear equation) - - Returns solutions in ascending order when two solutions exist +--- -### Example Usage +### Solving Quadratic Equations ```c++ -#include -#include -#include +static Solution solve(double a, double b, double c); +``` -int main() { - // Solve: x² - 5x + 6 = 0 - // Factors as: (x - 2)(x - 3) = 0 - auto result = imeth::QuadraticEquation::solve(1, -5, 6); - - if (std::holds_alternative>(result)) { - auto [x1, x2] = std::get>(result); - std::cout << "Two solutions: x1 = " << x1 << ", x2 = " << x2 << "\n"; - // Output: x1 = 2, x2 = 3 - } - else if (std::holds_alternative(result)) { - double x = std::get(result); - std::cout << "One solution: x = " << x << "\n"; - } - else { - std::cout << "No real solutions (complex roots)\n"; - } +Solves equations of the form ax² + bx + c = 0. - return 0; +**Formula:** x = (-b ± √(b² - 4ac)) / 2a + +**Discriminant:** Δ = b² - 4ac +- Δ > 0: Two distinct real roots +- Δ = 0: One repeated root +- Δ < 0: Two complex conjugate roots (no real solutions) + +**Examples:** + +#### Two Distinct Solutions +```c++ +// Solve: x² - 5x + 6 = 0 +// Factors as: (x - 2)(x - 3) = 0 +auto result = imeth::QuadraticEquation::solve(1, -5, 6); + +if (std::holds_alternative>(result)) { + auto [x1, x2] = std::get>(result); + std::cout << "Two solutions: x1 = " << x1 << ", x2 = " << x2 << "\n"; + // Output: x1 = 2, x2 = 3 } -``` -### More Examples +// Solve: x² - 7x + 10 = 0 +auto roots = imeth::QuadraticEquation::solve(1, -7, 10); // x1 = 2, x2 = 5 +// Solve: 2x² + 5x - 3 = 0 +auto result2 = imeth::QuadraticEquation::solve(2, 5, -3); // x1 = -3, x2 = 0.5 +``` + +#### One Repeated Root ```c++ -// Repeated root (discriminant = 0) -// Solve: x² - 4x + 4 = 0 → (x - 2)² = 0 +// Solve: x² - 4x + 4 = 0 +// Factors as: (x - 2)² = 0 auto repeated = imeth::QuadraticEquation::solve(1, -4, 4); + if (std::holds_alternative(repeated)) { double x = std::get(repeated); std::cout << "Repeated root: x = " << x << "\n"; // x = 2 } -// No real solutions (discriminant < 0) +// Solve: x² + 6x + 9 = 0 → (x + 3)² = 0 +auto root = imeth::QuadraticEquation::solve(1, 6, 9); // x = -3 +``` + +#### No Real Solutions +```c++ // Solve: x² + x + 1 = 0 auto no_real = imeth::QuadraticEquation::solve(1, 1, 1); + if (std::holds_alternative(no_real)) { - std::cout << "No real solutions\n"; + std::cout << "No real solutions (complex roots)\n"; } -// Negative leading coefficient -// Solve: -x² + 4x - 3 = 0 → x² - 4x + 3 = 0 +// Solve: x² + 4x + 5 = 0 +auto complex = imeth::QuadraticEquation::solve(1, 4, 5); // No real roots +``` + +#### Negative Leading Coefficient +```c++ +// Solve: -x² + 4x - 3 = 0 +// Equivalent to: x² - 4x + 3 = 0 auto negative_a = imeth::QuadraticEquation::solve(-1, 4, -3); + if (std::holds_alternative>(negative_a)) { auto [x1, x2] = std::get>(negative_a); std::cout << "x1 = " << x1 << ", x2 = " << x2 << "\n"; // x1 = 1, x2 = 3 } +``` -// Working with LinearAlgebra and QuadraticEquation together -// Check if a value is a solution +#### Degenerate Case (Linear Equation) +```c++ +// When a = 0, equation becomes linear: bx + c = 0 +// Solve: 0x² + 3x - 6 = 0 → 3x - 6 = 0 +auto linear = imeth::QuadraticEquation::solve(0, 3, -6); // x = 2 +``` + +--- + +### Verification and Usage + +```c++ +// Verify a solution auto solutions = imeth::QuadraticEquation::solve(1, -3, 2); if (std::holds_alternative>(solutions)) { auto [x1, x2] = std::get>(solutions); + // Verify: x² - 3x + 2 = 0 when x = x1 double check = x1 * x1 - 3 * x1 + 2; std::cout << "Verification: " << check << "\n"; // ≈ 0 + + // Check second root + double check2 = x2 * x2 - 3 * x2 + 2; + std::cout << "Verification: " << check2 << "\n"; // ≈ 0 +} + +// Pattern matching all solution types +auto result = imeth::QuadraticEquation::solve(2, -4, 2); +if (std::holds_alternative>(result)) { + auto [x1, x2] = std::get>(result); + std::cout << "Two solutions: " << x1 << ", " << x2 << "\n"; +} +else if (std::holds_alternative(result)) { + double x = std::get(result); + std::cout << "One solution: " << x << "\n"; +} +else { + std::cout << "No real solutions\n"; +} +``` + +**Real-world:** +- Projectile motion (height vs. time) +- Area and optimization problems +- Physics problems (acceleration, velocity) +- Economics (profit maximization) +- Engineering (beam deflection, circuit analysis) + +**Returns:** +- `std::monostate` if no real solutions exist +- `double` if one repeated root exists +- `std::pair` if two distinct solutions exist (ordered ascending) + +--- + +## Complete Example + +```c++ +#include +#include +#include + +int main() { + using namespace imeth; + + // Single variable linear equation + std::cout << "=== Linear Equation (1 variable) ===\n"; + auto linear1 = LinearAlgebra::solve_1v(2, 6); + if (linear1.has_value()) { + std::cout << "2x + 6 = 0, x = " << linear1.value() << "\n"; // x = -3 + } + + // System of linear equations + std::cout << "\n=== System of Linear Equations ===\n"; + auto system = LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); + if (system.has_value()) { + auto [x, y] = system.value(); + std::cout << "System solution: x = " << x << ", y = " << y << "\n"; + } + + // Quadratic with two solutions + std::cout << "\n=== Quadratic Equations ===\n"; + auto quad1 = QuadraticEquation::solve(1, -5, 6); + if (std::holds_alternative>(quad1)) { + auto [x1, x2] = std::get>(quad1); + std::cout << "x² - 5x + 6 = 0: x1 = " << x1 << ", x2 = " << x2 << "\n"; + } + + // Quadratic with repeated root + auto quad2 = QuadraticEquation::solve(1, -4, 4); + if (std::holds_alternative(quad2)) { + double x = std::get(quad2); + std::cout << "x² - 4x + 4 = 0: x = " << x << " (repeated)\n"; + } + + // Quadratic with no real solutions + auto quad3 = QuadraticEquation::solve(1, 1, 1); + if (std::holds_alternative(quad3)) { + std::cout << "x² + x + 1 = 0: No real solutions\n"; + } + + // Real-world problem: Projectile motion + std::cout << "\n=== Projectile Motion Example ===\n"; + // Height equation: h(t) = -4.9t² + 20t + 2 + // Find when projectile hits ground (h = 0) + auto time = QuadraticEquation::solve(-4.9, 20, 2); + if (std::holds_alternative>(time)) { + auto [t1, t2] = std::get>(time); + std::cout << "Projectile hits ground at t = " << t2 << " seconds\n"; + } + + return 0; } ``` +--- + +## Tips + +- **Linear vs Quadratic**: Linear equations have at most one solution; quadratic equations can have 0, 1, or 2 real solutions +- **Check for nullopt**: Always verify `has_value()` before accessing `std::optional` results +- **Discriminant**: For quadratics, check discriminant (b² - 4ac) to predict number of solutions before solving +- **Solution Order**: When two solutions exist, they're always returned in ascending order (smaller first) +- **Degenerate Cases**: Handle edge cases where a = 0 (linear instead of quadratic) +- **Verification**: Test solutions by substituting back into original equation + +--- + +## Quick Reference + +| Problem Type | Function | Example Use Case | +|-------------|----------|------------------| +| Linear (1 var) | `LinearAlgebra::solve_1v(a, b)` | Cost equations, simple physics | +| Linear system | `LinearAlgebra::solve_2v(...)` | Line intersections, supply/demand | +| Quadratic | `QuadraticEquation::solve(a, b, c)` | Projectile motion, area problems | + +| Discriminant | Result Type | Meaning | +|--------------|-------------|---------| +| Δ > 0 | `std::pair` | Two distinct real roots | +| Δ = 0 | `double` | One repeated root | +| Δ < 0 | `std::monostate` | No real roots (complex) | + +--- + ## Mathematical Background ### Linear Equations (1 variable) -- Form: ax + b = 0 -- Solution: x = -b/a (when a ≠ 0) +- **Form:** ax + b = 0 +- **Solution:** x = -b/a (when a ≠ 0) +- **No solution when:** a = 0 and b ≠ 0 ### System of Linear Equations (2 variables) -- Uses elimination or substitution methods -- Determines if system has unique solution, no solution, or infinite solutions +- **Form:** Two equations with two unknowns +- **Methods:** Elimination, substitution, matrix methods +- **Unique solution when:** Lines intersect at one point +- **No solution when:** Lines are parallel +- **Infinite solutions when:** Lines coincide (same line) ### Quadratic Equations -- Form: ax² + bx + c = 0 -- Discriminant: Δ = b² - 4ac +- **Form:** ax² + bx + c = 0 +- **Quadratic Formula:** x = (-b ± √Δ) / 2a +- **Discriminant:** Δ = b² - 4ac - Δ > 0: Two distinct real roots - - Δ = 0: One repeated root - - Δ < 0: Two complex conjugate roots (no real solutions) -- Quadratic formula: x = (-b ± √Δ) / 2a + - Δ = 0: One repeated root (perfect square) + - Δ < 0: Two complex conjugate roots +- **Factored Form:** a(x - r₁)(x - r₂) = 0, where r₁ and r₂ are roots \ No newline at end of file From 0ffb71d5dea23911e29b348613c4b97a01c51224 Mon Sep 17 00:00:00 2001 From: lordpaijo Date: Wed, 12 Nov 2025 20:09:55 +0700 Subject: [PATCH 6/6] docs: update to matrix (shortenings). --- docs/api/linear/matrix.md | 1271 ++++++------------------------------- 1 file changed, 195 insertions(+), 1076 deletions(-) diff --git a/docs/api/linear/matrix.md b/docs/api/linear/matrix.md index 21a76bd..0106db7 100644 --- a/docs/api/linear/matrix.md +++ b/docs/api/linear/matrix.md @@ -1,6 +1,6 @@ # Matrix -Matrix is a chapter from the `linear` category. It provides classes and methods for linear algebra operations, including matrix manipulation, vector operations, and solving systems of linear equations. Matrices are fundamental mathematical structures used to represent linear transformations, organize data, and solve complex systems of equations. +The matrix chapter provides classes and methods for linear algebra operations, including matrix manipulation, vector operations, and solving systems of linear equations. ```c++ #include @@ -8,32 +8,31 @@ Matrix is a chapter from the `linear` category. It provides classes and methods ## Overview -Think of matrices as rectangular grids of numbers that can represent: -- **Systems of equations**: Multiple equations with multiple unknowns -- **Transformations**: Rotations, scaling, shearing in graphics and physics -- **Data tables**: Organizing related information in rows and columns -- **Networks**: Connections between nodes (adjacency matrices) +Matrices are rectangular grids of numbers that represent: +- Systems of equations with multiple unknowns +- Transformations (rotations, scaling) in graphics and physics +- Data tables and organized information +- Network connections (adjacency matrices) This module helps you solve problems like: - "I have 3 equations with 3 unknowns - what are the solutions?" - "How do I rotate a 3D object in space?" -- "What's the result of applying multiple transformations in sequence?" -- "How do I organize and compute with tabular data efficiently?" +- "What's the result of applying multiple transformations?" --- ## Classes Overview The matrix module contains three main classes: -- **Matrix** - Represents a 2D matrix with mathematical operations -- **Vector** - Represents a mathematical vector (1D array of numbers) -- **Solver** - Provides methods for solving systems of linear equations +- **Matrix** - 2D matrix with mathematical operations +- **Vector** - 1D array of numbers +- **Solver** - Methods for solving systems of linear equations --- ## Matrix Class -A Matrix is a rectangular array of numbers arranged in rows and columns. Think of it as a spreadsheet where each cell contains a number, and you can perform mathematical operations on entire rows, columns, or the whole grid at once. +A rectangular array of numbers arranged in rows and columns. ### Constructors @@ -42,40 +41,22 @@ Matrix(size_t rows, size_t cols); Matrix(std::initializer_list> data); ``` -Creates a matrix with specified dimensions or from initial data. - **Examples:** ```c++ -// Create a 3×4 matrix initialized to zero +// Create 3×4 zero matrix imeth::Matrix A(3, 4); -// A = [[0, 0, 0, 0], -// [0, 0, 0, 0], -// [0, 0, 0, 0]] -// Create a 2×3 matrix with initial values +// Create matrix with values imeth::Matrix B = { {1, 2, 3}, {4, 5, 6} }; -// B = [[1, 2, 3], -// [4, 5, 6]] - -// Create a 2×2 matrix -imeth::Matrix C = { - {1.5, 2.7}, - {3.2, 4.8} -}; -// Create a single-row matrix (1×4) +// Single-row matrix imeth::Matrix row = {{1, 2, 3, 4}}; -// Create a single-column matrix (4×1) -imeth::Matrix col = { - {1}, - {2}, - {3}, - {4} -}; +// Single-column matrix +imeth::Matrix col = {{1}, {2}, {3}, {4}}; ``` --- @@ -87,9 +68,7 @@ double& operator()(size_t r, size_t c); double operator()(size_t r, size_t c) const; ``` -Accesses or modifies elements at specified row and column positions. - -**Important:** Matrix indexing starts at 0. A 3×3 matrix has valid indices from (0,0) to (2,2). +Access or modify elements at row r, column c (0-indexed). **Examples:** ```c++ @@ -99,41 +78,23 @@ imeth::Matrix M = { {7, 8, 9} }; -// Read elements (const access) -double val1 = M(0, 0); // 1 (top-left) -double val2 = M(1, 1); // 5 (center) -double val3 = M(2, 2); // 9 (bottom-right) -double val4 = M(0, 2); // 3 (top-right) - -// Modify elements -M(0, 0) = 10; // Change top-left to 10 -M(1, 1) = 20; // Change center to 20 -M(2, 2) = 30; // Change bottom-right to 30 +double val = M(0, 0); // 1 (top-left) +M(1, 1) = 20; // Modify center -// M is now: -// [[10, 2, 3], -// [4, 20, 6], -// [7, 8, 30]] - -// Access in loops +// Loop through elements for (size_t i = 0; i < M.rows(); ++i) { for (size_t j = 0; j < M.cols(); ++j) { std::cout << M(i, j) << " "; } - std::cout << "\n"; } -// Set diagonal elements +// Set diagonal to 1 for (size_t i = 0; i < std::min(M.rows(), M.cols()); ++i) { M(i, i) = 1.0; } ``` -**Real-world applications:** -- Image processing: Access and modify pixel values -- Game development: Update transformation matrices -- Data analysis: Access specific data points in tables -- Scientific computing: Iterate through matrix elements +**Real-world:** Image processing, data analysis, game transformations --- @@ -144,153 +105,70 @@ size_t rows() const; size_t cols() const; ``` -Returns the dimensions of the matrix. - **Examples:** ```c++ -imeth::Matrix A = { - {1, 2, 3, 4}, - {5, 6, 7, 8} -}; - -size_t num_rows = A.rows(); // 2 -size_t num_cols = A.cols(); // 4 -size_t total_elements = A.rows() * A.cols(); // 8 - -// Check if matrix is square -bool is_square = (A.rows() == A.cols()); // false - -// Check if matrix is a vector -bool is_row_vector = (A.rows() == 1); // false -bool is_col_vector = (A.cols() == 1); // false +imeth::Matrix A(3, 4); +size_t r = A.rows(); // 3 +size_t c = A.cols(); // 4 -// Validate dimensions for operations -imeth::Matrix B(3, 4); -bool can_add = (A.rows() == B.rows() && A.cols() == B.cols()); // false +// Check if square +bool is_square = (A.rows() == A.cols()); -imeth::Matrix C(4, 5); -bool can_multiply = (A.cols() == C.rows()); // true (2×4 · 4×5 = 2×5) +// Validate operations +bool can_multiply = (A.cols() == B.rows()); ``` -**Real-world applications:** -- Validating matrix operations before computation -- Allocating memory for result matrices -- Checking compatibility in neural network layers -- Ensuring data table dimensions match - --- -### Static Methods +### Identity Matrix ```c++ static Matrix identity(size_t n); ``` -Creates an n×n identity matrix - a square matrix with 1s on the diagonal and 0s elsewhere. - -**Formula:** I[i][j] = (i == j) ? 1 : 0 +Creates n×n identity matrix with 1s on diagonal, 0s elsewhere. **Examples:** ```c++ -// Create 3×3 identity matrix imeth::Matrix I3 = imeth::Matrix::identity(3); -// I3 = [[1, 0, 0], -// [0, 1, 0], -// [0, 0, 1]] - -// Create 4×4 identity matrix -imeth::Matrix I4 = imeth::Matrix::identity(4); -// I4 = [[1, 0, 0, 0], -// [0, 1, 0, 0], -// [0, 0, 1, 0], -// [0, 0, 0, 1]] - -// Create 2×2 identity matrix -imeth::Matrix I2 = imeth::Matrix::identity(2); -// I2 = [[1, 0], -// [0, 1]] +// [[1, 0, 0], +// [0, 1, 0], +// [0, 0, 1]] -// Identity matrix property: I × A = A × I = A -imeth::Matrix A = { - {2, 3}, - {4, 5} -}; -imeth::Matrix result = I2 * A; // result equals A - -// Create 1×1 identity (just [1]) -imeth::Matrix I1 = imeth::Matrix::identity(1); // [[1]] +// Identity property: I × A = A × I = A +imeth::Matrix A = {{2, 3}, {4, 5}}; +imeth::Matrix I2 = imeth::Matrix::identity(2); +imeth::Matrix result = I2 * A; // equals A ``` -**Why identity matrices are important:** -- **Neutral element**: Multiplying by identity doesn't change the matrix (like multiplying by 1) -- **Starting point**: Used as initial transformation in graphics -- **Diagonal matrices**: Identity is the simplest diagonal matrix -- **Inverse checking**: If A × B = I, then B is the inverse of A - -**Real-world applications:** -- 3D graphics: Default transformation matrix -- Control systems: Baseline system response -- Linear algebra: Checking matrix inverses -- Neural networks: Initialization strategy -- Image processing: No-change filter +**Real-world:** Default transformations, checking matrix inverses, initialization --- -### Matrix Operations - -#### Transpose +### Transpose ```c++ Matrix transpose() const; ``` -Returns a new matrix with rows and columns swapped. +Returns matrix with rows and columns swapped. -**Formula:** If A is m×n, then A^T is n×m where A^T[i][j] = A[j][i] +**Formula:** A^T[i][j] = A[j][i] **Examples:** ```c++ -// Transpose a 2×3 matrix imeth::Matrix A = { {1, 2, 3}, {4, 5, 6} -}; +}; // 2×3 imeth::Matrix A_T = A.transpose(); -// A_T = [[1, 4], -// [2, 5], -// [3, 6]] (3×2) - -// Transpose changes dimensions -std::cout << "A: " << A.rows() << "×" << A.cols() << "\n"; // 2×3 -std::cout << "A_T: " << A_T.rows() << "×" << A_T.cols() << "\n"; // 3×2 - -// Transpose of square matrix -imeth::Matrix B = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; - -imeth::Matrix B_T = B.transpose(); -// B_T = [[1, 4, 7], -// [2, 5, 8], -// [3, 6, 9]] - -// Symmetric matrix: A = A^T -imeth::Matrix S = { - {1, 2, 3}, - {2, 4, 5}, - {3, 5, 6} -}; -imeth::Matrix S_T = S.transpose(); // S_T equals S +// [[1, 4], +// [2, 5], +// [3, 6]] (3×2) // Column vector to row vector -imeth::Matrix col = { - {1}, - {2}, - {3} -}; +imeth::Matrix col = {{1}, {2}, {3}}; imeth::Matrix row = col.transpose(); // {{1, 2, 3}} // Double transpose returns original @@ -298,282 +176,126 @@ imeth::Matrix original = A.transpose().transpose(); // equals A ``` **Properties:** -- (A^T)^T = A (transpose twice returns original) +- (A^T)^T = A - (A + B)^T = A^T + B^T -- (AB)^T = B^T A^T (order reverses!) -- (kA)^T = k(A^T) where k is a scalar +- (AB)^T = B^T A^T -**Real-world applications:** -- Converting between row and column vectors -- Matrix calculus: Gradient computations -- Statistics: Covariance matrix calculations -- Data science: Reshaping data tables -- Linear algebra: Computing dot products -- Graphics: Converting between coordinate systems +**Real-world:** Converting vector formats, matrix calculus, covariance matrices --- -#### Matrix Addition +### Addition ```c++ Matrix operator+(const Matrix& rhs) const; ``` -Adds two matrices element-wise. Matrices must have the same dimensions. - -**Formula:** If C = A + B, then C[i][j] = A[i][j] + B[i][j] +Element-wise addition. Matrices must have same dimensions. **Examples:** ```c++ -// Add two 2×2 matrices -imeth::Matrix A = { - {1, 2}, - {3, 4} -}; - -imeth::Matrix B = { - {5, 6}, - {7, 8} -}; +imeth::Matrix A = {{1, 2}, {3, 4}}; +imeth::Matrix B = {{5, 6}, {7, 8}}; imeth::Matrix C = A + B; -// C = [[6, 8], -// [10, 12]] - -// Add 3×3 matrices -imeth::Matrix M1 = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; - -imeth::Matrix M2 = { - {9, 8, 7}, - {6, 5, 4}, - {3, 2, 1} -}; - -imeth::Matrix sum = M1 + M2; -// sum = [[10, 10, 10], -// [10, 10, 10], -// [10, 10, 10]] +// [[6, 8], +// [10, 12]] // Add identity to diagonal imeth::Matrix I = imeth::Matrix::identity(2); imeth::Matrix result = A + I; -// result = [[2, 2], // A + I increases diagonal by 1 -// [3, 5]] +// [[2, 2], +// [3, 5]] -// Chain multiple additions +// Chain additions imeth::Matrix total = A + B + C; - -// Add with zero matrix (no change) -imeth::Matrix zero(2, 2); // All zeros -imeth::Matrix unchanged = A + zero; // equals A ``` -**Properties:** -- Commutative: A + B = B + A -- Associative: (A + B) + C = A + (B + C) -- Identity: A + 0 = A (0 is zero matrix) -- Inverse: A + (-A) = 0 - -**Real-world applications:** -- Image processing: Combining multiple images -- Physics simulations: Summing force matrices -- Statistics: Aggregating data tables -- Economics: Combining input-output tables -- Signal processing: Adding multiple signals +**Properties:** Commutative, associative, A + 0 = A + +**Real-world:** Image blending, summing force matrices, aggregating data --- -#### Matrix Subtraction +### Subtraction ```c++ Matrix operator-(const Matrix& rhs) const; ``` -Subtracts two matrices element-wise. Matrices must have the same dimensions. - -**Formula:** If C = A - B, then C[i][j] = A[i][j] - B[i][j] +Element-wise subtraction. Matrices must have same dimensions. **Examples:** ```c++ -// Subtract two 2×2 matrices -imeth::Matrix A = { - {5, 6}, - {7, 8} -}; - -imeth::Matrix B = { - {1, 2}, - {3, 4} -}; +imeth::Matrix A = {{5, 6}, {7, 8}}; +imeth::Matrix B = {{1, 2}, {3, 4}}; imeth::Matrix C = A - B; -// C = [[4, 4], -// [4, 4]] - -// Subtract from identity -imeth::Matrix I = imeth::Matrix::identity(3); -imeth::Matrix M = { - {1, 2, 3}, - {4, 5, 6}, - {7, 8, 9} -}; - -imeth::Matrix diff = I - M; -// diff = [[0, -2, -3], -// [-4, -4, -6], -// [-7, -8, -8]] +// [[4, 4], +// [4, 4]] -// Calculate difference matrix +// Calculate change imeth::Matrix original = {{10, 20}, {30, 40}}; imeth::Matrix modified = {{12, 18}, {32, 38}}; imeth::Matrix change = modified - original; -// change = [[2, -2], -// [2, -2]] -// Subtract from itself (creates zero matrix) +// Subtract from itself imeth::Matrix zero = A - A; // All zeros - -// Order matters: A - B ≠ B - A -imeth::Matrix diff1 = A - B; // [[4, 4], [4, 4]] -imeth::Matrix diff2 = B - A; // [[-4, -4], [-4, -4]] ``` -**Properties:** -- Not commutative: A - B ≠ B - A (usually) -- A - A = 0 (zero matrix) -- A - 0 = A -- A - B = A + (-B) - -**Real-world applications:** -- Image processing: Finding differences between frames -- Error calculation: Expected vs actual values -- Change detection: Comparing states over time -- Residual analysis: Observed minus predicted -- Calibration: Removing systematic errors +**Real-world:** Frame differences in video, error calculation, change detection --- -#### Matrix Multiplication +### Multiplication ```c++ Matrix operator*(const Matrix& rhs) const; ``` -Multiplies two matrices using the dot product of rows and columns. +Matrix multiplication using dot product of rows and columns. -**Important:** For A × B to be valid, the number of columns in A must equal the number of rows in B. +**Rule:** A.cols() must equal B.rows() for A × B -**Formula:** If C = A × B where A is m×n and B is n×p, then C is m×p and: -C[i][j] = Σ(A[i][k] × B[k][j]) for k from 0 to n-1 +**Formula:** C[i][j] = Σ(A[i][k] × B[k][j]) **Examples:** ```c++ -// Multiply 2×2 matrices -imeth::Matrix A = { - {1, 2}, - {3, 4} -}; - -imeth::Matrix B = { - {5, 6}, - {7, 8} -}; +imeth::Matrix A = {{1, 2}, {3, 4}}; +imeth::Matrix B = {{5, 6}, {7, 8}}; imeth::Matrix C = A * B; // C[0][0] = 1×5 + 2×7 = 19 // C[0][1] = 1×6 + 2×8 = 22 -// C[1][0] = 3×5 + 4×7 = 43 -// C[1][1] = 3×6 + 4×8 = 50 -// C = [[19, 22], -// [43, 50]] - -// Multiply 2×3 and 3×2 matrices (result is 2×2) -imeth::Matrix D = { - {1, 2, 3}, - {4, 5, 6} -}; // 2×3 +// [[19, 22], +// [43, 50]] -imeth::Matrix E = { - {7, 8}, - {9, 10}, - {11, 12} -}; // 3×2 +// Multiply 2×3 and 3×2 → 2×2 +imeth::Matrix D = {{1, 2, 3}, {4, 5, 6}}; +imeth::Matrix E = {{7, 8}, {9, 10}, {11, 12}}; +imeth::Matrix F = D * E; // [[58, 64], [139, 154]] -imeth::Matrix F = D * E; // 2×2 -// F = [[58, 64], -// [139, 154]] - -// Multiply by identity (no change) +// Identity property imeth::Matrix I = imeth::Matrix::identity(2); imeth::Matrix unchanged = A * I; // equals A -imeth::Matrix also_unchanged = I * A; // equals A - -// Chain multiplications -imeth::Matrix result = A * B * I; // equals A * B -// Square matrix powers +// Matrix powers imeth::Matrix A_squared = A * A; -imeth::Matrix A_cubed = A * A * A; - -// Non-square multiplication -imeth::Matrix tall = { - {1, 2}, - {3, 4}, - {5, 6} -}; // 3×2 - -imeth::Matrix wide = { - {1, 2, 3}, - {4, 5, 6} -}; // 2×3 - -imeth::Matrix product1 = tall * wide; // 3×3 (valid) -// product1 = [[9, 12, 15], -// [19, 26, 33], -// [29, 40, 51]] - -imeth::Matrix product2 = wide * tall; // 2×2 (valid) -// product2 = [[22, 28], -// [49, 64]] - -// Note: tall * wide ≠ wide * tall (different dimensions!) ``` **Properties:** -- Not commutative: A × B ≠ B × A (usually) -- Associative: (A × B) × C = A × (B × C) -- Distributive: A × (B + C) = A × B + A × C -- Identity: I × A = A × I = A +- NOT commutative: A × B ≠ B × A +- Associative: (AB)C = A(BC) +- Distributive: A(B + C) = AB + AC - Dimension rule: (m×n) × (n×p) = (m×p) -**Real-world applications:** -- **3D Graphics**: Combining transformations (rotation, scaling, translation) -- **Neural Networks**: Computing layer outputs (weights × inputs) -- **Physics**: Transforming coordinate systems -- **Economics**: Input-output analysis (Leontief models) -- **Cryptography**: Encryption algorithms -- **Quantum Computing**: Gate operations -- **Image Processing**: Applying filters and transformations -- **Robotics**: Forward and inverse kinematics - -**Why multiplication is complex:** -Matrix multiplication represents composition of linear transformations. When you multiply matrices, you're applying one transformation after another, which is why the order matters and the operation is more complex than element-wise operations. +**Real-world:** 3D graphics transformations, neural networks, coordinate systems --- ## Vector Class -A Vector is a one-dimensional array of numbers. In mathematical terms, it's typically a column vector, but this implementation focuses on efficient storage and access rather than explicit orientation. - -**Think of vectors as:** -- A list of numbers representing a point in space -- The coefficients in an equation -- A column or row in a data table -- A sequence of measurements +One-dimensional array of numbers. ### Constructors @@ -582,46 +304,24 @@ Vector(size_t n); Vector(std::initializer_list data); ``` -Creates a vector of specified size or from initial values. - **Examples:** ```c++ -// Create a vector of size 5 (initialized to zero) +// Size 5, initialized to zero imeth::Vector v1(5); -// v1 = [0, 0, 0, 0, 0] -// Create a vector with initial values +// With initial values imeth::Vector v2 = {1.0, 2.0, 3.0, 4.0}; -// v2 = [1.0, 2.0, 3.0, 4.0] -// Create a vector for 3D coordinates +// 3D position vector imeth::Vector position = {10.5, 20.3, 15.7}; -// Create a vector for RGB color -imeth::Vector color = {0.8, 0.2, 0.5}; - -// Create empty vector and fill later -imeth::Vector data(10); -for (size_t i = 0; i < data.size(); ++i) { - data[i] = i * 0.5; -} -// data = [0.0, 0.5, 1.0, 1.5, ..., 4.5] - -// Create unit vectors +// Unit vectors imeth::Vector x_axis = {1, 0, 0}; imeth::Vector y_axis = {0, 1, 0}; imeth::Vector z_axis = {0, 0, 1}; - -// Create solution vector -imeth::Vector solution = {2.5, 3.7, 1.2}; ``` -**Real-world applications:** -- 3D graphics: Position, velocity, acceleration vectors -- Machine learning: Feature vectors, weight vectors -- Physics: Force vectors, momentum -- Statistics: Data samples, observations -- Audio: Signal samples +**Real-world:** Coordinates, velocities, feature vectors, data samples --- @@ -632,41 +332,24 @@ double& operator[](size_t i); double operator[](size_t i) const; ``` -Accesses or modifies elements at specified index. - -**Important:** Vector indexing starts at 0. A vector of size n has valid indices from 0 to n-1. +Access element at index i (0-indexed). **Examples:** ```c++ imeth::Vector v = {10, 20, 30, 40, 50}; -// Read elements (const access) double first = v[0]; // 10 -double third = v[2]; // 30 -double last = v[4]; // 50 - -// Modify elements -v[0] = 100; // Change first element -v[2] = 300; // Change third element -// v = [100, 20, 300, 40, 50] - -// Access in loops -for (size_t i = 0; i < v.size(); ++i) { - std::cout << v[i] << " "; -} -std::cout << "\n"; +v[2] = 300; // Modify -// Modify in loops +// Iterate for (size_t i = 0; i < v.size(); ++i) { v[i] *= 2; // Double each element } -// Find maximum element +// Find maximum double max_val = v[0]; for (size_t i = 1; i < v.size(); ++i) { - if (v[i] > max_val) { - max_val = v[i]; - } + if (v[i] > max_val) max_val = v[i]; } // Compute sum @@ -674,25 +357,8 @@ double sum = 0; for (size_t i = 0; i < v.size(); ++i) { sum += v[i]; } - -// Normalize vector (make length = 1) -double length = 0; -for (size_t i = 0; i < v.size(); ++i) { - length += v[i] * v[i]; -} -length = std::sqrt(length); - -for (size_t i = 0; i < v.size(); ++i) { - v[i] /= length; -} ``` -**Real-world applications:** -- Accessing coordinates: position[0] = x, position[1] = y, position[2] = z -- Updating game state: velocity[i] += acceleration[i] -- Data processing: Iterating through measurements -- Statistics: Accessing individual samples - --- ### Properties @@ -701,67 +367,30 @@ for (size_t i = 0; i < v.size(); ++i) { size_t size() const; ``` -Returns the number of elements in the vector. +Returns number of elements. **Examples:** ```c++ -imeth::Vector v1 = {1, 2, 3, 4, 5}; -size_t len1 = v1.size(); // 5 - -imeth::Vector v2(10); -size_t len2 = v2.size(); // 10 +imeth::Vector v = {1, 2, 3, 4, 5}; +size_t len = v.size(); // 5 -// Check if empty (though this implementation doesn't create empty vectors) -bool is_empty = (v1.size() == 0); // false +// Validate operations +bool can_add = (a.size() == b.size()); -// Allocate result vector based on size -imeth::Vector result(v1.size()); - -// Validate vector operations -imeth::Vector a(5); -imeth::Vector b(5); -bool can_add = (a.size() == b.size()); // true - -imeth::Vector c(3); -bool cannot_add = (a.size() == c.size()); // false - -// Iterate safely -for (size_t i = 0; i < v1.size(); ++i) { - // Safe access -} - -// Check compatibility with matrix -imeth::Matrix M(3, 5); -bool compatible = (M.cols() == v1.size()); // true for M * v +// Check matrix compatibility +bool compatible = (M.cols() == v.size()); ``` -**Real-world applications:** -- Validating vector operations -- Allocating memory for results -- Loop bounds checking -- Ensuring dimension compatibility - --- ## Solver Class -The Solver class provides numerical methods for solving systems of linear equations of the form **Ax = b**, where: -- **A** is an n×n coefficient matrix -- **x** is the unknown vector (what we're solving for) -- **b** is the result vector (known values) - -### Understanding Linear Systems - -A system of linear equations looks like: -``` -a₁₁·x₁ + a₁₂·x₂ + a₁₃·x₃ = b₁ -a₂₁·x₁ + a₂₂·x₂ + a₂₃·x₃ = b₂ -a₃₁·x₁ + a₃₂·x₂ + a₃₃·x₃ = b₃ -``` - -In matrix form: **Ax = b** +Solves systems of linear equations: **Ax = b** -The Solver class provides three different methods to find the solution vector **x**. +Where: +- **A** is n×n coefficient matrix +- **x** is unknown vector +- **b** is result vector --- @@ -771,82 +400,34 @@ The Solver class provides three different methods to find the solution vector ** static Vector gaussian_elimination(const Matrix& A, const Vector& b); ``` -Solves Ax = b using Gaussian elimination with back substitution. - -**How it works:** -1. **Forward elimination**: Convert matrix to upper triangular form (zeros below diagonal) -2. **Back substitution**: Solve from bottom to top - -**Best for:** General-purpose solving, small to medium systems +Forward elimination + back substitution. **Examples:** ```c++ -// Solve a 2×2 system: -// 2x + 3y = 8 -// x - y = 1 - -imeth::Matrix A = { - {2, 3}, - {1, -1} -}; +// Solve: 2x + 3y = 8 +// x - y = 1 +imeth::Matrix A = {{2, 3}, {1, -1}}; imeth::Vector b = {8, 1}; -imeth::Vector solution = imeth::Solver::gaussian_elimination(A, b); - -std::cout << "x = " << solution[0] << "\n"; // x = 2.2 -std::cout << "y = " << solution[1] << "\n"; // y = 1.2 - -// Verify solution: A * x = b -// 2(2.2) + 3(1.2) = 4.4 + 3.6 = 8.0 ✓ -// 1(2.2) - 1(1.2) = 2.2 - 1.2 = 1.0 ✓ - -// Solve a 3×3 system: -// x + 2y + z = 6 -// 2x + y + z = 6 -// x + y + 2z = 7 +imeth::Vector sol = imeth::Solver::gaussian_elimination(A, b); +// x = 2.2, y = 1.2 +// 3×3 system imeth::Matrix A3 = { {1, 2, 1}, {2, 1, 1}, {1, 1, 2} }; - imeth::Vector b3 = {6, 6, 7}; - imeth::Vector sol3 = imeth::Solver::gaussian_elimination(A3, b3); - -std::cout << "x = " << sol3[0] << "\n"; // x = 1 -std::cout << "y = " << sol3[1] << "\n"; // y = 2 -std::cout << "z = " << sol3[2] << "\n"; // z = 2 - -// Verify: -// 1(1) + 2(2) + 1(2) = 1 + 4 + 2 = 7... wait, that's wrong! -// Let me recalculate: 1 + 4 + 2 = 7, but we want 6 -// Actually: x=1, y=2, z=2 gives: -// 1 + 4 + 2 = 7 (not 6, there might be an error in this example) - -// More practical example: Circuit analysis -// Using Kirchhoff's laws to find currents -imeth::Matrix circuit = { - {10, -5, 0}, - {-5, 15, -10}, - {0, -10, 20} -}; - -imeth::Vector voltages = {100, 0, 50}; - -imeth::Vector currents = imeth::Solver::gaussian_elimination(circuit, voltages); ``` -**Real-world applications:** -- Circuit analysis (Kirchhoff's laws) -- Structural engineering (force balance) -- Economics (input-output models) -- Computer graphics (transformation solving) -- Chemistry (chemical equilibrium) +**Best for:** General purpose, single solve -**Time complexity:** O(n³) where n is the number of equations +**Real-world:** Circuit analysis, structural engineering, economics + +**Complexity:** O(n³) --- @@ -856,60 +437,32 @@ imeth::Vector currents = imeth::Solver::gaussian_elimination(circuit, voltages); static Vector gauss_jordan(const Matrix& A, const Vector& b); ``` -Solves Ax = b using Gauss-Jordan elimination (reduced row echelon form). - -**How it works:** -1. Forward elimination (like Gaussian) -2. Continue eliminating to create identity matrix on left side -3. Solution appears directly on the right side (no back substitution needed) - -**Best for:** When you need the inverse matrix or solving multiple systems with the same A +Reduces to identity matrix (no back substitution needed). **Examples:** ```c++ -// Solve the same 2×2 system as before: -// 2x + 3y = 8 -// x - y = 1 - -imeth::Matrix A = { - {2, 3}, - {1, -1} -}; - +imeth::Matrix A = {{2, 3}, {1, -1}}; imeth::Vector b = {8, 1}; -imeth::Vector solution = imeth::Solver::gauss_jordan(A, b); +imeth::Vector sol = imeth::Solver::gauss_jordan(A, b); +// x = 2.2, y = 1.2 -std::cout << "x = " << solution[0] << "\n"; // x = 2.2 -std::cout << "y = " << solution[1] << "\n"; // y = 1.2 - -// Same result as Gaussian elimination, but computed differently - -// 4×4 system example +// 4×4 system imeth::Matrix A4 = { {4, 1, 0, 0}, {1, 4, 1, 0}, {0, 1, 4, 1}, {0, 0, 1, 4} }; - imeth::Vector b4 = {5, 6, 6, 5}; - imeth::Vector sol4 = imeth::Solver::gauss_jordan(A4, b4); - -for (size_t i = 0; i < sol4.size(); ++i) { - std::cout << "x" << i << " = " << sol4[i] << "\n"; -} ``` -**Real-world applications:** -- Finding matrix inverses -- Solving multiple systems with same coefficient matrix -- Linear programming problems -- Regression analysis -- Network flow problems +**Best for:** Finding inverses, multiple systems -**Time complexity:** O(n³), slightly more work than Gaussian elimination but no back substitution needed +**Real-world:** Linear programming, regression analysis + +**Complexity:** O(n³) --- @@ -919,116 +472,58 @@ for (size_t i = 0; i < sol4.size(); ++i) { static Vector lu_decomposition(const Matrix& A, const Vector& b); ``` -Solves Ax = b by decomposing A into lower (L) and upper (U) triangular matrices. - -**How it works:** -1. Factor A = LU where L is lower triangular, U is upper triangular -2. Solve Ly = b for y (forward substitution) -3. Solve Ux = y for x (back substitution) - -**Best for:** Solving multiple systems with the same A but different b vectors (factor once, solve many times) +Factors A = LU, then solves Ly = b and Ux = y. **Examples:** ```c++ -// Solve the same 2×2 system: -// 2x + 3y = 8 -// x - y = 1 - -imeth::Matrix A = { - {2, 3}, - {1, -1} -}; - +imeth::Matrix A = {{2, 3}, {1, -1}}; imeth::Vector b = {8, 1}; -imeth::Vector solution = imeth::Solver::lu_decomposition(A, b); - -std::cout << "x = " << solution[0] << "\n"; // x = 2.2 -std::cout << "y = " << solution[1] << "\n"; // y = 1.2 +imeth::Vector sol = imeth::Solver::lu_decomposition(A, b); +// x = 2.2, y = 1.2 -// Advantage: Solve multiple systems with same A +// Multiple solves with same A (efficient!) imeth::Vector b1 = {8, 1}; imeth::Vector b2 = {10, 2}; imeth::Vector b3 = {5, 0}; -// If you factor A once (internally), solving multiple times is faster imeth::Vector sol1 = imeth::Solver::lu_decomposition(A, b1); imeth::Vector sol2 = imeth::Solver::lu_decomposition(A, b2); imeth::Vector sol3 = imeth::Solver::lu_decomposition(A, b3); - -// Larger system example -imeth::Matrix A_large = { - {4, -1, 0, 0}, - {-1, 4, -1, 0}, - {0, -1, 4, -1}, - {0, 0, -1, 4} -}; - -imeth::Vector b_large = {15, 10, 10, 10}; - -imeth::Vector sol_large = imeth::Solver::lu_decomposition(A_large, b_large); - -for (size_t i = 0; i < sol_large.size(); ++i) { - std::cout << "x" << i << " = " << sol_large[i] << "\n"; -} ``` -**Real-world applications:** -- Solving many systems with same coefficient matrix -- Numerical simulations (repeated solve with different initial conditions) -- Finite element analysis -- Control systems -- Statistical estimation - -**Time complexity:** -- Factorization: O(n³) (done once) -- Each solve: O(n²) (much faster for subsequent solves) -- Total for k systems: O(n³ + kn²) vs O(kn³) for other methods - ---- +**Best for:** Multiple solves with same coefficient matrix -### Choosing the Right Solver +**Real-world:** Simulations, finite element analysis, control systems -| Method | Best Use Case | Complexity | Advantages | -|--------|---------------|------------|------------| -| **Gaussian Elimination** | General purpose, single solve | O(n³) | Simple, reliable, good for most cases | -| **Gauss-Jordan** | Need matrix inverse, teaching | O(n³) | No back substitution, clearer steps | -| **LU Decomposition** | Multiple solves with same A | O(n³) + O(kn²) | Efficient for repeated solving | +**Complexity:** O(n³) factorization + O(n²) per solve -**When to use each:** -```c++ -// Single solve: Use Gaussian elimination (simplest) -auto sol = imeth::Solver::gaussian_elimination(A, b); +--- -// Multiple solves: Use LU decomposition (most efficient) -for (const auto& b_vec : multiple_b_vectors) { - auto sol = imeth::Solver::lu_decomposition(A, b_vec); - // Process solution... -} +## Solver Comparison -// Educational purposes: Use Gauss-Jordan (easiest to understand steps) -auto sol = imeth::Solver::gauss_jordan(A, b); -``` +| Method | Best Use | Complexity | Advantage | +|--------|----------|------------|-----------| +| **Gaussian** | Single solve | O(n³) | Simple, reliable | +| **Gauss-Jordan** | Need inverse | O(n³) | No back substitution | +| **LU** | Multiple solves | O(n³) + O(kn²) | Efficient for k solves | --- ## Complete Examples -### Example 1: Traffic Flow Analysis +### Traffic Flow Analysis ```c++ #include #include -#include int main() { - // Traffic intersection with 4 roads - // Conservation law: flow in = flow out at each intersection - - // x1 + x2 = 100 (Intersection 1) - // x2 + x3 = 150 (Intersection 2) - // x3 + x4 = 80 (Intersection 3) - // x4 + x1 = 130 (Intersection 4) + // Conservation law: flow in = flow out + // x1 + x2 = 100 + // x2 + x3 = 150 + // x3 + x4 = 80 + // x4 + x1 = 130 imeth::Matrix A = { {1, 1, 0, 0}, @@ -1038,15 +533,12 @@ int main() { }; imeth::Vector b = {100, 150, 80, 130}; - imeth::Vector flow = imeth::Solver::gaussian_elimination(A, b); - std::cout << std::fixed << std::setprecision(1); - std::cout << "Traffic Flow (vehicles/hour):\n"; - std::cout << "Road 1: " << flow[0] << "\n"; - std::cout << "Road 2: " << flow[1] << "\n"; - std::cout << "Road 3: " << flow[2] << "\n"; - std::cout << "Road 4: " << flow[3] << "\n"; + std::cout << "Road flows (vehicles/hour):\n"; + for (size_t i = 0; i < flow.size(); ++i) { + std::cout << "Road " << i+1 << ": " << flow[i] << "\n"; + } return 0; } @@ -1054,75 +546,28 @@ int main() { --- -### Example 2: 3D Graphics Transformation +### 3D Rotation ```c++ #include -#include #include int main() { - // Rotate a point (1, 0, 0) by 90° around Z-axis - - double angle = M_PI / 2; // 90 degrees in radians + // Rotate point (1,0,0) by 90° around Z-axis + double angle = M_PI / 2; - // 3D rotation matrix around Z-axis imeth::Matrix rotation = { {std::cos(angle), -std::sin(angle), 0}, {std::sin(angle), std::cos(angle), 0}, {0, 0, 1} }; - // Original point - imeth::Matrix point = { - {1}, - {0}, - {0} - }; - - // Apply rotation + imeth::Matrix point = {{1}, {0}, {0}}; imeth::Matrix rotated = rotation * point; - std::cout << "Original point: (" << point(0,0) << ", " - << point(1,0) << ", " << point(2,0) << ")\n"; - - std::cout << "Rotated point: (" << rotated(0,0) << ", " + std::cout << "Rotated: (" << rotated(0,0) << ", " << rotated(1,0) << ", " << rotated(2,0) << ")\n"; - // Result: (0, 1, 0) - rotated 90° from X-axis to Y-axis - - return 0; -} -``` - ---- - -### Example 3: Chemical Equation Balancing - -```c++ -#include -#include - -int main() { - // Balance: C₂H₆ + O₂ → CO₂ + H₂O - // Variables: a·C₂H₆ + b·O₂ → c·CO₂ + d·H₂O - - // Carbon: 2a = c - // Hydrogen: 6a = 2d - // Oxygen: 2b = 2c + d - // Constraint: a = 1 (normalize) - - imeth::Matrix A = { - {2, 0, -1, 0}, // Carbon balance - {6, 0, 0, -2}, // Hydrogen balance - {0, 2, -2, -1} // Oxygen balance - }; - - imeth::Vector b = {0, 0, 0}; - - // This system needs special handling for balancing - // (simplified example - real balancing is more complex) - - std::cout << "Balanced equation: 2C₂H₆ + 7O₂ → 4CO₂ + 6H₂O\n"; + // Result: (0, 1, 0) return 0; } @@ -1130,67 +575,25 @@ int main() { --- -### Example 4: Portfolio Optimization +### Portfolio Optimization ```c++ #include -#include -#include int main() { // Allocate $10,000 across 3 investments - // Constraints: - // - Total investment = $10,000 - // - Expected return = 8% - // - Risk balance equation - imeth::Matrix constraints = { - {1, 1, 1}, // x1 + x2 + x3 = 10000 - {0.05, 0.08, 0.12}, // Expected return + {1, 1, 1}, // Total = $10,000 + {0.05, 0.08, 0.12}, // Expected return 8% {1, -2, 1} // Risk balance }; imeth::Vector targets = {10000, 800, 0}; - imeth::Vector allocation = imeth::Solver::gauss_jordan(constraints, targets); - std::cout << std::fixed << std::setprecision(2); - std::cout << "Portfolio Allocation:\n"; - std::cout << "Investment 1: $" << allocation[0] << "\n"; - std::cout << "Investment 2: $" << allocation[1] << "\n"; - std::cout << "Investment 3: $" << allocation[2] << "\n"; - - return 0; -} -``` - ---- - -### Example 5: Network Flow Problem - -```c++ -#include -#include - -int main() { - // Water distribution network - // 4 nodes, conservation of flow at each node - - imeth::Matrix network = { - {1, -1, 0, 0}, - {0, 1, -1, 0}, - {0, 0, 1, -1}, - {-1, 0, 0, 1} - }; - - imeth::Vector supply = {50, 30, -40, -40}; - // Positive = source, Negative = sink - - imeth::Vector flow = imeth::Solver::lu_decomposition(network, supply); - - std::cout << "Pipe flows (liters/min):\n"; - for (size_t i = 0; i < flow.size(); ++i) { - std::cout << "Pipe " << (i+1) << ": " << flow[i] << "\n"; + std::cout << "Allocation:\n"; + for (size_t i = 0; i < allocation.size(); ++i) { + std::cout << "Investment " << i+1 << ": $" << allocation[i] << "\n"; } return 0; @@ -1199,321 +602,37 @@ int main() { --- -## Mathematical Properties - -### Matrix Properties - -**Transpose Properties:** -- (A^T)^T = A -- (A + B)^T = A^T + B^T -- (AB)^T = B^T A^T (order reverses!) -- (kA)^T = k(A^T) - -**Addition Properties:** -- Commutative: A + B = B + A -- Associative: (A + B) + C = A + (B + C) -- Identity: A + 0 = A -- Inverse: A + (-A) = 0 - -**Multiplication Properties:** -- Associative: (AB)C = A(BC) -- Distributive: A(B + C) = AB + AC -- Identity: AI = IA = A -- NOT commutative: AB ≠ BA (usually) +## Tips -**Identity Matrix Properties:** -- I · A = A · I = A -- I^n = I (any power) -- I^T = I (symmetric) -- det(I) = 1 +- **Dimension compatibility**: Check before operations (A.cols() == B.rows() for multiplication) +- **Zero-based indexing**: Valid indices for 3×3 matrix are (0,0) to (2,2) +- **Order matters**: A × B ≠ B × A for matrix multiplication +- **Choose solver wisely**: Gaussian for one solve, LU for multiple solves +- **Verify solutions**: Substitute back into original equations +- **Identity baseline**: Use I as starting point for transformations --- -## Common Pitfalls - -### 1. Dimension Mismatch in Operations - -```c++ -// ❌ WRONG - Cannot add matrices of different sizes -imeth::Matrix A(2, 3); -imeth::Matrix B(3, 2); -// auto C = A + B; // ERROR! Dimensions don't match - -// ✅ CORRECT - Check dimensions first -if (A.rows() == B.rows() && A.cols() == B.cols()) { - auto C = A + B; -} -``` - -### 2. Invalid Matrix Multiplication - -```c++ -// ❌ WRONG - Columns of A must equal rows of B -imeth::Matrix A(2, 3); // 2×3 -imeth::Matrix B(4, 5); // 4×5 -// auto C = A * B; // ERROR! 3 ≠ 4 - -// ✅ CORRECT - Ensure dimensions match -imeth::Matrix A(2, 3); // 2×3 -imeth::Matrix B(3, 5); // 3×5 -auto C = A * B; // OK! Result is 2×5 -``` - -### 3. Confusing Indices - -```c++ -// ❌ WRONG - Indices start at 0, not 1 -imeth::Matrix M(3, 3); -// double val = M(3, 3); // ERROR! Valid range is (0,0) to (2,2) - -// ✅ CORRECT - Use 0-based indexing -double val = M(2, 2); // Last element -``` - -### 4. Assuming Matrix Multiplication is Commutative +## Quick Reference -```c++ -// ❌ WRONG ASSUMPTION - A*B ≠ B*A -imeth::Matrix A = {{1, 2}, {3, 4}}; -imeth::Matrix B = {{5, 6}, {7, 8}}; - -auto AB = A * B; // [[19, 22], [43, 50]] -auto BA = B * A; // [[23, 34], [31, 46]] -// AB ≠ BA! - -// ✅ CORRECT - Order matters in matrix multiplication -// Always multiply in the correct order -``` - -### 5. Forgetting to Check Solution Validity - -```c++ -// ❌ WRONG - Not all systems have solutions -imeth::Matrix A = { - {1, 2}, - {2, 4} // Second row is 2× first row (linearly dependent) -}; -imeth::Vector b = {3, 7}; -// auto sol = imeth::Solver::gaussian_elimination(A, b); -// This system has no solution or infinitely many! - -// ✅ CORRECT - Check if system is solvable -// (This library doesn't provide built-in validation yet, -// but be aware of singular/ill-conditioned systems) -``` - -### 6. Modifying Temporary Results - -```c++ -// ❌ WRONG - Cannot modify temporary -// (A + B)(0, 0) = 5; // ERROR! (A+B) is temporary - -// ✅ CORRECT - Store result first -imeth::Matrix C = A + B; -C(0, 0) = 5; // OK -``` - ---- +| Operation | Syntax | Requirement | +|-----------|--------|-------------| +| Create matrix | `Matrix A(m, n)` or `{{...}}` | - | +| Access element | `A(i, j)` | 0 ≤ i < rows, 0 ≤ j < cols | +| Add/Subtract | `A + B`, `A - B` | Same dimensions | +| Multiply | `A * B` | A.cols() == B.rows() | +| Transpose | `A.transpose()` | - | +| Identity | `Matrix::identity(n)` | Square n×n | +| Solve system | `Solver::gaussian_elimination(A, b)` | Square matrix A | -## Performance Characteristics - -### Time Complexity +**Properties:** +- Addition: Commutative, associative +- Multiplication: Associative, NOT commutative +- Transpose: (A^T)^T = A, (AB)^T = B^T A^T +- Identity: I × A = A × I = A -**Matrix Operations:** +**Complexity:** - Element access: O(1) -- Addition/Subtraction: O(mn) where m×n is matrix size -- Multiplication: O(mnp) for (m×n) × (n×p) matrices -- Transpose: O(mn) - -**Solver Methods:** -- Gaussian Elimination: O(n³) -- Gauss-Jordan: O(n³) -- LU Decomposition: O(n³) for factorization + O(n²) per solve - -### Space Complexity - -**Matrix Storage:** O(mn) for m×n matrix -**Vector Storage:** O(n) for size n vector -**Solver Intermediate:** O(n²) for working matrices - -### Optimization Tips - -```c++ -// Slow: Multiple temporary matrices -auto result = (A + B) * (C + D) * E; - -// Better: Minimize temporaries (though compiler may optimize) -auto temp1 = A + B; -auto temp2 = C + D; -auto temp3 = temp1 * temp2; -auto result = temp3 * E; - -// For repeated solves with same A: Use LU decomposition -// Factor once: O(n³) -// Solve many times: O(n²) each - -// Avoid unnecessary copies -const imeth::Matrix& ref = large_matrix; // Use reference -// auto copy = large_matrix; // Avoid copying if not needed -``` - ---- - -## Integration with Other Modules - -### With Algebra Module - -```c++ -#include -#include - -// Solve 2×2 system using both approaches -imeth::Matrix A = {{2, 3}, {1, -1}}; -imeth::Vector b = {8, 1}; - -// Method 1: Matrix solver -auto sol1 = imeth::Solver::gaussian_elimination(A, b); - -// Method 2: LinearAlgebra (for 2 variables only) -auto sol2 = imeth::LinearAlgebra::solve_2v(2, 3, 8, 1, -1, 1); - -if (sol2.has_value()) { - auto [x, y] = sol2.value(); - std::cout << "x = " << x << ", y = " << y << "\n"; -} -``` - -### With Logarithm Module - -```c++ -#include -#include - -// Apply logarithmic transformation to matrix elements -imeth::Matrix data = { - {100, 1000}, - {10000, 100000} -}; - -imeth::Matrix log_data(data.rows(), data.cols()); - -for (size_t i = 0; i < data.rows(); ++i) { - for (size_t j = 0; j < data.cols(); ++j) { - auto log_val = imeth::Logarithm::log10(data(i, j)); - if (log_val.has_value()) { - log_data(i, j) = log_val.value(); - } - } -} -// log_data = [[2, 3], -// [4, 5]] -``` - ---- - -## Tips and Best Practices - -### Matrix Operations -- **Always check dimensions** before operations -- **Use const references** for large matrices to avoid copying -- **Prefer specialized functions** (ln, log10) over general log when possible -- **Store intermediate results** if used multiple times -- **Use identity matrix** as baseline for transformations - -### Solving Systems -- **Choose the right solver** based on your use case -- **Gaussian elimination** for single solves -- **LU decomposition** for multiple solves with same coefficient matrix -- **Check solution** by substituting back into original equations -- **Be aware of singular matrices** (determinant = 0, no unique solution) - -### Code Organization -- **Validate inputs** before expensive computations -- **Use meaningful variable names** (coefficients, solution, not A, x) -- **Comment complex matrix operations** -- **Verify results** with test cases - -### Memory Management -- **Avoid unnecessary copies** of large matrices -- **Reuse matrices** when possible -- **Clear unused matrices** in long-running programs -- **Consider memory layout** for cache efficiency - ---- - -## Frequently Asked Questions - -**Q: What's the difference between a Matrix and a Vector?** -A: A Matrix is 2D (rows and columns), while a Vector is 1D (just elements). Mathematically, a vector is often represented as a column matrix (n×1), but this implementation treats them separately for efficiency. - -**Q: Why do matrix indices start at 0?** -A: Following C++ convention. Matrix(0, 0) is the top-left element. In mathematics, matrices often use 1-based indexing, but programming uses 0-based. - -**Q: Can I multiply matrices of any size?** -A: No. For A × B, the number of columns in A must equal the number of rows in B. A (m×n) matrix can only multiply a (n×p) matrix, giving an (m×p) result. - -**Q: Why is A × B ≠ B × A?** -A: Matrix multiplication represents composition of transformations, which depends on order. Also, A × B and B × A might not even have the same dimensions! - -**Q: Which solver method should I use?** -A: For single solves, use Gaussian elimination (simplest and efficient). For multiple solves with the same coefficient matrix, use LU decomposition. Use Gauss-Jordan mainly for educational purposes or when you need the matrix inverse. - -**Q: What happens if the system has no solution?** -A: The current implementation doesn't have built-in detection for singular or ill-conditioned matrices. It's the user's responsibility to ensure the system is solvable. Future versions may add validation. - -**Q: How do I create a zero matrix?** -A: Use the constructor: `imeth::Matrix zero(rows, cols);` - it initializes all elements to 0. - -**Q: Can I solve non-square systems (more/fewer equations than unknowns)?** -A: The current Solver class requires square matrices (n equations, n unknowns). For over/under-determined systems, you'd need least-squares or other specialized methods. - -**Q: How accurate are the solutions?** -A: Solutions are computed using double precision (~15-17 significant digits), but numerical stability depends on the condition number of the matrix. Ill-conditioned matrices may have large errors. - -**Q: What's the transpose used for?** -A: Converting between row and column vectors, computing dot products (A^T × B), symmetric matrix operations, and many matrix calculus operations. - ---- - -## Summary - -The Matrix module provides: -- ✅ **Matrix class**: 2D arrays with mathematical operations -- ✅ **Vector class**: 1D arrays for equation coefficients and solutions -- ✅ **Solver class**: Three methods for solving linear systems -- ✅ **Complete operations**: Addition, subtraction, multiplication, transpose -- ✅ **Efficient implementations**: O(n³) for solving, O(1) for access -- ✅ **Real-world ready**: Suitable for graphics, engineering, ML, and more - -**Quick Reference:** -```c++ -// Create matrices -imeth::Matrix A = {{1, 2}, {3, 4}}; -imeth::Matrix I = imeth::Matrix::identity(2); - -// Access elements -double val = A(0, 1); // 2 -A(1, 1) = 5; - -// Operations -imeth::Matrix sum = A + I; -imeth::Matrix diff = A - I; -imeth::Matrix product = A * I; -imeth::Matrix transposed = A.transpose(); - -// Create vectors -imeth::Vector v = {1, 2, 3}; -double element = v[0]; // 1 -v[2] = 5; - -// Solve systems: Ax = b -imeth::Vector x1 = imeth::Solver::gaussian_elimination(A, b); -imeth::Vector x2 = imeth::Solver::gauss_jordan(A, b); -imeth::Vector x3 = imeth::Solver::lu_decomposition(A, b); -``` - -**Remember:** -- Matrix operations require compatible dimensions -- Indices start at 0 -- Matrix multiplication order matters (A×B ≠ B×A) -- Choose appropriate solver for your use case \ No newline at end of file +- Add/Subtract: O(mn) +- Multiply: O(mnp) for (m×n) × (n×p) +- Solve: O(n³) \ No newline at end of file