# Item III

*Solving a very (un)known problem*

1. Implement a function that finds the two roots of the quadratic equation $a x^2 + b x + c = 0$ given $a$,$b$, and $c$, i.e. implement $x_{\pm} = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$.
2. What are the roots of $2x^2+10^9+1 = 0$? How many digits of significance can you get for the two roots? Is there any problem?
3. Design a code that finds the correct roots for $x^2+Bx+C=0$, given $B \gg C$ to at least 2 digits of significance.
4. Solve the previous equation using this new code and find the new roots. *I hope it works!*
5. From the well-known solution $x_{\pm}$ of the quadratic equation design an algorithm that approximates the two roots of $x^2+Bx+C = 0$, given $B \gg C$. Hint: *A Taylor expansion may work*.
---

## Part 1


```python
def solve_quadratic(a,b,c):
    assert(a!=0)
    disc = (b**2-4*a*c+0j)**0.5
    x1 = (-b-disc)/(2*a)
    x2 = (-b+disc)/(2*a)
    return (x1,x2)
```

## Part 2

The analytical solution is:
$$
x_{\pm} = \frac{-10^{9}\pm\sqrt{10^{18}-8}}{4}
$$


```python
# if we use the solver
x1,x2 = solve_quadratic(2,1e9,1)
print("x-:",x1)
print("x+:",x2)
```

    x-: (-500000000+0j)
    x+: 0j


The approximation given for $x_{-}$ is good since the relative error is very little (the approximation $\sqrt{10^{18}-8} \approx 10^{9}$ that the computer does because of the *absorption* of the much smaller $-8$ doesn't affect the relative error too much).
<!-- we have as many digits of significance as the double's allow, since -->

For $x_{+}$ however, the error is equal to the value of the root, since  

## Part 3

We make the following change to the equation:
\begin{align}
x_{\pm} = \frac{-b \pm \sqrt{b^2-4ac}}{2a} &= \frac{-b \pm \sqrt{b^2-4ac}}{2a} \cdot \frac{-b \mp \sqrt{b^2-4ac}}{-b \mp \sqrt{b^2-4ac}}
\\ &= \frac{4ac}{2a \left(-b \mp \sqrt{b^2-4ac}\right)}
\\ &= \frac{-2c}{\left(b \pm \sqrt{b^2-4ac}\right)}
\end{align}
we can use it for $x_{+}$ if $b>0$ or $x_{-}$ otherwise.


```python
def solve_quadratic_2(a,b,c):
    assert(a!=0)
    disc = (b**2-4*a*c+0j)**0.5
    if b>0:
        x1 = (-b-disc)/(2*a)
        x2 = -2*c/(b+disc)
    else:
        x1 = -2*c/(b-disc)
        x2 = (-b+disc)/(2*a)
    return (x1,x2)
```

## Part 4

We solve using the new method and see that it works.


```python
x1,x2 = solve_quadratic_2(2,1e9,1)
print("x-:",x1)
print("x+:",x2)
```

    x-: (-500000000+0j)
    x+: (-1e-09+0j)


## Part 5

If $C$ is small, we can approximate the solution:
$$
x = x_0 + C x_1 + C^2 x_2 + ...
$$

Then
$$
\begin{align}
x^2 + B x + C &= 0
\\ (x_0^2 + C (2x_0x_1) + C^2 (x_1^2 + 2x_0x_2) + \dots) + (Bx_0 + C B x_1 + C^2 B x_2 + \dots) + C &= 0
\end{align}
$$
And we have the following equations:
\begin{align}
O(C^0) :  &\qquad x_0^2 + B x_0 = 0 
\\ O(C^1) :  &\qquad 2x_0x_1 + B x_1 +1 = 0 
\\ O(C^2) :  &\qquad x_1^2 + 2 x_0x_2 + B x_2 = 0 
\end{align}
which have the following solutions:
$$
(x_0,x_1,x_2)_1 = \left(0,\frac{-1}{B},\frac{-1}{B^3}\right)
$$
$$
(x_0,x_1,x_2)_2 = \left(-B,\frac{1}{B},\frac{1}{B^3}\right)
$$
which result in the following approximations for $x$:
$$
\begin{align}
x_{1} &= 0 + C \frac{-1}{B} + C^2 \frac{-1}{B^3} + \cdots
\\ x_{2} &= -B + C \frac{1}{B} + C^2 \frac{1}{B^3} + \cdots
\end{align}
$$


```python
def solve_quadratic_3(a,b,c):
    # In case a!=1 we just have to scale the equation:
    b /= a
    c /= a
    # Approximations:
    x1 = 0+c*(-1/b)+c**2*(-1/b**3)
    x2 = -b+c*(1/b)+c**2*(1/b**3)
    return (x1,x2)
```


```python
x1,x2 = solve_quadratic_3(2,1e9,1)
print("x1:",x1)
print("x2:",x2)
```

    x1: -1e-09
    x2: -500000000.0



```python

```

7252c1c30da54c99ea864d11b3892cd24ec394e4
ipynb
Jupyter Notebook
t1_questions/item_03_alpha.ipynb
autopawn/cc5-works
63775574c82da85ed0e750a4d6978a071096f6e7
MIT
t1_questions/item_03_alpha.ipynb
autopawn/cc5-works
63775574c82da85ed0e750a4d6978a071096f6e7
MIT
t1_questions/item_03_alpha.ipynb
autopawn/cc5-works
63775574c82da85ed0e750a4d6978a071096f6e7
MIT
Qwen/Qwen-72B
1. YES
2. YES