Skip to content

Commit fe7a789

Browse files
authored
Merge pull request #288 from tylerjarvis/main
Pulling from Main
2 parents 804c4b1 + e6cd862 commit fe7a789

5 files changed

Lines changed: 117 additions & 75 deletions

File tree

CombinedNotebook.ipynb

Lines changed: 71 additions & 61 deletions
Large diffs are not rendered by default.

tests/test_Combined_Solver.py

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ def test_univariate():
3434
assert len(roots) == 128
3535
assert np.max(np.abs(f(roots))) < tol1
3636

37-
def test_univariate_power():
37+
def test_univariate_power():
3838
coeff = np.zeros(5)
3939
coeff[0], coeff[1], coeff[2], coeff[3], coeff[4] = -2, 2, 3, 4, 5
4040
f = yr.MultiPower(coeff)
4141

42-
roots = yr.solve(f, -2, 1)
42+
roots = yr.solve(f, -1, 1)
4343
assert len(roots) == 2
4444
assert np.max(np.abs(f(roots))) < tol1
4545

@@ -48,8 +48,8 @@ def test_univariate_cheb():
4848
coeff[0], coeff[1], coeff[2], coeff[3] = 0, 1, 2, 3
4949
f = yr.MultiCheb(coeff)
5050

51-
roots = yr.solve(f, -0.5, 1)
52-
assert len(roots) == 2
51+
roots = yr.solve(f, -1, 1)
52+
assert len(roots) == 3
5353
assert np.max(np.abs(f(roots))) < tol1
5454

5555
# Test Multidimensional Examples
@@ -103,6 +103,28 @@ def test_multiCheb_multiPower():
103103
assert np.max(np.abs(f(roots))) < tol2
104104
assert np.max(np.abs(g(roots))) < tol2
105105

