Example #1
0
DoubleCRT& DoubleCRT::Op(const DoubleCRT &other, Fun fun,
			 bool matchIndexSets)
{
  if (dryRun) return *this;

  if (&context != &other.context)
    Error("DoubleCRT::Op: incompatible objects");

  // Match the index sets, if needed
  if (matchIndexSets && !(map.getIndexSet() >= other.map.getIndexSet()))
    addPrimes(other.map.getIndexSet() / map.getIndexSet()); // This is expensive

  // If you need to mod-up the other, do it on a temporary scratch copy
  DoubleCRT tmp(context, IndexSet()); 
  const IndexMap<vec_long>* other_map = &other.map;
  if (!(map.getIndexSet() <= other.map.getIndexSet())){ // Even more expensive
    tmp = other;
    tmp.addPrimes(map.getIndexSet() / other.map.getIndexSet());
    other_map = &tmp.map;
  }

  const IndexSet& s = map.getIndexSet();
  long phim = context.zMStar.getPhiM();

  // add/sub/mul the data, element by element, modulo the respective primes
  for (long i = s.first(); i <= s.last(); i = s.next(i)) {
    long pi = context.ithPrime(i);
    vec_long& row = map[i];
    const vec_long& other_row = (*other_map)[i];
    
    for (long j = 0; j < phim; j++)
      row[j] = fun.apply(row[j], other_row[j], pi);
  }
  return *this;
}
Example #2
0
// Generic operators, Fnc is either AddMod or SubMod
// This should have been a template, but gcc refuses to cooperate
SingleCRT& SingleCRT::Op(const SingleCRT &other,
			 void (*Fnc)(ZZ&, const ZZ&, const ZZ&, const ZZ&),
			 bool matchIndexSets)
{
 if (&context != &other.context)
    Error("SingleCRT::Op: incomopatible objects");

  // Match the index sets, if needed
  if (matchIndexSets && !(map.getIndexSet() >= other.map.getIndexSet()))
    addPrimes(other.map.getIndexSet() / map.getIndexSet());  // This is expensive

  // INVARIANT: map.getIndexSet() >= other.map.getIndexSet()) 

  SingleCRT tmp(context); // a rare case where you want an empty SingleCRT object
  const IndexMap<ZZX>* other_map = &other.map;
  if (map.getIndexSet() > other.map.getIndexSet()) { // Even more expensive
    tmp = other;
    tmp.addPrimes(map.getIndexSet() / other.map.getIndexSet());
    other_map = &tmp.map;
  }

  const IndexSet& s = map.getIndexSet();

  // add/sub polynomial, modulo the respective primes

  for (long i = s.first(); i <= s.last(); i = s.next(i)) {
    ZZ pi = to_ZZ(context.ithPrime(i));
    vec_ZZ& vp1 = map[i].rep;
    const vec_ZZ& vp2 = (*other_map)[i].rep;

    long len1 = vp1.length();
    long len2 = vp2.length();
    long maxlen = max(len1, len2);
    vp1.SetLength(maxlen);
    for (long j=len1; j < maxlen; j++) clear(vp1[j]);
    for (long j=0; j<len2; j++) 
      Fnc(vp1[j], vp1[j], vp2[j], pi);
    map[i].normalize();
  }
  return *this;
}