83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
import numpy as np
|
|
import utils.vector_utils as vector_utils
|
|
|
|
|
|
def weighted_least_squares(A,y,weights):
|
|
"""Computes the weighted least squares solution of Ax=y.
|
|
|
|
Args:
|
|
A (Array ...,u,v): Design matrix.
|
|
y (Array ...,u): Target values.
|
|
weights (Array ...,u): Weights for each equation.
|
|
|
|
Returns:
|
|
Array ...,v : Weighted least squares solution.
|
|
"""
|
|
pinv = np.linalg.pinv(A*weights[...,np.newaxis])
|
|
result = np.einsum('...uv,...v->...u',pinv,y*weights)
|
|
return result
|
|
|
|
def least_squares(A,y):
|
|
"""Computes the least squares solution of Ax=y.
|
|
|
|
Args:
|
|
A (Array ...,u,v): Design matrix.
|
|
y (Array ...,u): Target values.
|
|
|
|
Returns:
|
|
Array ...,v : Least squares solution.
|
|
"""
|
|
result = weighted_least_squares(A,y,np.ones(A.shape[0]))
|
|
return result
|
|
|
|
def iteratively_reweighted_least_squares(A,y, epsilon=1e-5, it=20):
|
|
"""Computes the iteratively reweighted least squares solution. of Ax=y
|
|
|
|
Args:
|
|
A (Array ..., u, v): Design matrix.
|
|
y (Array ..., u): Target values.
|
|
epsilon (float, optional): Small value to avoid division by zero. Defaults to 1e-5.
|
|
it (int, optional): Number of iterations. Defaults to 20.
|
|
|
|
Returns:
|
|
Array ..., v: Iteratively reweighted least squares solution.
|
|
"""
|
|
weights = np.ones(y.shape)
|
|
for _ in range(it):
|
|
result = weighted_least_squares(A,y,weights)
|
|
ychap = np.einsum('...uv,...v->...u',A,result)
|
|
delta = np.abs(ychap-y)
|
|
weights = np.reciprocal(np.maximum(epsilon,np.sqrt(delta)))
|
|
return result
|
|
|
|
|
|
def matrix_kernel(A):
|
|
"""Computes the eigenvector corresponding to the smallest eigenvalue of the matrix A.
|
|
|
|
Args:
|
|
A (Array ..., n, n): Input square matrix.
|
|
|
|
Returns:
|
|
Array ..., n: Eigenvector corresponding to the smallest eigenvalue.
|
|
"""
|
|
eigval, eigvec = np.linalg.eig(A)
|
|
min_index = np.argmin(np.abs(eigval),axis=-1)
|
|
min_eigvec = np.take_along_axis(eigvec,min_index[...,None,None],-1)[...,0]
|
|
normed_eigvec = vector_utils.norm_vector(min_eigvec)[1]
|
|
return normed_eigvec
|
|
|
|
def masked_least_squares(A,y,mask):
|
|
"""Computes the least squares solution of Ax = y for masked data.
|
|
|
|
Args:
|
|
A (Array ..., n, p): Design matrix.
|
|
y (Array ..., n): Target values.
|
|
mask (Array ..., n, bool): Mask to select valid data points.
|
|
|
|
Returns:
|
|
Array ..., p: Least squares solution for the masked data.
|
|
"""
|
|
masked_solver = lambda A,y,mask : least_squares(A[mask,:],y[mask])
|
|
vectorized = np.vectorize(masked_solver,signature='(n,p),(n),(n)->(p)')
|
|
result = vectorized(A,y,mask)
|
|
return result |