<commit_before>import { opModZ } from '../spacegroups/spacegroups';
import { buildDSymbol } from '../dsymbols/delaney';
import { minimal } from '../dsymbols/derived';
import * as common from './common';

import {
  coordinateChangesQ as opsQ,
  coordinateChangesF as opsF
} from '../geometry/types';


const mapFace = (face, toPrimitive) =>
  face.map(p => opsF.times(toPrimitive, opsF.point(p)));


const applyOpsToPoint = (p, offset, symOps, pointsEqFn) => {
  const inStabilizer = op => pointsEqFn(p, common.applyToPoint(op, p));
  const sub = common.subgroup(symOps, inStabilizer);
  const reps = common.cosetReps(symOps, inStabilizer);

  const images = {};

  for (let i = 0; i < reps.length; ++i) {
    for (const op of sub)
      images[opModZ(opsQ.times(reps[i], op))] = offset + i;
  }

  const result = [];

  for (const r of reps) {
    const point = opsF.modZ(common.applyToPoint(r, p));

    const action = {};
    for (const op of symOps)
      action[op] = images[opModZ(opsQ.times(op, r))];

    result.push([ point, action ]);
  }

  return result;
};


const applyOpsToCorners = (rawFaces, symOps, pointsEqFn) => {
  const pos = [];
  const action = [];
  const faces = [];

  for (const rf of rawFaces) {
    const face = [];

    for (const p of rf) {
      const found = pos.findIndex(q => pointsEqFn(p, q));
      const index = found < 0 ? pos.length : found;

      if (found < 0) {
        for (const [p, a] of applyOpsToPoint(p, index, symOps, pointsEqFn)) {
          pos.push(p);
          action.push(a);
        }
      }

      const shift = opsF.minus(p, pos[index]).map(x => opsF.round(x));
      face.push({ index, shift });
    }

    faces.push(face);
  }

  return { pos, action, faces };
};


const compareCorners = (c1, c2) => (
  opsF.cmp(c1.index, c2.index) || opsF.cmp(c1.shift, c2.shift)
);


const compareFaces = (f1, f2) => {
  for (const i in f1) {
    const d = compareCorners(f1[i], f2[i]);
    if (d)
      return d;
  }
  return 0;
};


const compareShiftedFaces = (p, q) => (
  compareFaces(p.face, q.face) || opsF.cmp(p.shift, q.shift)
);


const compareTiles = (ps, qs) => {
  for (const i in ps) {
    const d = compareShiftedFaces(ps[i], qs[i]);
    if (d)
      return d;
  }
  return 0;
};


const normalizedFace = face => {
  let best, bestShift;

  for (const i in face) {
    const s = face[i].shift;
    const fs = face.map(
      ({ index, shift }) => ({ index, shift: opsF.minus(shift, s) })
    );

    const fa = fs.slice(i).concat(fs.slice(0, i))
    if (best == null || compareFaces(fa, best) < 0)
      [ best, bestShift ] = [ fa, s ];

    const fb = [fa[0]].concat(fa.slice(1).reverse());
    if (compareFaces(fb, best) < 0)
      [ best, bestShift ] = [ fb, s ];
  }

  return { face: best, shift: bestShift };
};


const normalizedTile = tile => {
  let best = null;

  for (const { shift: s } of tile) {
    const mapped = tile.map(
      ({ face, shift }) => ({ face, shift: opsF.minus(shift, s) })
    );
    mapped.sort(compareShiftedFaces)

    if (best == null || compareTiles(best, mapped) < 0)
      best = mapped;
  }

  return best;
};


const cornerAction = (pos, action) => (op, c) => {
  const newPos = common.applyToPoint(op, opsF.plus(pos[c.index], c.shift));
  const index = action[c.index][op];
  const shift = opsF.minus(newPos, pos[index]).map(x => opsF.round(x));

  return { index, shift };
};


const applyOpsToFaces = ({ pos, action, faces }, symOps) => {
  const apply = cornerAction(pos, action);
  const seen = {};
  const result = [];

  for (const f of faces) {
    for (const op of symOps) {
      const { face: fNew } = normalizedFace(f.map(e => apply(op, e)));
      const key = JSON.stringify(fNew);

      if (!seen[key]) {
        seen[key] = true;
        result.push(fNew);
      }
    }
  }

  return result;
};


const applyOpsToTiles = ({ pos, action, faces }, tiles, symOps) => {
  const apply = cornerAction(pos, action);
  const seen = {};
  const result = [];

  for (const t of tiles) {
    for (const op of symOps) {
      const mappedFaces = t.map(
        i => normalizedFace(faces[i].map(e => apply(op, e)))
      );
      const tNew = normalizedTile(mappedFaces);
      const key = JSON.stringify(tNew);

      if (!seen[key]) {
        seen[key] = true;
        result.push(tNew);
      }
    }
  }

  return result;
};

<commit_msg>faceList: refactor applyOpsToFaces() and applyOpsToTiles()<commit_after>import { opModZ } from '../spacegroups/spacegroups';
import { buildDSymbol } from '../dsymbols/delaney';
import { minimal } from '../dsymbols/derived';
import * as common from './common';

