Skip to content

Commit

Permalink
Extracting reduction modulo a basis set to a static method in Chain.s…
Browse files Browse the repository at this point in the history
…cala
  • Loading branch information
Mikael Vejdemo-Johansson committed Nov 12, 2024
1 parent 5a66112 commit 9442ad3
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 20 deletions.
14 changes: 14 additions & 0 deletions src/main/scala/org/appliedtopology/tda4j/Chain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ object Chain {
}
}

@tailrec
final def reduceBy[CellT : Ordering, CoefficientT : Field](z : Chain[CellT, CoefficientT],
basis: mutable.Map[CellT, Chain[CellT, CoefficientT]],
reductionLog: Chain[CellT, CoefficientT] = Chain()
): (Chain[CellT, CoefficientT], Chain[CellT, CoefficientT]) =
z.leadingCell match {
case None => (z, reductionLog)
case Some(sigma) =>
if basis.contains(sigma) then
val redCoeff = z.leadingCoefficient / basis(sigma).leadingCoefficient
reduceBy(z - redCoeff basis(sigma), basis, reductionLog + redCoeff Chain(sigma))
else (z, reductionLog)
}

given [CellT : Ordering, CoefficientT: Field as fr] => (Chain[CellT, CoefficientT] is RingModule {
type R = CoefficientT
}) = new {
Expand Down
24 changes: 4 additions & 20 deletions src/main/scala/org/appliedtopology/tda4j/Homology.scala
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class SimplicialHomologyByDimensionContext[VertexT: Ordering, CoefficientT: Fiel
val dEdge = edge.boundary
// TODO is it worth it to have a more complex UnionFind that allows us to get the entire path along the MST?
val (reduced, reductionLog): (Chain[Simplex[VertexT], CoefficientT], Chain[Simplex[VertexT], CoefficientT]) =
reduceBy(dEdge, boundaries)
Chain.reduceBy(dEdge, boundaries)
val fr = summon[CoefficientT is Field]
val coboundary: Chain[Simplex[VertexT], CoefficientT] =
reductionLog.items.foldRight(fr.negate(fr.one) Chain(edge)) { (item, acc) =>
Expand All @@ -205,29 +205,13 @@ class SimplicialHomologyByDimensionContext[VertexT: Ordering, CoefficientT: Fiel
// setup is done, we should be ready to start dimension 2
currentDim = 1
current = Double.PositiveInfinity

@tailrec
private def reduceBy(
z: Chain[Simplex[VertexT], CoefficientT],
basis: mutable.Map[Simplex[VertexT], Chain[Simplex[VertexT], CoefficientT]],
reductionLog: Chain[Simplex[VertexT], CoefficientT] = Chain()
)(using
fr: (CoefficientT is Field)
): (Chain[Simplex[VertexT], CoefficientT], Chain[Simplex[VertexT], CoefficientT]) =
z.leadingCell match
case None => (z, reductionLog)
case Some(sigma) =>
if basis.contains(sigma) then
val redCoeff = fr.divide(z.leadingCoefficient, basis(sigma).leadingCoefficient)
reduceBy(z - redCoeff basis(sigma), basis, reductionLog + redCoeff Chain(sigma))
else (z, reductionLog)


def advanceOne(): Unit =
if currentIterator.hasNext then
val fr = summon[CoefficientT is Field]
val sigma = currentIterator.next()
val dsigma: Chain[Simplex[VertexT], CoefficientT] = sigma.boundary
val (dsigmaReduced, reduction) = reduceBy(dsigma, boundaries)
val (dsigmaReduced, reduction) = Chain.reduceBy(dsigma, boundaries)
val coboundary = reduction.items.foldRight(fr.negate(fr.one) Chain(sigma)) { (next, acc) =>
val (spx, coeff) = next
if coboundaries.contains(spx) then acc + coeff coboundaries(spx)
Expand All @@ -243,7 +227,7 @@ class SimplicialHomologyByDimensionContext[VertexT: Ordering, CoefficientT: Fiel
boundariesBornBy(dsigmaReduced.leadingCell.get) = sigma
coboundaries(dsigmaReduced.leadingCell.get) = coboundary

val (_, cycleBasis) = reduceBy(dsigmaReduced, cycles)
val (_, cycleBasis) = Chain.reduceBy(dsigmaReduced, cycles)
val representativeCycle: Chain[Simplex[VertexT], CoefficientT] = cycleBasis.leadingCell match
case None => Chain()
case Some(cell) => cycles(cell)
Expand Down

0 comments on commit 9442ad3

Please sign in to comment.