UV partial derivatives of a cylinder shape primitive I am new to rendering and I would like to calcualte UV partial derivatives of a cylinder shape, which is parameterized by radius $R$ and length $L$.
Using cylindrical coordinate mapping, for a surface point $\mathbf{p}=(x,y,z)$, the UV map (normalized to $[0,1]$) is:
$$
(u,v) = \Big(\frac{\phi}{2\pi}, \frac{z}{L}\Big)\qquad \text{where} \quad \phi = \arctan \frac{y}{x}
$$
Then I compute the derivatives with respect to $\mathbf{p}$, that is:
$$
\begin{aligned}
\frac{\partial u}{\partial \mathbf{p}} &amp; = \frac{1}{2\pi R^2} \Big( -y, x, 0\Big) = \frac{1}{2\pi R} \Big( -\sin\phi, \cos\phi, 0\Big)\\
\frac{\partial v}{\partial \mathbf{p}} &amp;= \Big( 0, 0, \frac{1}{L}\Big)
\end{aligned}
$$
Or equivalently:
$$
\begin{aligned}
\frac{\partial \mathbf{p}}{\partial u} &amp; = 2\pi R \Big( -\frac{1}{\sin\phi}, \frac{1}{\cos\phi}, 0\Big)\\
\frac{\partial \mathbf{p}}{\partial v} &amp;= \Big( 0, 0, L\Big)
\end{aligned}
$$
Everything looks good until now.
Question
In pbrt-3, the relevant part of cylinder.cpp is: (i) UV same as above; (ii) $\partial \mathbf{p}/\partial u$ however is different:
Float u = phi / phiMax;
Float v = (pHit.z - zMin) / (zMax - zMin);

// Compute cylinder $\dpdu$ and $\dpdv$
Vector3f dpdu(-phiMax * pHit.y, phiMax * pHit.x, 0);
Vector3f dpdv(0, 0, zMax - zMin);

What am I missing here?
I think it's easiest to get the tangent frame by writing the forward mapping from $(u,v)$ to $\mathbf{p}$:
$$
    \mathbf{p}(u,v) = \begin{bmatrix} R \, \cos (2\pi u) \\ R \, \sin (2\pi u) \\ vL \end{bmatrix}
$$
Then you can see that the derivatives are:
$$
    \frac{\partial\mathbf{p}}{\partial u} = \begin{bmatrix} -2\pi R \, \sin(2\pi u) \\ 2\pi R \, \cos(2\pi u) \\ 0\end{bmatrix} = \begin{bmatrix} -2\pi y \\ 2\pi x \\ 0\end{bmatrix}, \qquad
    \frac{\partial\mathbf{p}}{\partial v} = \begin{bmatrix} 0 \\ 0 \\ L \end{bmatrix}
$$
which matches the pbrt code.
I think your derivation went wrong by assuming that $\partial\mathbf{p}/\partial u$ was the component-wise reciprocal of $\partial u / \partial{\mathbf{p}}$. It's not so simple, because the latter object is really the gradient of $u$, where $u$ is now considered as a scalar field defined over all space (not just on the cylinder). To invert this properly we really need another coordinate running perpendicular to $u$ in the $xy$ plane, so that we have a locally invertible mapping; then we can take its Jacobian matrix and invert that. We can use the radius $R$ as such a coordinate. Then we have the inverse mapping,
$$
\begin{aligned}
    u(x,y) &amp;= \frac{1}{2\pi} \arctan(y,x) \\
    R(x,y) &amp;= \sqrt{x^2 + y^2}
\end{aligned}
$$
whose Jacobian is:
$$
    \frac{\partial(u,R)}{\partial(x,y)} =
    \begin{bmatrix}
        \tfrac{\partial u}{\partial x} &amp; \tfrac{\partial u}{\partial y} \\
        \tfrac{\partial R}{\partial x} &amp; \tfrac{\partial R}{\partial y}
    \end{bmatrix} =
    \begin{bmatrix}
        -y/(2\pi R^2) &amp; x/(2\pi R^2) \\
        x/R &amp; y/R
    \end{bmatrix}
$$
and the inverse of that is:
$$
    \frac{\partial(x,y)}{\partial(u,R)} =
    -2\pi R \begin{bmatrix}
        y/R &amp; -x/(2\pi R^2) \\
        -x/R &amp; -y/(2\pi R^2)
    \end{bmatrix} =
    \begin{bmatrix}
        -2\pi y &amp; x/R \\
        2\pi x &amp; y/R
    \end{bmatrix}
$$
from which you can then read off $\partial{(x,y)}/\partial u$ as the first column, which matches the result obtained for $\partial\mathbf{p}/\partial u$ above.