A naive question about the extend vjp used in netket. #1332
|
Hi, there, I have a naive question when reading the source codes of extend vjp in netket, def vjp_rc(
fun: Callable, *primals, has_aux: bool = False, conjugate: bool = False
) -> Union[Tuple[Any, Callable], Tuple[Any, Callable, Any]]:
if has_aux:
def real_fun(*primals):
val, aux = fun(*primals)
return val.real, aux
def imag_fun(*primals):
val, aux = fun(*primals)
return val.imag, aux
vals_r, vjp_r_fun, aux = jax.vjp(real_fun, *primals, has_aux=True)
vals_j, vjp_j_fun, _ = jax.vjp(imag_fun, *primals, has_aux=True)
else:
real_fun = lambda *primals: fun(*primals).real
imag_fun = lambda *primals: fun(*primals).imag
vals_r, vjp_r_fun = jax.vjp(real_fun, *primals, has_aux=False)
vals_j, vjp_j_fun = jax.vjp(imag_fun, *primals, has_aux=False)
primals_out = vals_r + 1j * vals_j
def vjp_fun(ȳ):
"""
function computing the vjp product for a R->C function.
"""
ȳ_r = ȳ.real
ȳ_j = ȳ.imag
# val = vals_r + vals_j
vr_jr = vjp_r_fun(jnp.asarray(ȳ_r, dtype=vals_r.dtype))
vj_jr = vjp_r_fun(jnp.asarray(ȳ_j, dtype=vals_r.dtype))
vr_jj = vjp_j_fun(jnp.asarray(ȳ_r, dtype=vals_j.dtype))
vj_jj = vjp_j_fun(jnp.asarray(ȳ_j, dtype=vals_j.dtype))
r = tree_map(
lambda re, im: re + 1j * im,
vr_jr,
vj_jr,
)
i = tree_map(lambda re, im: re + 1j * im, vr_jj, vj_jj)
out = tree_map(lambda re, im: re + 1j * im, r, i)
if conjugate:
out = tree_map(jnp.conjugate, out)
return out
if has_aux:
return primals_out, vjp_fun, aux
else:
return primals_out, vjp_funAs we all known, the jax.vjp is used for calculating the gradient in reverse-mode, such as def f(x, y):
return x+1, 2*y**2-1
primals, f_vjp = jax.vjp(f, 1., 2.)
xbar, ybar = f_vjp((1.,1.))
print(xbar)
print(ybar)we calculate the gradient of x and y when the inputs are x=1. and y=2. my question is why it returns vjp_fun at the end instead of [vjp_r_fun,vjp_i_fun]? P.S. def f(x, y):
return x**2+2*j*y
params = jnp.array([1., 2.])
_, vjp_funs = vjp(lambda w: func(w),
params,
conjugate=True) # if I return [vjp_r_fun,vjp_i_fun]
grad_r = vjp_funs[0](1.)
grad_i = vjp_funs[1](1.)
grad = grad_r+grad_iit returns me grad_r = [2., 2.], it seems right when we need to separately update the real parameters x and y. |
Replies: 1 comment 3 replies
|
I don't understand what you are saying, also because your snippets don't run for me. For info, I suspect that whatever you might be computing is not that. |

I don't understand what you are saying, also because your snippets don't run for me.
Can you write a snippet that does not run and maybe the mathematical formula corresponding to it so that we can see what is wrong?
For info,$f(z) = u(x, y) + iv(x, y) $ , $z =x+iy $ and vector $v=c+id$ .
nk.jax.vjp(f, z)(v)computes the following, assumingI suspect that whatever you might be computing is not that.