Difficulties in using jacobian of torch.autograd.functional

username: miraboreasu
cooked: <p>I am solving PDE, so I need the jacobian matrix of the residual with respect to variables.</p>
<p>The math is shown in the picture<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/c/6/c677c7e0dafc802b56e16bddb288fc955ad5276e.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/c677c7e0dafc802b56e16bddb288fc955ad5276e" title="WeChat Image_20220704224220"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/c/6/c677c7e0dafc802b56e16bddb288fc955ad5276e_2_375x500.jpeg" alt="WeChat Image_20220704224220" data-base62-sha1="sjJaqQImsV6Jshxgt588o2NQ4G2" width="375" height="500" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/c/6/c677c7e0dafc802b56e16bddb288fc955ad5276e_2_375x500.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/c/6/c677c7e0dafc802b56e16bddb288fc955ad5276e_2_562x750.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/c/6/c677c7e0dafc802b56e16bddb288fc955ad5276e_2_750x1000.jpeg 2x" data-dominant-color="A59B8C"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">WeChat Image_20220704224220</span><span class="informations">1920×2560 322 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>I want the vector residual to be differentiated by [pgnew[1,:,:],swnew[0,:,:],pgnew[2,:,:],swnew[1,:,:],pgnew[3,:,:],swnew[2,:,:]]</p>
<p>Here is my code</p>
<pre><code class="lang-auto">import torch
from torch.autograd.functional import jacobian
def get_residual (pgnew, swnew):
    residual_w  = 5*(swnew-swold)+T_w*((pgnew[2:,:,:]-pgnew[1:-1,:,:])-(pc[2:,:,:]-pc[1:-1,:,:])) - T_w*((pgnew[1:-1,:,:]-pgnew[0:-2,:,:])-(pc[1:-1,:,:]-pc[0:-2,:,:]))
    residual_g  = 5*((1-swnew)-(1-swold))+T_g*(pgnew[2:,:,:]-pgnew[1:-1,:,:]) - T_g*(pgnew[1:-1,:,:]-pgnew[0:-2,:,:])
    residual    = torch.ravel(torch.column_stack((residual_w,residual_g)))
    return residual

if __name__ == '__main__':
    dt       = 0.01
    T_w      = 10 
    T_g      = 12
    swnew     = torch.zeros(3, 1, 1, requires_grad=True, dtype=torch.float64)   
    swold     = torch.ones(3, 1, 1, requires_grad=True, dtype=torch.float64)     
    pgnew     = 2*torch.ones(5, 1, 1, requires_grad=True, dtype=torch.float64)
    pc        = 3*torch.ones(5, 1, 1, requires_grad=True, dtype=torch.float64)
    

    unknown  = torch.ravel(torch.column_stack((pgnew[1:-1,:,:],swnew)))
    
    residual = get_residual(pgnew, swnew)
    print('Check Jacobian \n', jacobian(get_residual, unknown))

</code></pre>
<p>I am following this tutorial <a href="https://www.geeksforgeeks.org/jacobian-matrix-in-pytorch/" class="inline-onebox" rel="noopener nofollow ugc">Jacobian matrix in PyTorch - GeeksforGeeks</a><br>
However, it shows an error, namely,</p>
<p>get_residual() missing 1 required positional argument: ‘swnew’,</p>
<p>so I change it to</p>
<pre><code class="lang-auto"> print('Check Jacobian \n', jacobian(get_residual(pgnew, swnew),unknown)
</code></pre>
<p>Then it shows ‘Tensor’ object is not callable’</p>
<p>Thank you.</p>

username: KFrank
cooked: <p>Hi Miraboreasu!</p>
<aside class="quote no-group quote-modified" data-username="miraboreasu" data-post="1" data-topic="155799" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/m/6bbea6/48.png" class="avatar"> miraboreasu:</div>
<blockquote>
<pre><code class="lang-auto">    unknown  = torch.ravel(torch.column_stack((pgnew[1:-1,:,:],swnew)))
    
    residual = get_residual(pgnew, swnew)
    print('Check Jacobian \n', jacobian(get_residual, unknown))

</code></pre>
<p>get_residual() missing 1 required positional argument: ‘swnew’,</p>
</blockquote>
</aside>
<p><a href="https://pytorch.org/docs/1.12/generated/torch.autograd.functional.jacobian.html" rel="noopener nofollow ugc">jacobian()</a> is calling your function <code>get_residual()</code>.  <em>How</em> <code>jacobian()</code> calls<br>
<code>get_residual()</code> depends on the second argument you pass to <code>jacobian()</code>.<br>
You are calling <code>jacobian()</code> with the single tensor <code>unknown</code> as its second<br>
argument, so <code>jacobian()</code> calls <code>get_residual()</code> with just a single tensor<br>
argument.  But your <code>get_residual()</code> function requires two arguments, hence<br>
the error.</p>
<aside class="quote no-group">
<blockquote>
<p>so I change it to</p>
<pre><code class="lang-auto"> print('Check Jacobian \n', jacobian(get_residual(pgnew, swnew),unknown)
</code></pre>
<p>Then it shows ‘Tensor’ object is not callable’</p>
</blockquote>
</aside>
<p><code>jacobian()</code> requires its first argument to be a function (more precisely, a<br>
“callable” – something that can be called like a function).  But you are<br>
calling <code>jacobian()</code> not with a function, but with the result of calling<br>
<code>get_residual (pgnew, swnew)</code>.  Your <code>get_residual()</code> returns a <code>Tensor</code><br>
(which isn’t a callable), hence the error.</p>
<p>Best.</p>
<p>K. Frank</p>