import {
  coordinateChangesQ as opsQ,
  coordinateChangesF as opsF
} from '../geometry/types';


const mapFace = (face, toPrimitive) =>
  face.map(p => opsF.times(toPrimitive, opsF.point(p)));


const applyOpsToPoint = (p, offset, symOps, pointsEqFn) => {
  const inStabilizer = op => pointsEqFn(p, common.applyToPoint(op, p));
  const sub = common.subgroup(symOps, inStabilizer);
  const reps = common.cosetReps(symOps, inStabilizer);

  const images = {};

  for (let i = 0; i < reps.length; ++i) {
    for (const op of sub)
      images[opModZ(opsQ.times(reps[i], op))] = offset + i;
  }

  const result = [];

  for (const r of reps) {
    const point = opsF.modZ(common.applyToPoint(r, p));

    const action = {};
    for (const op of symOps)
      action[op] = images[opModZ(opsQ.times(op, r))];

    result.push([ point, action ]);
  }

  return result;
};


const applyOpsToCorners = (rawFaces, symOps, pointsEqFn) => {
  const pos = [];
  const action = [];
  const faces = [];

  for (const rf of rawFaces) {
    const face = [];

    for (const p of rf) {
      const found = pos.findIndex(q => pointsEqFn(p, q));
      const index = found < 0 ? pos.length : found;

      if (found < 0) {
        for (const [p, a] of applyOpsToPoint(p, index, symOps, pointsEqFn)) {
          pos.push(p);
          action.push(a);
        }
      }

      const shift = opsF.minus(p, pos[index]).map(x => opsF.round(x));
      face.push({ index, shift });
    }

    faces.push(face);
  }

  return { pos, action, faces };
};


const compareCorners = (c1, c2) => (
  opsF.cmp(c1.index, c2.index) || opsF.cmp(c1.shift, c2.shift)
);


const compareFaces = (f1, f2) => {
  for (const i in f1) {
    const d = compareCorners(f1[i], f2[i]);
    if (d)
      return d;
  }
  return 0;
};


const compareShiftedFaces = (p, q) => (
  compareFaces(p.face, q.face) || opsF.cmp(p.shift, q.shift)
);


const compareTiles = (ps, qs) => {
  for (const i in ps) {
    const d = compareShiftedFaces(ps[i], qs[i]);
    if (d)
      return d;
  }
  return 0;
};


const normalizedFace = face => {
  let best, bestShift;

  for (const i in face) {
    const s = face[i].shift;
    const fs = face.map(
      ({ index, shift }) => ({ index, shift: opsF.minus(shift, s) })
    );

    const fa = fs.slice(i).concat(fs.slice(0, i))
    if (best == null || compareFaces(fa, best) < 0)
      [ best, bestShift ] = [ fa, s ];

    const fb = [fa[0]].concat(fa.slice(1).reverse());
    if (compareFaces(fb, best) < 0)
      [ best, bestShift ] = [ fb, s ];
  }

  return { face: best, shift: bestShift };
};


const normalizedTile = tile => {
  let best = null;

  for (const { shift: s } of tile) {
    const mapped = tile.map(
      ({ face, shift }) => ({ face, shift: opsF.minus(shift, s) })
    );
    mapped.sort(compareShiftedFaces)

    if (best == null || compareTiles(best, mapped) < 0)
      best = mapped;
  }

  return best;
};


const mappedFace = (op, face, pos, action) => {
  const mapped = [];

  for (const { index, shift } of face) {
    const p = common.applyToPoint(op, opsF.plus(pos[index], shift));
    const i = action[index][op];
    const s = opsF.minus(p, pos[i]).map(x => opsF.round(x));

    mapped.push({ index: i, shift: s });
  }

  return normalizedFace(mapped);
};


const applyOpsToFaces = ({ pos, action, faces }, symOps) => {
  const seen = {};
  const result = [];

  for (const f of faces) {
    for (const op of symOps) {
      const { face: fNew } = mappedFace(op, f, pos, action);
      const key = JSON.stringify(fNew);

      if (!seen[key]) {
        seen[key] = true;
        result.push(fNew);
      }
    }
  }

  return result;
};


const applyOpsToTiles = ({ pos, action, faces }, tiles, symOps) => {
  const seen = {};
  const result = [];

  for (const t of tiles) {
    for (const op of symOps) {
      const mapped = t.map(i => mappedFace(op, faces[i], pos, action));
      const tNew = normalizedTile(mapped);
      const key = JSON.stringify(tNew);

      if (!seen[key]) {
        seen[key] = true;
        result.push(tNew);
      }
    }
  }

  return result;
};


{'fraction_non_alphanumeric': 0.16871341673361642, 'fraction_numerical': 0.005049925398829335, 'mean_word_length': 2.6939381093683763, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3054346', 'n_tokens_mistral': 3231, 'n_tokens_neox': 3116, 'n_words': 817}