public final MVPerm compose(MVPerm perm) { MVPerm res = new MVPerm(); for (int i = 0; i < this.elems.length; i++) { ModelValue mv = this.elems[i]; if (mv == null) { res.put(i, perm.elems[i]); } else { ModelValue mv1 = perm.elems[mv.index]; if (mv1 == null) { res.put(i, mv); } else if (!ModelValue.mvs[i].equals(mv1)) { res.put(i, mv1); } } } return res; }
public static final MVPerm[] permutationSubgroup(ValueEnumeration varEnum) { Set perms = new Set(20); Vect permVec = new Vect(20); // Compute the group generators: Value elem; while ((elem = varEnum.nextElement()) != null) { FcnRcdValue fcn = FcnRcdValue.convert(elem); if (fcn == null) { Assert.fail("The symmetry operator must specify a set of functions."); } MVPerm perm = new MVPerm(); for (int i = 0; i < fcn.domain.length; i++) { Value dval = fcn.domain[i]; Value rval = fcn.values[i]; if ((dval instanceof ModelValue) && (rval instanceof ModelValue)) { perm.put((ModelValue) dval, (ModelValue) rval); } else { Assert.fail("Symmetry function must have model values as domain and range."); } } if (perm.size() > 0 && perms.put(perm) == null) { permVec.addElement(perm); } } // Compute the group generated by the generators: int gsz = permVec.size(); int sz0 = 0; while (true) { int sz1 = permVec.size(); for (int i = 0; i < gsz; i++) { MVPerm perm1 = (MVPerm) permVec.elementAt(i); for (int j = sz0; j < sz1; j++) { MVPerm perm = perm1.compose((MVPerm) permVec.elementAt(j)); if (perm.size() > 0 && perms.put(perm) == null) { permVec.addElement(perm); } } } if (sz1 == permVec.size()) break; sz0 = sz1; } // Finally, put all the elements in an array ready for use: MVPerm[] res = new MVPerm[permVec.size()]; Enumeration permEnum = permVec.elements(); for (int i = 0; i < res.length; i++) { res[i] = (MVPerm) permEnum.nextElement(); } return res; }