|
| 1 | +# Polynomial Factoring Implementation (#33) |
| 2 | + |
| 3 | +This document summarizes the polynomial factoring implementation for issue #33 and issue #180. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Implemented polynomial factoring algorithms to enable simplification of expressions like `sqrt(x²+2x+1)` → `|x+1|`. |
| 8 | + |
| 9 | +## Features Implemented |
| 10 | + |
| 11 | +### 1. Perfect Square Trinomial Factoring |
| 12 | + |
| 13 | +Detects and factors patterns like: |
| 14 | +- `a² + 2ab + b²` → `(a+b)²` |
| 15 | +- `a² - 2ab + b²` → `(a-b)²` |
| 16 | + |
| 17 | +Examples: |
| 18 | +```typescript |
| 19 | +sqrt(x² + 2x + 1) → |x+1| |
| 20 | +sqrt(x² - 2x + 1) → |x-1| |
| 21 | +sqrt(4x² + 12x + 9) → |2x+3| |
| 22 | +sqrt(a² + 2ab + b²) → |a+b| |
| 23 | +``` |
| 24 | + |
| 25 | +### 2. Difference of Squares Factoring |
| 26 | + |
| 27 | +Detects and factors patterns like: |
| 28 | +- `a² - b²` → `(a-b)(a+b)` |
| 29 | + |
| 30 | +Examples: |
| 31 | +```typescript |
| 32 | +x² - 4 → (x-2)(x+2) |
| 33 | +4x² - 9 → (2x-3)(2x+3) |
| 34 | +``` |
| 35 | + |
| 36 | +### 3. Quadratic Factoring with Rational Roots |
| 37 | + |
| 38 | +Factors quadratics using the quadratic formula when roots are rational: |
| 39 | +- `ax² + bx + c` → `a(x - r₁)(x - r₂)` |
| 40 | + |
| 41 | +Examples: |
| 42 | +```typescript |
| 43 | +x² + 5x + 6 → (x+2)(x+3) |
| 44 | +x² - 5x + 6 → (x-2)(x-3) |
| 45 | +``` |
| 46 | + |
| 47 | +Note: Quadratics with irrational roots (like `x² + 2x - 1`) are not factored. |
| 48 | + |
| 49 | +## Integration with sqrt Simplification |
| 50 | + |
| 51 | +The factoring is automatically applied when simplifying square root expressions. Before applying the `sqrt(x²) → |x|` rule, the system now tries to factor the argument: |
| 52 | + |
| 53 | +```typescript |
| 54 | +// Before factoring implementation: |
| 55 | +sqrt(x² + 2x + 1) → sqrt(x² + 2x + 1) // No simplification |
| 56 | + |
| 57 | +// After factoring implementation: |
| 58 | +sqrt(x² + 2x + 1) → |x+1| // Factors to (x+1)², then applies sqrt rule |
| 59 | +``` |
| 60 | + |
| 61 | +This fixes issue #180. |
| 62 | + |
| 63 | +## API |
| 64 | + |
| 65 | +### Exported Functions |
| 66 | + |
| 67 | +```typescript |
| 68 | +import { |
| 69 | + factorPerfectSquare, |
| 70 | + factorDifferenceOfSquares, |
| 71 | + factorQuadratic, |
| 72 | + factorPolynomial, |
| 73 | +} from '@cortex-js/compute-engine'; |
| 74 | + |
| 75 | +// Factor perfect square trinomials |
| 76 | +factorPerfectSquare(expr: BoxedExpression): BoxedExpression | null |
| 77 | + |
| 78 | +// Factor difference of squares |
| 79 | +factorDifferenceOfSquares(expr: BoxedExpression): BoxedExpression | null |
| 80 | + |
| 81 | +// Factor quadratics with rational roots |
| 82 | +factorQuadratic(expr: BoxedExpression, variable: string): BoxedExpression | null |
| 83 | + |
| 84 | +// General polynomial factoring (tries all strategies) |
| 85 | +factorPolynomial(expr: BoxedExpression, variable?: string): BoxedExpression |
| 86 | +``` |
| 87 | + |
| 88 | +### Usage Examples |
| 89 | + |
| 90 | +```typescript |
| 91 | +const ce = new ComputeEngine(); |
| 92 | + |
| 93 | +// Automatic factoring in sqrt simplification |
| 94 | +const expr1 = ce.parse('\\sqrt{x^2 + 2x + 1}').simplify(); |
| 95 | +console.log(expr1.latex); // \vert x+1\vert |
| 96 | + |
| 97 | +// Manual factoring |
| 98 | +import { factorPerfectSquare } from '@cortex-js/compute-engine'; |
| 99 | + |
| 100 | +const expr2 = ce.parse('x^2 + 2x + 1'); |
| 101 | +const factored = factorPerfectSquare(expr2); |
| 102 | +console.log(factored?.latex); // (x+1)^2 |
| 103 | +``` |
| 104 | + |
| 105 | +## Implementation Details |
| 106 | + |
| 107 | +### Files Modified |
| 108 | + |
| 109 | +1. **src/compute-engine/boxed-expression/factor.ts** |
| 110 | + - Added `factorPerfectSquare()` - detects perfect square trinomials |
| 111 | + - Added `factorDifferenceOfSquares()` - detects difference of squares |
| 112 | + - Added `factorQuadratic()` - factors using quadratic formula for rational roots |
| 113 | + - Added `factorPolynomial()` - general factoring dispatcher |
| 114 | + - Added `extractSquareRoot()` - helper to extract square roots safely |
| 115 | + |
| 116 | +2. **src/compute-engine/symbolic/simplify-power.ts** |
| 117 | + - Integrated factoring into sqrt simplification |
| 118 | + - Added perfect square and difference of squares checks before applying sqrt rules |
| 119 | + |
| 120 | +3. **src/compute-engine/index.ts** |
| 121 | + - Exported new factoring functions for public API |
| 122 | + |
| 123 | +### Key Implementation Considerations |
| 124 | + |
| 125 | +1. **No .simplify() calls in factoring functions** |
| 126 | + - To avoid infinite recursion, factoring functions don't call `.simplify()` on their results |
| 127 | + - However, `.simplify()` is called on individual square roots during extraction, which is safe |
| 128 | + - See CLAUDE.md section "Simplification and Recursion Prevention" for details |
| 129 | + |
| 130 | +2. **Handling different representations** |
| 131 | + - `4x²` is represented as `Multiply(4, Power(x, 2))`, not `Power(2x, 2)` |
| 132 | + - The implementation uses `.sqrt().simplify()` to extract square roots properly |
| 133 | + - Handles both symbolic (√x²) and numeric (√4) perfect squares |
| 134 | + |
| 135 | +3. **Irrational root filtering** |
| 136 | + - Quadratic factoring checks for radical components in discriminant and roots |
| 137 | + - Uses `numericValue.radical` property to detect irrational square roots |
| 138 | + - Only factors when roots are provably rational |
| 139 | + |
| 140 | +## Tests |
| 141 | + |
| 142 | +Comprehensive test suite in `test/compute-engine/factor.test.ts`: |
| 143 | +- Perfect square trinomial tests (6 tests) |
| 144 | +- Difference of squares tests (6 tests) |
| 145 | +- Quadratic factoring tests (8 tests) |
| 146 | +- General polynomial factoring tests (4 tests) |
| 147 | +- Integration with sqrt simplification (8 tests) |
| 148 | +- Issue #180 regression tests (3 tests) |
| 149 | + |
| 150 | +All tests passing ✓ |
| 151 | + |
| 152 | +## Performance |
| 153 | + |
| 154 | +The factoring algorithms are O(1) for checking patterns: |
| 155 | +- Perfect square: O(1) - checks 3 terms |
| 156 | +- Difference of squares: O(1) - checks 2 terms |
| 157 | +- Quadratic factoring: O(1) - quadratic formula |
| 158 | + |
| 159 | +The algorithms are called during simplification only when needed (sqrt of Add expressions). |
| 160 | + |
| 161 | +## Future Enhancements |
| 162 | + |
| 163 | +Potential improvements not yet implemented: |
| 164 | +1. Higher-degree polynomial factoring (cubic, quartic) |
| 165 | +2. Factoring over different domains (complex numbers, modular arithmetic) |
| 166 | +3. Multivariate polynomial factoring |
| 167 | +4. Kronecker's method for general factorization |
| 168 | + |
| 169 | +## Related Issues |
| 170 | + |
| 171 | +- Issue #180: "Factoring before trying to simplify" ✓ Fixed |
| 172 | +- Issue #33: "Polynomial Factoring" ✓ Implemented |
0 commit comments