Source code for mipcandy.common.numpy.regressions
import numpy as np
[docs]
def quotient_regression(x: np.ndarray, y: np.ndarray, m: int, n: int) -> tuple[np.ndarray, np.ndarray]:
matrix = []
for xi, yi in zip(x, y):
row = []
for k in range(m + 1):
row.append(xi ** k)
for k in range(1, n + 1):
row.append(-yi * xi ** k)
matrix.append(row)
matrix = np.array(matrix)
coefficients, _, _, _ = np.linalg.lstsq(matrix, y, rcond=None)
return coefficients[:m + 1][::-1], np.concatenate(([1.0], coefficients[m + 1:]))[::-1]
[docs]
def quotient_derivative(a: np.ndarray, b: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
da = np.polyder(a)
db = np.polyder(b)
return np.polysub(np.polymul(da, b), np.polymul(a, db)), np.polymul(b, b)
[docs]
def quotient_bounds(a: np.ndarray, b: np.ndarray, lower_bound: float | None, upper_bound: float | None, *,
x_start: float = 0, x_stop: float = 1e4, x_step: float = .01) -> tuple[float, float] | None:
x = np.arange(x_start, x_stop, x_step)
y = np.polyval(a, x) / np.polyval(b, x)
mask = np.array(True, like=y)
if lower_bound is not None:
mask = mask & (y > lower_bound)
if upper_bound is not None:
mask = mask & (y < upper_bound)
if isinstance(mask, bool):
raise ValueError("Bounds must be specified on at least one side")
return (float(x[mask][0]), float(x[mask][-1])) if mask.any() else None