From cc5ddfe6b4d1499fd28730d18c3c5f00e792f344 Mon Sep 17 00:00:00 2001 From: m-stclair Date: Wed, 3 Apr 2024 22:02:20 -0400 Subject: [PATCH] add benchmarking method to quickseries --- README.md | 6 +++++- quickseries/__init__.py | 4 ++-- quickseries/approximate.py | 31 +++++++++++++++++++++++++++++++ setup.py | 2 +- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f573b9b..84986a2 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,14 @@ approx runtime: ## tips +* *NOTE: `quickseries.benchmark()` offers an easy way to test the precision and + efficiency of `quickseries.quickseries()`-generated approximations.* * Narrowing `bounds` will tend to make the approximation more accurate within those bounds. In the example above, setting `bounds` to `(-1, 1)` provides ~20x greater precision within the (-1, 1) interval (with the downside that -the resulting approximation will get pretty bad past about +/-pi/2). +the resulting approximation will get pretty bad past about +/-pi/2). + * `quickseries()` tends to be much more effective closer to 0. You may be + able to get more use out of it if you shift/squeeze your data towards 0. * Increasing `order` will tend to make the approximation slower but more precise. In the example above, increasing `order` to 14 provides ~20x greater precision but makes the approximation ~20% slower. diff --git a/quickseries/__init__.py b/quickseries/__init__.py index 7716f43..4ccdb05 100644 --- a/quickseries/__init__.py +++ b/quickseries/__init__.py @@ -1,3 +1,3 @@ -from quickseries.approximate import quickseries +from quickseries.approximate import benchmark, quickseries -__version__ = "0.1.0" +__version__ = "0.1.1" diff --git a/quickseries/approximate.py b/quickseries/approximate.py index 7a24d47..36f58a7 100644 --- a/quickseries/approximate.py +++ b/quickseries/approximate.py @@ -264,3 +264,34 @@ def quickseries( import numba polyfunc = numba.njit(polyfunc) return polyfunc + + +def benchmark( + func: Union[str, sp.Expr, sp.core.function.FunctionClass], + offset_resolution: int = 10000, + timeit_cycles: int = 10000, + testbounds = "equal", + **quickkwargs +): + lamb = lambdify(sp.sympify(func)) + quick = quickseries(func, **quickkwargs) + if testbounds == "equal": + testbounds = quickkwargs.get("bounds", (-1, 1)) + x_ax = np.linspace(*testbounds, offset_resolution) + # TODO: should probably permit specifying dtype for jitted + # functions -- both here and in primary quickseries(). + approx_y, orig_y = quick(x_ax), lamb(x_ax) + approx_time = timeit.timeit(lambda: quick(x_ax), number=timeit_cycles) + orig_time = timeit.timeit(lambda: lamb(x_ax), number=timeit_cycles) + funcrange = min(orig_y), max(orig_y) + absdiff = max(abs(approx_y - orig_y)) + orig_s = orig_time / timeit_cycles + approx_s = approx_time / timeit_cycles + return { + 'absdiff': absdiff, + 'reldiff': absdiff / (funcrange[1] - funcrange[0]), + 'range': funcrange, + 'orig_s': orig_s, + 'approx_s': approx_s, + 'timeratio': approx_s / orig_s + } \ No newline at end of file diff --git a/setup.py b/setup.py index ce7cd53..4d825ef 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="quickseries", - version="0.1.0", + version="0.1.1", packages=find_packages(), url="https://github.com/millionconcepts/quickseries.git", author="Michael St. Clair",