-2

I just would like to approximate any number, out of mathematical curiosity, purely in terms of e.

Example: If I give n=7.3890, the program must return a=1,b=0, which is the best approximation(minimal error) for all whole number pairs(a,b)

from math import *
n=float(input("Enter a number to be approximated:"))
for a in range(10):
    for b in range(10):
            if ((e**2)*a)+(e*b)==n:
                print(a,b)

This program couldn't do so since it searches for exact values rather than approximate ones

DatBoi
  • 99
  • 4
  • Your approach is a little bit naive. [have you ever head of the discriminant](https://www.mathsisfun.com/algebra/quadratic-equation.html)? – UmNyobe Aug 23 '20 at 06:51
  • So you want to find all **real** numbers a, b, c in [0,10) for which ax^2+bx+c=n for given x,n? There could be rather a lot of them! Or what exactly do you want it to do? – alani Aug 23 '20 at 06:53
  • Well I wanted to generalize it for higher powers of x as well. We dont have discriminants for them, do we? – DatBoi Aug 23 '20 at 06:53
  • 1
    Do you want to find _all_ solutions (which is impossible) or _any_ solution? In the latter case, pick any a and b, and c=x-ax^2-bx. Unless there are other constraints, which you _must_ mention in the question. – DYZ Aug 23 '20 at 06:54
  • Do you want to create your own program or would a scipy implentation also work? – Nathan Aug 23 '20 at 06:56
  • I would like to get some idea. I could go on creating my own code after that. – DatBoi Aug 23 '20 at 06:59
  • We may have infinite such ordered numbers(a,b,c). However good approximations mean (a,b,c) to be in simple fractions or just whole numbers – DatBoi Aug 23 '20 at 07:02
  • 1
    Without any additional constraint, the simplest solution is to set `a` and `b` to zero and `c` to `n`, which always hold regardless of the value of `x`. – Roberto Trani Aug 23 '20 at 07:07
  • @DatBoi So you would like to find "simple fractions" - also known as rational numbers. You should add that to the question. But without other constraints, there are still going to be too many solutions though (if x and n are rational then choose any rational a and b, and c is also rational). – alani Aug 23 '20 at 07:13
  • Ah, now you've changed the question to use e in place of x, and presumably you intend `e` here to be the base of natural logarithms. In that case, your only rational solution (with n rational) is probably a=0, b=0, c=n – alani Aug 23 '20 at 07:15
  • I have completely changed the question. Does the new question make sense? – DatBoi Aug 23 '20 at 07:35
  • Regarding the new question: does the solution `a=0, b=n/e` make sense for you? – Roberto Trani Aug 23 '20 at 08:10
  • b=n/e isn't a whole number always – DatBoi Aug 23 '20 at 08:22
  • Then, do you need only integer coefficients? This is unclear from the question. – Roberto Trani Aug 23 '20 at 08:28

1 Answers1

0

Premise: the following solution finds integer (approximate) coefficients.

An easy way to make your code more efficient is to use vectorization (using the numpy library) to compute the polynomial on all combination of indices, then return the combination of indices whose value of the polynomial is closer to the value of n.

The following code creates a grid of all integer a and b combinations using np.meshgrid, then computes the polynomial on all combinations and computes the positions of the combination making the polynomial closer to n using np.argmin. Lastly, it returns the a and b values of the combination.

import numpy as np

def find_approximate_integer_coefficients(n, x, amin=-10, amax=10, bmin=-10, bmax=10):
    a_range = np.arange(amin, amax+1)
    b_range = np.arange(bmin, bmax+1)

    a_coefficients, b_coefficients = np.meshgrid(a_range, b_range)
    polynomial_value = (a_coefficients * (x ** 2) + b_coefficients * x)

    argmin = np.abs(polynomial_value - n).argmin()
    return a_coefficients.flatten()[argmin], b_coefficients.flatten()[argmin]

For instance, find_approximate_integer_coefficients(7.3890, np.e) returns (1, 0) in about 75 microseconds on my laptop.

You can easily extend the code above to the case of higher-order polynomials as the np.meshgrid method accepts an arbitrary number of ranges to create the grid.

Roberto Trani
  • 1,217
  • 11
  • 14