106+
# Test MultiCheb and MultiPower
107+
def test_multiCheb_multiPower_non_unit_box():
108+
"""
109+
f(x,y) = 5x^3 + 4 xy^2 + 3x^2 + 2y^2 + 1
110+
g(x,y) = 5 T_2(x) + 3T_1(x)T_2(y) + 2
111+
112+
"""
113+
114+
coeff = np.zeros((4,4))
115+
coeff[3,0], coeff[1,2], coeff[2,0], coeff[0,2], coeff[0,0] = 5, 4, 3, 2, 1
116+
f = yr.MultiPower(coeff)
117+
118+
coeff = np.zeros((3,3))
119+
coeff[2,0], coeff[1,2], coeff[0,0] = 5, 3, 2
120+
g = yr.MultiCheb(coeff)
121+
122+
roots = yr.solve([f,g],[-2,-2],[2,2])
123+
124+
assert len(roots) == 2
125+
assert np.max(np.abs(f(roots))) < tol2
126+
assert np.max(np.abs(g(roots))) < tol2
127+
106128
def test_multiPower():
107129
"""
108130
f(x,y) = 5x^3 + 4 xy^2 + 3x^2 + 2y^2 - 5
@@ -117,9 +139,9 @@ def test_multiPower():
117139
coeff[2,1], coeff[1,2], coeff[2,0], coeff[0,2], coeff[0,0] = 3, -4, 3, 2, -1
118140
g = yr.MultiPower(coeff)
119141

120-
roots = yr.solve([f,g],[-2,-2],[2,2])
142+
roots = yr.solve([f,g],[-1,-1],[1,1])
121143

122-
assert len(roots) == 2
144+
assert len(roots) == 1
123145
assert np.max(np.abs(f(roots))) < tol2
124146
assert np.max(np.abs(g(roots))) < tol2
125147

@@ -208,8 +230,8 @@ def test_exact_option():
208230
yroots_non_exact = yr.solve(funcs,a,b,exact=False)
209231
yroots_exact = yr.solve(funcs,a,b,exact=True)
210232

211-
actual_roots = np.load('../../Polished_results/polished_2.3.npy')
212-
chebfun_roots = np.loadtxt('../../Chebfun_results/test_roots_2.3.csv', delimiter=',')
233+
actual_roots = np.load('../Polished_results/polished_2.3.npy')
234+
chebfun_roots = np.loadtxt('../Chebfun_results/test_roots_2.3.csv', delimiter=',')
213235

214236
assert len(yroots_non_exact) == len(actual_roots)
215237
assert len(yroots_exact) == len(actual_roots)

yroots/ChebyshevApproximator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -441,9 +441,9 @@ def chebApproximate(f, a, b, relApproxTol=1e-10):
441441
except TypeError as e:
442442
raise ValueError("Invalid input: length of the upper/lower bound lists must match the dimension of the function")
443443

444-
# If the function is a MultiCheb object on [-1,1]^n, then return its matrix as the approximation
445-
if isinstance(f,MultiCheb) and np.allclose(a,-np.ones_like(a)) and np.allclose(b,np.ones_like(b)):
446-
return f.coeff.astype(float), 0
444+
# # If the function is a MultiCheb object on [-1,1]^n, then return its matrix as the approximation
445+
# if isinstance(f,MultiCheb) and np.allclose(a,-np.ones_like(a)) and np.allclose(b,np.ones_like(b)):
446+
# return f.coeff.astype(float), 0
447447

448448
# Generate and return the approximation
449449
degs, epsilons, rhos = getChebyshevDegrees(f, a, b, relApproxTol)

yroots/ChebyshevSubdivisionSolver.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from scipy.spatial import HalfspaceIntersection, QhullError
66
from scipy.optimize import linprog
77
from yroots.QuadraticCheck import quadratic_check
8+
from time import time
89
import copy
910
import warnings
1011

@@ -1238,6 +1239,7 @@ def solvePolyRecursive(Ms, trackedInterval, errors, solverOptions):
12381239
originalIntervalSize = trackedInterval.size()
12391240
#Zoom in while we can
12401241
lastSizes = trackedInterval.dimSize()
1242+
start_time = time()
12411243
while changed and zoomCount <= solverOptions.maxZoomCount:
12421244
#Zoom in until we stop changing or we hit machine epsilon
12431245
Ms, errors, trackedInterval, changed, should_stop = zoomInOnIntervalIter(Ms, errors, trackedInterval, solverOptions.exact)
@@ -1248,6 +1250,7 @@ def solvePolyRecursive(Ms, trackedInterval, errors, solverOptions):
12481250
if np.all(newSizes >= lastSizes / 2): #Check all dims and use >= to account for a dimension being 0.
12491251
zoomCount += 1
12501252
lastSizes = newSizes
1253+
finish_time = time()
12511254
if should_stop:
12521255
#Start the final step if the is in the options and we aren't already in it.
12531256
if trackedInterval.finalStep or not solverOptions.useFinalStep:

yroots/Combined_Solver.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
import functools
55
import yroots.ChebyshevSubdivisionSolver as ChebyshevSubdivisionSolver
66
import yroots.ChebyshevApproximator as ChebyshevApproximator
7-
from yroots.polynomial import MultiCheb, MultiPower
7+
from yroots.polynomial import MultiCheb,MultiPower
8+
from time import time
89

910
def solve(funcs,a=-1,b=1, verbose = False, returnBoundingBoxes = False, exact=False, minBoundingIntervalSize=1e-5):
1011
"""Finds and returns the roots of a system of functions on the search interval [a,b].
@@ -106,18 +107,24 @@ def solve(funcs,a=-1,b=1, verbose = False, returnBoundingBoxes = False, exact=Fa
106107
polys = np.array(funcs)
107108
errs = np.array([0.]*dim)
108109
macheps = 2**-52
110+
unit_box = True
111+
# Check if original region is in the unit box
112+
if not np.allclose(a,-np.ones_like(a)) or not np.allclose(b,np.ones_like(b)):
113+
unit_box = False
109114
# Get an approximation for each function.
110115
if verbose:
111116
print("Approximation shapes:", end=" ")
112117
for i in range(dim):
113-
if isinstance(funcs[i], MultiPower):
118+
# t = time()
119+
if unit_box and isinstance(funcs[i], MultiPower):
114120
polys[i] = funcs[i].to_cheb()
115121
errs[i] = macheps
116-
elif isinstance(funcs[i], MultiCheb):
122+
elif unit_box and isinstance(funcs[i], MultiCheb):
117123
polys[i] = funcs[i].coeff
118124
errs[i] = macheps
119125
else:
120126
polys[i], errs[i] = ChebyshevApproximator.chebApproximate(funcs[i],a,b)
127+
# return time() - t
121128
if verbose:
122129
print(f"{i}: {polys[i].shape}", end = " " if i != dim-1 else '\n')
123130
if verbose:

0 commit comments

Comments
 (0)