def apply_layerwise_transform_fn_to_multiple_activations(
        self,
        layerwise_transform_fn: MultiArgLayerwiseTransformFn,  # input to Callable is N tensors
        # this must take a layer_index kwarg, to distinguish it from the arbitrary number of tensor args
        others: tuple["ActivationsAndMetadata", ...],  # N - 1 entries
        output_dst: DerivedScalarType,
        output_pass_type: PassType,
    ) -> "ActivationsAndMetadata":
        """Same as above, but the transform_fn takes
        two tensors as arguments, and the activations_by_layer_index tensors from 'other' are used
        as the second argument."""

        def _layerwise_transform_multiple_activations_by_layer_index(
            activations_by_layer_index: dict[LayerIndex, torch.Tensor],
            layerwise_transform_fn: MultiArgLayerwiseTransformFn,
            other_activations_by_layer_index_tuple: tuple[dict[LayerIndex, torch.Tensor], ...],
        ) -> dict[LayerIndex, torch.Tensor]:
            for other_activations_by_layer_index in other_activations_by_layer_index_tuple:
                assert set(activations_by_layer_index.keys()) == set(
                    other_activations_by_layer_index.keys()
                ), (
                    f"{activations_by_layer_index.keys()=} , "
                    f"{other_activations_by_layer_index.keys()=}"
                )
            return {
                layer_index: layerwise_transform_fn(
                    activations,
                    *[
                        other_activations_by_layer_index[layer_index]
                        for other_activations_by_layer_index in other_activations_by_layer_index_tuple
                    ],
                    layer_index=layer_index,
                )
                for layer_index, activations in activations_by_layer_index.items()
            }

        self_activations_by_layer_index = self.activations_by_layer_index
        other_activations_by_layer_index_tuple = tuple(
            other.activations_by_layer_index for other in others
        )
        for other_activations_by_layer_index in other_activations_by_layer_index_tuple:
            assert set(other_activations_by_layer_index.keys()) == set(
                self_activations_by_layer_index.keys()
            ), (
                f"{other_activations_by_layer_index.keys()=} , "
                f"{self_activations_by_layer_index.keys()=}"
            )

        return dataclasses.replace(
            self,
            activations_by_layer_index=_layerwise_transform_multiple_activations_by_layer_index(
                self_activations_by_layer_index,
                layerwise_transform_fn=layerwise_transform_fn,
                other_activations_by_layer_index_tuple=other_activations_by_layer_index_tuple,
            ),
            dst=output_dst,
            pass_type=output_pass_type,
        )
Same as above, but the transform_fn takes
        two tensors as arguments, and the activations_by_layer_index tensors from 'other' are used
        as the second argument.
neuron_explainer/activations/derived_scalars/activations_and_metadata.py