pypose.Parameter¶
- class pypose.Parameter(data=None, requires_grad=True, sjac=False)[source]¶
Parameterwraps atorch.Tensororpypose.LieTensor. When setting sjac=True, it tracks all operations performed on the tensor, allowing PyPose’s sparse backend to build structured sparse Jacobians.- Parameters:
data (Tensor or LieTensor) – parameter data.
requires_grad (bool, optional) – if the parameter requires gradient. Default:
Truesjac (bool, optional) – if
True, sparse Jacobian tracing is enabled. Default:False
Use sjac=True together with
pypose.autograd.function.parallel_for_sparse_jacobian()(aliaspsjac()) for anypypose.Parameterthat needs to be optimized with the sparse backend, when the optimization model is instantiated.Note
Recommend to use alias
pypose.autograd.function.psjac()for brevity.Warning
Wrap the original batched tensor before performing any operation. If you use a regular tensor or LieTensor instead, the sparse backend will not recover the Jacobian for the tensor.
Note
Parameterdoes not change numerical results. It only adds tracing information for sparse Jacobian construction when setting sjac=True.Example
Below,
self.posesandself.points_3dare the optimization variables in a bundle-adjustment model.pp.Parameter(..., sjac=True)records the indexing and reprojection operations so the sparse backend knows how each entry in the output depends on these variables. This includes tracingpsjac()functions as well, so the dependency throughprojectis preserved.observations,camera_indices, andpoint_indicesdo not need to be wrapped inParameterbecause they are fixed inputs, not optimization variables.import pypose as pp from torch import nn from pypose.autograd.function import psjac class Reproj(nn.Module): def __init__(self, poses, points_3d): # self.points_3d: tensor (P, 3), self.poses: pp.SE3 (C, 7) super().__init__() self.poses = pp.Parameter(poses, sjac=True) self.points_3d = pp.Parameter(points_3d, sjac=True) @psjac def project(points, poses): # points: tensor (N, 3), poses: pp.SE3 (N, 7) # returns: (N, 2) points = poses.Act(points) return -points[..., :2] / points[..., 2].unsqueeze(-1) def forward(self, observations, camera_indices, point_indices): # observations: tensor (N, 2), camera_indices: (N,), point_indices: (N,) poses = self.poses[camera_indices] points = self.points_3d[point_indices] points_proj = Reproj.project(points, poses) return points_proj - observations