Skip to content

Commit

Permalink
GrpLazy can be provided a representation to use when computing the BS…
Browse files Browse the repository at this point in the history
…GS chain in the future.
  • Loading branch information
Denis Rosset committed Oct 15, 2014
1 parent 6b3ce49 commit 1f93d2d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 37 deletions.
40 changes: 20 additions & 20 deletions src/main/scala/net.alasc/math/Grp.scala
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ abstract class GrpLazyBase[G] extends Grp[G] {
def orderIfComputed: RefOption[BigInt]
def chainIfComputed: RefOption[Chain[G]]

protected def compute(givenRepresentation: RefOption[Representation[G]] = RefNone, givenBaseGuide: RefOption[BaseGuide] = RefNone): Unit
protected def computeChain(givenRepresentation: RefOption[Representation[G]] = RefNone): Chain[G]

def chain: Chain[G] = chain(representation)

Expand All @@ -130,7 +130,7 @@ abstract class GrpLazyBase[G] extends Grp[G] {
case RefOption(node: Node[G]) => algorithms.chainWithBase(node, baseGuide, representationToUse.action)
case RefOption(term: Term[G]) => term
case _ =>
compute(RefSome(representationToUse), RefSome(baseGuide))
computeChain(RefSome(representationToUse))
chain(representationToUse, baseGuide)
}
}
Expand All @@ -141,34 +141,34 @@ object Grp {
def trivial[G: ClassTag: FiniteGroup: Representations] = apply[G]()
implicit def defaultAlgorithms[G: ClassTag: FiniteGroup] = BasicAlgorithms.randomized(Random)

def fromChain[G: ClassTag: FiniteGroup: Representations](chain: Chain[G], representation: Representation[G]): Grp[G] = {
chain match {
case node: Node[G] => require(representation.action == node.action)
case _: Term[G] =>
}
new GrpChain[G](chain.generators, representation, chain)
}

def fromChain[G: ClassTag: FiniteGroup: Representations](chain: Chain[G]): Grp[G] = {
val representation = Representations[G].get(chain.generators)
def fromChain[G: ClassTag: FiniteGroup: Representations](chain: Chain[G],
representationOption: RefOption[Representation[G]] = RefNone): Grp[G] = {
val representation = representationOption.getOrElse(Representations[G].get(chain.generators))
chain match {
case node: Node[G] if representation.action != node.action =>
new GrpLazy(chain.generators, RefSome(chain.order), RefSome(chain.randomElement(_)))
case _ => fromChain(chain, representation)
new GrpLazy(chain.generators, RefSome(chain.order), RefSome(chain.randomElement(_)), representationOption)
case _ =>
new GrpChain[G](chain.generators, representation, chain)
}
}

def fromGenerators[G: ClassTag: FiniteGroup: Representations](generators: Iterable[G]): Grp[G] =
new GrpLazy[G](generators)
def fromGenerators[G: ClassTag: FiniteGroup: Representations](generators: Iterable[G],
representationOption: RefOption[Representation[G]] = RefNone): Grp[G] =
new GrpLazy[G](generators, givenRepresentation = representationOption)

def apply[G: ClassTag: FiniteGroup: Representations](generators: G*): Grp[G] =
new GrpLazy[G](generators)

def fromGeneratorsAndOrder[G: ClassTag: FiniteGroup: Representations](generators: Iterable[G], order: BigInt): Grp[G] =
new GrpLazy[G](generators, givenOrder = RefSome(order))
def fromGeneratorsAndOrder[G: ClassTag: FiniteGroup: Representations](generators: Iterable[G], order: BigInt,
representationOption: RefOption[Representation[G]] = RefNone): Grp[G] =
new GrpLazy[G](generators, givenOrder = RefSome(order), givenRepresentation = representationOption)

def fromSubgroup[S, G: ClassTag: FiniteGroup: Representations](subgroup: S)(implicit sg: Subgroup[S, G]): Grp[G] =
new GrpLazy[G](subgroup.generators, givenOrder = RefSome(subgroup.order), givenRandomElement = RefSome(subgroup.randomElement(_)))
def fromSubgroup[S, G: ClassTag: FiniteGroup: Representations](subgroup: S,
representationOption: RefOption[Representation[G]] = RefNone)(implicit sg: Subgroup[S, G]): Grp[G] =
new GrpLazy[G](subgroup.generators,
givenOrder = RefSome(subgroup.order),
givenRandomElement = RefSome(subgroup.randomElement(_)),
givenRepresentation = representationOption)

implicit def GrpSubgroup[G](implicit algebra: FiniteGroup[G]): Subgroup[Grp[G], G] = new GrpSubgroup[G]
implicit def GrpSubgroups[G](grp: Grp[G]): GrpSubgroups[G] = new GrpSubgroups[G](grp)
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/net.alasc/math/GrpLattice.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class GrpLattice[G](implicit val algorithms: BasicAlgorithms[G], val representat
val mutableChain = algorithms.mutableChainCopyWithAction(chain, rp.action)
algorithms.insertGenerators(mutableChain, generators)
algorithms.completeStrongGenerators(mutableChain)
Grp.fromChain(mutableChain.toChain, rp)
Grp.fromChain(mutableChain.toChain, RefSome(rp))
}

def join(lhs: Grp[G], rhs: Grp[G]): Grp[G] = {
Expand Down
42 changes: 28 additions & 14 deletions src/main/scala/net.alasc/math/GrpLazy.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,40 +16,54 @@ import algorithms._
/**
* @param givenOrder Known order for the group, enabling the use of faster randomized algorithms.
* @param givenRandomElement Function that provides a random element of the group, for use with randomized algorithms.
* @param givenRepresentation Representation to be used by default to compute the group chain.
*/
class GrpLazy[G](
val generators: Iterable[G],
givenOrder: RefOption[BigInt] = RefNone,
givenRandomElement: RefOption[Function1[Random, G]] = RefNone)(
givenRandomElement: RefOption[Function1[Random, G]] = RefNone,
givenRepresentation: RefOption[Representation[G]] = RefNone)(
implicit val algorithms: BasicAlgorithms[G], val representations: Representations[G]) extends GrpLazyBase[G] { lhs =>

private[this] var computedRepresentation: RefOption[Representation[G]] = RefNone
private[this] var computedChain: RefOption[Chain[G]] = RefNone
private[this] var computedRepresentation: RefOption[Representation[G]] = givenRepresentation
/** Forces the computation of the representation.
*
* @param givenRepresentation Representation to be used to avoid computation
*/
protected def computeRepresentation(givenRepresentation: RefOption[Representation[G]] = RefNone): Representation[G] =
this.synchronized {
if (computedRepresentation.isEmpty) {
if (givenRepresentation.nonEmpty)
computedRepresentation = givenRepresentation
else
computedRepresentation = RefSome(representations.get(generators))
}
computedRepresentation.get
}

protected def compute(givenRepresentation: RefOption[Representation[G]] = RefNone,
givenBaseGuide: RefOption[BaseGuide] = RefNone): Unit =
private[this] var computedChain: RefOption[Chain[G]] = RefNone
/** Forces the computation of the group chain.
*
* @param givenRepresentation Representation to be used; the one given during `GrpLazy` has priority.
*/
protected def computeChain(givenRepresentation: RefOption[Representation[G]] = RefNone): Chain[G] =
this.synchronized {
if (computedRepresentation.nonEmpty) {
assert(computedChain.nonEmpty)
} else {
assert(computedChain.isEmpty)
val representation = givenRepresentation.getOrElse(representations.get(generators))
val baseGuide = givenBaseGuide.getOrElse(BaseGuide.empty)
val baseGuide = BaseGuide.empty
if (computedChain.isEmpty) {
computedChain = RefSome(givenOrder match {
case RefOption(order) => givenRandomElement match {
case RefOption(randomElement) => algorithms.chainWithBase(generators, randomElement, order, baseGuide, representation.action)
case _ => algorithms.chainWithBase(generators, order, baseGuide, representation.action)
}
case _ => algorithms.chainWithBase(generators, baseGuide, representation.action)
})
computedRepresentation = RefSome(representation)
}
computedChain.get
}

def representation: Representation[G] = computedRepresentation match {
case RefOption(r) => r
case _ => compute()
representation
case _ => computeRepresentation()
}

def isChainComputed = computedChain.nonEmpty
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/net.alasc/math/GrpSubgroups.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class GrpSubgroups[G](val lhs: Grp[G]) {
new RightCosets(lhs, rhs)
}
def fixingPartition(partition: Domain#Partition, rp: Representation[G]): Grp[G] =
Grp.fromChain(FixingPartition.fixingPartition(lhs.chain(rp, FixingPartition.baseGuide(partition)), partition), rp)
Grp.fromChain(FixingPartition.fixingPartition(lhs.chain(rp, FixingPartition.baseGuide(partition)), partition), RefSome(rp))

def fixingPartition(partition: Domain#Partition)(implicit prp: PermutationRepresentations[G]): Grp[G] =
fixingPartition(partition, prp.forSize(partition.size))
Expand Down Expand Up @@ -79,7 +79,7 @@ class GrpSubgroups[G](val lhs: Grp[G]) {
}
val newChain = lhs.chain(rp, BaseGuideSeq(Seq(b)))
val (nextChain, transversal) = newChain.detach(b)
(Grp.fromChain(nextChain, rp), transversal)
(Grp.fromChain(nextChain, RefSome(rp)), transversal)
}
def stabilizer(b: Int)(implicit prp: PermutationRepresentations[G]): (Grp[G], Transversal[G]) = {
val rp = if (b < representation.size) representation else prp.forSize(b + 1)
Expand Down

0 comments on commit 1f93d2d

Please sign in to comment.