/**
 * Test if (X + a) ^ n != X ^ n + a (mod X ^ r - 1,n)
 */
int check_poly(mpz_t n, mpz_t a, mpz_t r) {
  unsigned int i, terms, equality_holds;

  mpz_t tmp, neg_a, loop;
  mpz_init(tmp);
  mpz_init(neg_a);
  mpz_init(loop);

  terms = mpz_get_ui(r) + 1;
  mpz_t* poly = init_poly(terms);
  mpz_t* ptmp = init_poly(terms);
  mpz_t* stmp;

  mpz_mul_ui(neg_a, a, -1);

  mpz_set(poly[0], neg_a);
  mpz_set_ui(poly[1], 1);

  for (mpz_set_ui(loop, 2); mpz_cmp(loop, n) <= 0; mpz_mul(loop, loop, loop)) {
    polymul(ptmp, poly, terms, poly, terms, n);
    stmp = poly;
    poly = ptmp;
    ptmp = stmp;
  }

  mpz_t* xMinusA = init_poly(2);
  mpz_set(ptmp[0], neg_a);
  mpz_set_ui(ptmp[1], 1);
  for (; mpz_cmp(loop, n) <= 0; mpz_add_ui(loop, loop, 1)) {
    polymul(ptmp, poly, terms, xMinusA, 2, n);
    stmp = poly;
    poly = ptmp;
    ptmp = stmp;
  }
  clear_poly(xMinusA, 2);

  equality_holds = TRUE;
  if (mpz_cmp(poly[0], neg_a) != 0 || mpz_cmp_ui(poly[terms - 1], 1) != 0) {
    equality_holds = FALSE;
  }
  else {
    for (i = 1; i < terms - 1; i++) {
      if (mpz_cmp_ui(poly[i], 0) != 0) {
        equality_holds = FALSE;
        break;
      }
    }
  }

  clear_poly(poly, terms);
  clear_poly(ptmp, terms);

  mpz_clear(tmp);
  mpz_clear(neg_a);
  mpz_clear(loop);

  return equality_holds;
}
Esempio n. 2
0
int main( )
{
	struct poly p1, p2, p3 ;

	system ( "cls" ) ;

	initpoly ( &p1 ) ;
	initpoly ( &p2 ) ;
	initpoly ( &p3 ) ;

	polyappend ( &p1, 1, 4 ) ;
	polyappend ( &p1, 2, 3 ) ;
	polyappend ( &p1, 2, 2 ) ;
	polyappend ( &p1, 2, 1 ) ;

	polyappend ( &p2, 2, 3 ) ;
	polyappend ( &p2, 3, 2 ) ;
	polyappend ( &p2, 4, 1 ) ;

	p3 = polymul ( p1, p2 ) ;

	printf ( "First polynomial:\n" ) ;
	display ( p1 ) ;

	printf ( "Second polynomial:\n" ) ;
	display ( p2 ) ;

	printf ( "Resultant polynomial:\n" ) ;
	display ( p3 ) ;

	return 0 ;
}
Esempio n. 3
0
void fpe_mul_c(fpe_t rop, const fpe_t op1, const fpe_t op2)
{
  mydouble h[24];
  polymul(h,op1->v,op2->v);
  degred(h);
  coeffred_round_par(h); 
  int i;
  for (i=0;i<12;i++)
    rop->v[i] = h[i];
}
Esempio n. 4
0
File: fp2e.c Progetto: agl/dclxvi
// Square an fp2e, store result in rop:
void fp2e_square_c(fp2e_t rop, const fp2e_t op)
{
#ifdef N_OPS
  sqfp2ctr += 1;
#endif
  fpe_t a1, b1, r1, r2;
  mydouble ropa[24], ropb[24];
  fp2e_to_2fpe(a1, b1, op);
  int i;

/* CheckDoubles are not smart enough to recognize 
 * binomial formula to compute b^2-a^2 */
#ifdef CHECK
  mydouble d1[24];
  polymul(d1, a1->v, a1->v);
  polymul(ropb, b1->v, b1->v);
  polymul(ropa, b1->v, a1->v);
  for (i = 0; i < 23; i++) {
    ropb[i] -= d1[i];
    ropa[i] *= 2;
  }
#else
  fpe_t t1, t2, t3;
  for (i = 0; i < 12; i++) {
    t1->v[i] = a1->v[i] + b1->v[i];
    t2->v[i] = b1->v[i] - a1->v[i];
    t3->v[i] = 2 * b1->v[i];
  }
  polymul(ropa, a1->v, t3->v);
  polymul(ropb, t1->v, t2->v);
#endif

  degred(ropa);
  degred(ropb);
  coeffred_round_par(ropa);
  coeffred_round_par(ropb);

  fpe_set_doublearray(r1, ropa);
  fpe_set_doublearray(r2, ropb);
  _2fpe_to_fp2e(rop, r1, r2);
}
Esempio n. 5
0
File: fp2e.c Progetto: agl/dclxvi
// Multiply two fp2e, store result in rop:
void fp2e_mul_c(fp2e_t rop, const fp2e_t op1, const fp2e_t op2)
{
#ifdef N_OPS
  mulfp2ctr += 1;
#endif
  fpe_t a1, b1, a2, b2, r1, r2;
  mydouble a3[24], b3[24];
  int i;
  mydouble t0[24], t1[24], t2[24], t3[24];

  fp2e_to_2fpe(a1, b1, op1);
  fp2e_to_2fpe(a2, b2, op2);

  polymul(t1, a1->v, b2->v);	// t1 = a1*b2
  polymul(t2, b1->v, a2->v);	// t2 = b1*a2

  for (i = 0; i < 12; i++)	// t3 = 1*a1
  {
    t3[i] = 1 * a1->v[i];
  }
  polymul(t3, t3, a2->v);	// t3 = 1*a1*a2
  polymul(t0, b1->v, b2->v);	// t0 = b1*b2

  for (i = 0; i < 23; i++) {
    a3[i] = t1[i] + t2[i];	// a3 = a1*b2 + b1*a2
    b3[i] = t0[i] - t3[i];	// b3 = b1*b2 - 1*a1*a2
  }
  degred(a3);
  degred(b3);
  coeffred_round_par(a3);
  coeffred_round_par(b3);

  fpe_set_doublearray(r1, a3);
  fpe_set_doublearray(r2, b3);
  _2fpe_to_fp2e(rop, r1, r2);
}
Esempio n. 6
0
//
// Measure Whisker Segment Features
// --------------------------------
// <face_axis> indicates the orientation of the mouse head with respect to 
//             the image.
// <face_axis> == 'x' --> horizontally (along x axis)
// <face_axis> == 'y' --> vertically   (along y axis)
//
void Whisker_Seg_Measure( Whisker_Seg *w, double *dest, int facex, int facey, char face_axis )
{ float path_length,     //               
        median_score,    //
        root_angle_deg,  // side  poly
        mean_curvature,  //(side) poly quad?  (depends on side for sign)
        follicle_x,      // side
        follicle_y,      // side
        tip_x,           // side
        tip_y;           // side
  float *x = w->x,
        *y = w->y,
        *s = w->scores;
  int len = w->len,
      idx_follicle,
      idx_tip;
  float dx;
  static double *cumlen = NULL;
  static size_t  cumlen_size = 0;

  cumlen = request_storage( cumlen, &cumlen_size, sizeof(double), len, "measure: cumlen");
  cumlen[0] = 0.0;

  // path length
  // -----------
  // XXX: an alternate approach would be to compute the polynomial fit
  //      and do quadrature on that.  Might be more precise.
  //      Although, need cumlen (a.k.a cl) for polyfit anyway
  { float *ax = x + 1,       *ay = y + 1,
          *bx = x,           *by = y;
    double *cl = cumlen + 1, *clm = cumlen;
    while( ax < x + len )
      *cl++ = (*clm++) + hypotf( (*ax++) - (*bx++), (*ay++) - (*by++) );
    path_length = cl[-1];
  }

  // median score
  // ------------
  { qsort( s, len, sizeof(float), _score_cmp );
    if(len&1) // odd
      median_score = s[ (len-1)/2 ];
    else      //even
      median_score = ( s[len/2 - 1] + s[len/2] )/2.0;
  }

  // Follicle and root positions
  // ---------------------------
  dx = _side( w, facex, facey, &idx_follicle, &idx_tip );

  follicle_x = x[ idx_follicle ];
  follicle_y = y[ idx_follicle ];
  tip_x = x[ idx_tip ];
  tip_y = y[ idx_tip ];

  // Polynomial based measurements
  // (Curvature and angle)
  // -----------------------------
  { double px[  MEASURE_POLY_FIT_DEGREE+1 ],
           py[  MEASURE_POLY_FIT_DEGREE+1 ],
           xp[  MEASURE_POLY_FIT_DEGREE+1 ],
           yp[  MEASURE_POLY_FIT_DEGREE+1 ],
           xpp[ MEASURE_POLY_FIT_DEGREE+1 ],
           ypp[ MEASURE_POLY_FIT_DEGREE+1 ],
           mul1[ 2*MEASURE_POLY_FIT_DEGREE ],
           mul2[ 2*MEASURE_POLY_FIT_DEGREE ],
           num[  2*MEASURE_POLY_FIT_DEGREE ],
           den[  2*MEASURE_POLY_FIT_DEGREE ]; 
    static double *t = NULL;
    static size_t  t_size = 0;
    static double *xd = NULL;
    static size_t  xd_size = 0;
    static double *yd = NULL;
    static size_t  yd_size = 0;
    static double *workspace = NULL;
    static size_t  workspace_size = 0;
    int i;
    const int pad = MIN( MEASURE_POLY_END_PADDING, len/4 );

    // parameter for parametric polynomial representation
    t = request_storage(t, &t_size, sizeof(double), len, "measure");
    xd = request_storage(xd, &xd_size, sizeof(double), len, "measure");
    yd = request_storage(yd, &yd_size, sizeof(double), len, "measure");
    { int i = len; // convert floats to doubles
      while(i--)
      { xd[i] = x[i];
        yd[i] = y[i];
      }
    }

    for( i=0; i<len; i++ )
      t[i] = cumlen[i] / path_length; // [0 to 1]
#ifdef DEBUG_MEASURE_POLYFIT_ERROR
    assert(t[0] == 0.0 );
    assert( (t[len-1] - 1.0)<1e-6 );
#endif

    // polynomial fit
    workspace = request_storage( workspace, 
                                &workspace_size, 
                                 sizeof(double), 
                                 polyfit_size_workspace( len, 2*MEASURE_POLY_FIT_DEGREE ), //need 2*degree for curvature eval later
                                 "measure: polyfit workspace" );
    polyfit( t+pad, xd+pad, len-2*pad, MEASURE_POLY_FIT_DEGREE, px, workspace );
    polyfit_reuse(  yd+pad, len-2*pad, MEASURE_POLY_FIT_DEGREE, py, workspace );

#ifdef DEBUG_MEASURE_POLYFIT_ERROR
    { double err = 0.0;
      int i;
      for( i=pad; i<len-2*pad; i++ )
        err += hypot( xd[i] - polyval( px, MEASURE_POLY_FIT_DEGREE, t[i] ),
                      yd[i] - polyval( py, MEASURE_POLY_FIT_DEGREE, t[i] ) );
      err /= ((float)len);
      debug("Polyfit root mean squared residual: %f\n", err );
      assert( err < 1.0 );
    }
#endif

    // first derivative
    memcpy( xp, px, sizeof(double) * ( MEASURE_POLY_FIT_DEGREE+1 ) );
    memcpy( yp, py, sizeof(double) * ( MEASURE_POLY_FIT_DEGREE+1 ) );
    polyder_ip( xp, MEASURE_POLY_FIT_DEGREE+1, 1 );
    polyder_ip( yp, MEASURE_POLY_FIT_DEGREE+1, 1 );

    // second derivative
    memcpy( xpp, xp, sizeof(double) * ( MEASURE_POLY_FIT_DEGREE+1 ) );
    memcpy( ypp, yp, sizeof(double) * ( MEASURE_POLY_FIT_DEGREE+1 ) );
    polyder_ip( xpp, MEASURE_POLY_FIT_DEGREE+1, 1 );
    polyder_ip( ypp, MEASURE_POLY_FIT_DEGREE+1, 1 );

    // Root angle
    // ----------
    { double teval = (idx_follicle == 0) ? t[pad] : t[len-pad-1];
      static const double rad2deg = 180.0/M_PI;
      switch(face_axis)
      { case 'h':
        case 'x':
          root_angle_deg = atan2( dx*polyval(yp, MEASURE_POLY_FIT_DEGREE, teval ),
                                  dx*polyval(xp, MEASURE_POLY_FIT_DEGREE, teval ) ) * rad2deg;
          break;
        case 'v':
        case 'y':
          root_angle_deg = atan2( dx*polyval(xp, MEASURE_POLY_FIT_DEGREE, teval ),
                                  dx*polyval(yp, MEASURE_POLY_FIT_DEGREE, teval ) ) * rad2deg;
          break;
        default:
          error("In Whisker_Seg_Measure\n"
                "\tParameter <face_axis> must take on a value of 'x' or 'y'\n"
                "\tGot value %c\n",face_axis);
      }
    }

    // Mean curvature
    // --------------
    // Use the most naive of integration schemes
    { double  *V = workspace; // done with workspace, so reuse it for vandermonde matrix (just alias it here)
      static double *evalnum = NULL,
                    *evalden = NULL;
      static size_t evalnum_size = 0,
                    evalden_size = 0;
      size_t npoints = len-2*pad;
  
      evalnum = request_storage( evalnum, &evalnum_size, sizeof(double), npoints, "numerator" );
      evalden = request_storage( evalden, &evalden_size, sizeof(double), npoints, "denominator" );
  
      Vandermonde_Build( t+pad, npoints, 2*MEASURE_POLY_FIT_DEGREE, V ); // used for polynomial evaluation
  
      // numerator
      memset( mul1, 0, 2*MEASURE_POLY_FIT_DEGREE*sizeof(double) );
      memset( mul2, 0, 2*MEASURE_POLY_FIT_DEGREE*sizeof(double) );
      polymul( xp, MEASURE_POLY_FIT_DEGREE+1,
              ypp, MEASURE_POLY_FIT_DEGREE+1,
              mul1 );
      polymul( yp, MEASURE_POLY_FIT_DEGREE+1,
              xpp, MEASURE_POLY_FIT_DEGREE+1,
              mul2 );
      polysub( mul1, 2*MEASURE_POLY_FIT_DEGREE,
               mul2, 2*MEASURE_POLY_FIT_DEGREE,
               num );
  
      // denominator
      memset( mul1, 0, 2*MEASURE_POLY_FIT_DEGREE*sizeof(double) );
      memset( mul2, 0, 2*MEASURE_POLY_FIT_DEGREE*sizeof(double) );
      polymul( xp, MEASURE_POLY_FIT_DEGREE+1,
               xp, MEASURE_POLY_FIT_DEGREE+1,
              mul1 );
      polymul( yp, MEASURE_POLY_FIT_DEGREE+1,
               yp, MEASURE_POLY_FIT_DEGREE+1,
              mul2 );
      polyadd( mul1, 2*MEASURE_POLY_FIT_DEGREE,
               mul2, 2*MEASURE_POLY_FIT_DEGREE,
               den );
  
      // Eval
      matmul(   V, npoints,                   MEASURE_POLY_FIT_DEGREE*2,
              num, MEASURE_POLY_FIT_DEGREE*2, 1,
              evalnum );
      matmul(   V, npoints,                   MEASURE_POLY_FIT_DEGREE*2,
              den, MEASURE_POLY_FIT_DEGREE*2, 1,
              evalden );
      // compute kappa at each t
      { int i;
        for(i=0; i<npoints; i++ )
          evalnum[i] /= pow( evalden[i], 3.0/2.0 )*dx; //dx is 1 or -1 so dx = 1/dx;
        mean_curvature = evalnum[0] * (t[1]-t[0]);
        for(i=1; i<npoints; i++ )
          mean_curvature += evalnum[i] * ( t[i]-t[i-1] );
      }
    }
  }

  // fill in fields
  dest[0] = path_length;
  dest[1] = median_score;
  dest[2] = root_angle_deg;
  dest[3] = mean_curvature;
  dest[4] = follicle_x;
  dest[5] = follicle_y;
  dest[6] = tip_x;
  dest[7] = tip_y;
}