def pseudo_inverse(mat, eps=1e-10):
"""Computes pseudo-inverse of mat, treating eigenvalues below eps as 0."""
s, u, v = tf.svd(mat)
eps = 1e-10 # zero threshold for eigenvalues
si = tf.where(tf.less(s, eps), s, 1./s)
return u @ tf.diag(si) @ tf.transpose(v)
python类svd()的实例源码
def symsqrt(mat, eps=1e-7):
"""Symmetric square root."""
s, u, v = tf.svd(mat)
# sqrt is unstable around 0, just use 0 in such case
print("Warning, cutting off at eps")
si = tf.where(tf.less(s, eps), s, tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_sqrt2(svd, eps=1e-7):
"""half pseduo-inverse, accepting existing values"""
# zero threshold for eigenvalues
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
si = tf.where(tf.less(s, eps), s, 1./tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse2(svd, eps=1e-7):
"""pseudo-inverse, accepting existing values"""
# use float32 machine precision as cut-off (works for MKL)
# https://www.wolframcloud.com/objects/927b2aa5-de9c-46f5-89fe-c4a58aa4c04b
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
si = tf.where(s/max_eigen<eps, 0.*s, 1./s)
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_stable(svd, eps=1e-7):
"""pseudo-inverse, accepting existing values"""
# use float32 machine precision as cut-off (works for MKL)
# https://www.wolframcloud.com/objects/927b2aa5-de9c-46f5-89fe-c4a58aa4c04b
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
si = tf.where(s/max_eigen<eps, 0.*s, tf.pow(s, -0.9))
return u @ tf.diag(si) @ tf.transpose(v)
# todo: rename l to L
def regularized_inverse2(svd, L=1e-3):
"""Regularized inverse, working from SVD"""
if svd.__class__.__name__=='SvdTuple' or svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
# max_eigen = tf.Print(max_eigen, [max_eigen], "max_eigen")
#si = 1/(s + L*tf.ones_like(s)/max_eigen)
si = 1/(s+L*tf.ones_like(s))
return u @ tf.diag(si) @ tf.transpose(v)
def regularized_inverse3(svd, L=1e-3):
"""Unbiased version of regularized_inverse2"""
if svd.__class__.__name__=='SvdTuple' or svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
if L.__class__.__name__=='Var':
L = L.var
max_eigen = tf.reduce_max(s)
# max_eigen = tf.Print(max_eigen, [max_eigen], "max_eigen")
#si = 1/(s + L*tf.ones_like(s)/max_eigen)
si = (1+L*tf.ones_like(s))/(s+L*tf.ones_like(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse(mat, eps=1e-10):
"""Computes pseudo-inverse of mat, treating eigenvalues below eps as 0."""
s, u, v = tf.svd(mat)
eps = 1e-10 # zero threshold for eigenvalues
si = tf.where(tf.less(s, eps), s, 1./s)
return u @ tf.diag(si) @ tf.transpose(v)
def symsqrt(mat, eps=1e-7):
"""Symmetric square root."""
s, u, v = tf.svd(mat)
# sqrt is unstable around 0, just use 0 in such case
print("Warning, cutting off at eps")
si = tf.where(tf.less(s, eps), s, tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_sqrt(mat, eps=1e-7):
"""half pseduo-inverse"""
s, u, v = tf.svd(mat)
# zero threshold for eigenvalues
si = tf.where(tf.less(s, eps), s, 1./tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse2(svd, eps=1e-7):
"""pseudo-inverse, accepting existing values"""
# use float32 machine precision as cut-off (works for MKL)
# https://www.wolframcloud.com/objects/927b2aa5-de9c-46f5-89fe-c4a58aa4c04b
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
si = tf.where(s/max_eigen<eps, 0.*s, 1./s)
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_stable(svd, eps=1e-7):
"""pseudo-inverse, accepting existing values"""
# use float32 machine precision as cut-off (works for MKL)
# https://www.wolframcloud.com/objects/927b2aa5-de9c-46f5-89fe-c4a58aa4c04b
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
si = tf.where(s/max_eigen<eps, 0.*s, tf.pow(s, -0.9))
return u @ tf.diag(si) @ tf.transpose(v)
# todo: rename l to L
def regularized_inverse2(svd, L=1e-3):
"""Regularized inverse, working from SVD"""
if svd.__class__.__name__=='SvdTuple' or svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
# max_eigen = tf.Print(max_eigen, [max_eigen], "max_eigen")
#si = 1/(s + L*tf.ones_like(s)/max_eigen)
si = 1/(s+L*tf.ones_like(s))
return u @ tf.diag(si) @ tf.transpose(v)
def regularized_inverse3(svd, L=1e-3):
"""Unbiased version of regularized_inverse2"""
if svd.__class__.__name__=='SvdTuple' or svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
if L.__class__.__name__=='Var':
L = L.var
max_eigen = tf.reduce_max(s)
# max_eigen = tf.Print(max_eigen, [max_eigen], "max_eigen")
#si = 1/(s + L*tf.ones_like(s)/max_eigen)
si = (1+L*tf.ones_like(s))/(s+L*tf.ones_like(s))
return u @ tf.diag(si) @ tf.transpose(v)
def regularized_inverse4(svd, L=1e-3):
"""Uses relative norm"""
if svd.__class__.__name__=='SvdTuple' or svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
if L.__class__.__name__=='Var':
L = L.var
max_eigen = tf.reduce_max(s)
L = L/max_eigen
si = (1+L*tf.ones_like(s))/(s+L*tf.ones_like(s))
# si = tf.ones_like(s)
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse(mat, eps=1e-10):
"""Computes pseudo-inverse of mat, treating eigenvalues below eps as 0."""
s, u, v = tf.svd(mat)
eps = 1e-10 # zero threshold for eigenvalues
si = tf.where(tf.less(s, eps), s, 1./s)
return u @ tf.diag(si) @ tf.transpose(v)
def symsqrt(mat, eps=1e-7):
"""Symmetric square root."""
s, u, v = tf.svd(mat)
# sqrt is unstable around 0, just use 0 in such case
print("Warning, cutting off at eps")
si = tf.where(tf.less(s, eps), s, tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_sqrt(mat, eps=1e-7):
"""half pseduo-inverse"""
s, u, v = tf.svd(mat)
# zero threshold for eigenvalues
si = tf.where(tf.less(s, eps), s, 1./tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_sqrt2(svd, eps=1e-7):
"""half pseduo-inverse, accepting existing values"""
# zero threshold for eigenvalues
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
si = tf.where(tf.less(s, eps), s, 1./tf.sqrt(s))
return u @ tf.diag(si) @ tf.transpose(v)
def pseudo_inverse_stable(svd, eps=1e-7):
"""pseudo-inverse, accepting existing values"""
# use float32 machine precision as cut-off (works for MKL)
# https://www.wolframcloud.com/objects/927b2aa5-de9c-46f5-89fe-c4a58aa4c04b
if svd.__class__.__name__=='SvdTuple':
(s, u, v) = (svd.s, svd.u, svd.v)
elif svd.__class__.__name__=='SvdWrapper':
(s, u, v) = (svd.s, svd.u, svd.v)
else:
assert False, "Unknown type"
max_eigen = tf.reduce_max(s)
si = tf.where(s/max_eigen<eps, 0.*s, tf.pow(s, -0.9))
return u @ tf.diag(si) @ tf.transpose(v)
# todo: rename l to L