Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/torchjd/aggregation/_aggregator_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@
def __str__(self) -> str:
return f"{self.__class__.__name__}"

def __lshift__(self, other: "Aggregator") -> "Composition":
from torchjd.aggregation.composition import Composition

Check warning on line 48 in src/torchjd/aggregation/_aggregator_bases.py

View check run for this annotation

Codecov / codecov/patch

src/torchjd/aggregation/_aggregator_bases.py#L48

Added line #L48 was not covered by tests

if isinstance(other, Composition):
return Composition([*other.aggregators, self])
elif isinstance(self, Composition):
return Composition([*self.aggregators, other])
return Composition([other, self])

Check warning on line 54 in src/torchjd/aggregation/_aggregator_bases.py

View check run for this annotation

Codecov / codecov/patch

src/torchjd/aggregation/_aggregator_bases.py#L50-L54

Added lines #L50 - L54 were not covered by tests


class WeightedAggregator(Aggregator):
"""
Expand Down
25 changes: 25 additions & 0 deletions torchjd/aggregation/composition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import torch
from torch import Tensor
from typing import Sequence
from torchjd.aggregation.abstract import Aggregator

class Composition(Aggregator):
"""
Composes a sequence of aggregators/transforms into a single aggregator.
Executes each aggregator sequentially on the Jacobian matrix.
"""
def __init__(self, aggregators: Sequence[Aggregator]):
super().__init__()
if not aggregators:
raise ValueError("Aggregators sequence cannot be empty.")
self.aggregators = list(aggregators)

def __call__(self, matrix: Tensor) -> Tensor:
out = matrix
for aggregator in self.aggregators:
out = aggregator(out)
return out

def __repr__(self) -> str:
names = [agg.__class__.__name__ for agg in self.aggregators]
return f"Composition({', '.join(names)})"
Loading