code: def test_cardinality(self, device, dtype, input_shape, cdtype):
      z = torch.randn(input_shape, dtype=cdtype, device=device)
      s = So2(z)
      theta = torch.rand(input_shape, dtype=dtype, device=device)
      assert s.z.shape == input_shape
      assert (s * s).z.shape == input_shape
      assert s.exp(theta).z.shape == input_shape
      assert s.log().shape == input_shape
      if not any(input_shape):
          expected_hat_shape = (2, 2)
      else:
          expected_hat_shape = (input_shape[0], 2, 2)
      assert s.hat(theta).shape == expected_hat_shape
      assert s.inverse().z.shape == input_shape
  
imports: import pytest
  import torch
  from kornia.geometry.liegroup import So2
  from kornia.geometry.vector import Vector2
  from kornia.testing import BaseTester
label_desc: Use image node_id 3 for calling the TestSo2 obj's underlying member method code with example usage: obj.test_cardinality(device, dtype, input_shape, cdtype) without return types