// ============================================================================ // Quadratic equations — discriminant and the two real roots // ============================================================================ // // For ax² + bx + c = 0 the discriminant D = b² − 4ac decides the root count: // D > 0 two real roots, D == 0 one repeated, D < 0 none real. Vieta's // relations cross-check: roots sum to −b/a and multiply to c/a. // // soma run quadratic.cell run // ============================================================================ cell Quadratic { face { signal discriminant(a: Float, b: Float, c: Float) -> Float signal roots(a: Float, b: Float, c: Float) -> List signal run() -> Map } on discriminant(a: Float, b: Float, c: Float) { return b * b - 4.0 * a * c } on roots(a: Float, b: Float, c: Float) { let d = discriminant(a, b, c) if d < 0.0 { return [] } // no real roots let sq = sqrt(d) let r1 = (0 - b + sq) / (2.0 * a) let r2 = (0 - b - sq) / (2.0 * a) return [r1, r2] } on run() { // x^2 - 5x + 6 = 0 -> roots 3 and 2 let r = roots(1.0, 0 - 5.0, 6.0) return map("discriminant", discriminant(1.0, 0 - 5.0, 6.0), "roots", r) } } cell test QuadraticTests { rules { // x^2 - 5x + 6: D = 25 - 24 = 1 assert discriminant(1.0, 0 - 5.0, 6.0) == 1.0 // roots are 3 and 2 assert abs(roots(1.0, 0 - 5.0, 6.0)[0] - 3.0) < 0.0000001 assert abs(roots(1.0, 0 - 5.0, 6.0)[1] - 2.0) < 0.0000001 // Vieta: sum of roots = -b/a = 5 assert abs(sum(roots(1.0, 0 - 5.0, 6.0)) - 5.0) < 0.0000001 // Vieta: product of roots = c/a = 6 assert abs(product(roots(1.0, 0 - 5.0, 6.0)) - 6.0) < 0.0000001 // negative discriminant -> no real roots assert len(roots(1.0, 0.0, 1.0)) == 0 } }