static void ComputeGS(mat_ZZ& B, xdouble **B1, xdouble **mu, xdouble *b, xdouble *c, long k, xdouble bound, long st, xdouble *buf) { long n = B.NumCols(); long i, j; xdouble s, t1, y, t; ZZ T1; xdouble *mu_k = mu[k]; if (st < k) { for (i = 1; i < st; i++) buf[i] = mu_k[i]*c[i]; } for (j = st; j <= k-1; j++) { if (b[k]*b[j] < NTL_FDOUBLE_PRECISION*NTL_FDOUBLE_PRECISION) { double z = 0; xdouble *B1_k = B1[k]; xdouble *B1_j = B1[j]; for (i = 1; i <= n; i++) z += B1_k[i].x * B1_j[i].x; s = z; } else { s = InnerProduct(B1[k], B1[j], n); if (s*s <= b[k]*b[j]/bound) { InnerProduct(T1, B(k), B(j)); conv(s, T1); } } xdouble *mu_j = mu[j]; t1 = 0; for (i = 1; i <= j-1; i++) MulAdd(t1, t1, mu_j[i], buf[i]); mu_k[j] = (buf[j] = (s - t1))/c[j]; } s = 0; for (j = 1; j <= k-1; j++) MulAdd(s, s, mu_k[j], buf[j]); c[k] = b[k] - s; }
/* * Multiplies pxo1 with pxo2 and stores the result in pxo. * returns complexity hint * | efM11 efM12 0 | * | efM21 efM22 0 | * | efDx efDy 1 | */ ULONG NTAPI XFORMOBJ_iCombine( IN XFORMOBJ *pxo, IN XFORMOBJ *pxo1, IN XFORMOBJ *pxo2) { MATRIX mx; PMATRIX pmx, pmx1, pmx2; /* Get the source matrices */ pmx1 = XFORMOBJ_pmx(pxo1); pmx2 = XFORMOBJ_pmx(pxo2); /* Do a 3 x 3 matrix multiplication with mx as destinantion */ MulAdd(&mx.efM11, &pmx1->efM11, &pmx2->efM11, &pmx1->efM12, &pmx2->efM21); MulAdd(&mx.efM12, &pmx1->efM11, &pmx2->efM12, &pmx1->efM12, &pmx2->efM22); MulAdd(&mx.efM21, &pmx1->efM21, &pmx2->efM11, &pmx1->efM22, &pmx2->efM21); MulAdd(&mx.efM22, &pmx1->efM21, &pmx2->efM12, &pmx1->efM22, &pmx2->efM22); MulAdd(&mx.efDx, &pmx1->efDx, &pmx2->efM11, &pmx1->efDy, &pmx2->efM21); FLOATOBJ_Add(&mx.efDx, &pmx2->efDx); MulAdd(&mx.efDy, &pmx1->efDx, &pmx2->efM12, &pmx1->efDy, &pmx2->efM22); FLOATOBJ_Add(&mx.efDy, &pmx2->efDy); /* Copy back */ pmx = XFORMOBJ_pmx(pxo); *pmx = mx; /* Update accelerators and return complexity */ return XFORMOBJ_UpdateAccel(pxo); }
NTL_START_IMPL static xdouble InnerProduct(xdouble *a, xdouble *b, long n) { xdouble s; long i; s = 0; for (i = 1; i <= n; i++) MulAdd(s, s, a[i], b[i]); return s; }
SCBigInteger::SCBigInteger(std::string val) { size_t size = ESTIMATE(val.length()); // estimate words (crude, 16-bit) if (size < MINALLOC) size = MINALLOC; dataAlloc = size; dataArray = (BIWORD *)malloc(sizeof(BIWORD) * dataAlloc); dataArray[0] = 0; dataSize = 0; isNeg = false; isNan = false; const char *c = val.c_str(); if (*c == '-') { isNeg = true; ++c; } while (*c) { MulAdd(10, *c++ - '0'); } }
void solve1(ZZ& d_out, vec_ZZ& x_out, const mat_ZZ& A, const vec_ZZ& b) { long n = A.NumRows(); if (A.NumCols() != n) LogicError("solve1: nonsquare matrix"); if (b.length() != n) LogicError("solve1: dimension mismatch"); if (n == 0) { set(d_out); x_out.SetLength(0); return; } ZZ num_bound, den_bound; hadamard(num_bound, den_bound, A, b); if (den_bound == 0) { clear(d_out); return; } zz_pBak zbak; zbak.save(); long i; long j; ZZ prod; prod = 1; mat_zz_p B; for (i = 0; ; i++) { zz_p::FFTInit(i); mat_zz_p AA, BB; zz_p dd; conv(AA, A); inv(dd, BB, AA); if (dd != 0) { transpose(B, BB); break; } mul(prod, prod, zz_p::modulus()); if (prod > den_bound) { d_out = 0; return; } } long max_A_len = MaxBits(A); long use_double_mul1 = 0; long use_double_mul2 = 0; long double_limit = 0; if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_DOUBLE_PRECISION-1) use_double_mul1 = 1; if (!use_double_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_DOUBLE_PRECISION-1) { use_double_mul2 = 1; double_limit = (1L << (NTL_DOUBLE_PRECISION-1-max_A_len-NTL_SP_NBITS)); } long use_long_mul1 = 0; long use_long_mul2 = 0; long long_limit = 0; if (max_A_len + NTL_SP_NBITS + NumBits(n) <= NTL_BITS_PER_LONG-1) use_long_mul1 = 1; if (!use_long_mul1 && max_A_len+NTL_SP_NBITS+2 <= NTL_BITS_PER_LONG-1) { use_long_mul2 = 1; long_limit = (1L << (NTL_BITS_PER_LONG-1-max_A_len-NTL_SP_NBITS)); } if (use_double_mul1 && use_long_mul1) use_long_mul1 = 0; else if (use_double_mul1 && use_long_mul2) use_long_mul2 = 0; else if (use_double_mul2 && use_long_mul1) use_double_mul2 = 0; else if (use_double_mul2 && use_long_mul2) { if (long_limit > double_limit) use_double_mul2 = 0; else use_long_mul2 = 0; } double **double_A=0; double *double_h=0; Unique2DArray<double> double_A_store; UniqueArray<double> double_h_store; if (use_double_mul1 || use_double_mul2) { double_h_store.SetLength(n); double_h = double_h_store.get(); double_A_store.SetDims(n, n); double_A = double_A_store.get(); for (i = 0; i < n; i++) for (j = 0; j < n; j++) double_A[j][i] = to_double(A[i][j]); } long **long_A=0; long *long_h=0; Unique2DArray<long> long_A_store; UniqueArray<long> long_h_store; if (use_long_mul1 || use_long_mul2) { long_h_store.SetLength(n); long_h = long_h_store.get(); long_A_store.SetDims(n, n); long_A = long_A_store.get(); for (i = 0; i < n; i++) for (j = 0; j < n; j++) long_A[j][i] = to_long(A[i][j]); } vec_ZZ x; x.SetLength(n); vec_zz_p h; h.SetLength(n); vec_ZZ e; e = b; vec_zz_p ee; vec_ZZ t; t.SetLength(n); prod = 1; ZZ bound1; mul(bound1, num_bound, den_bound); mul(bound1, bound1, 2); while (prod <= bound1) { conv(ee, e); mul(h, B, ee); if (use_double_mul1) { for (i = 0; i < n; i++) double_h[i] = to_double(rep(h[i])); double_MixedMul1(t, double_h, double_A, n); } else if (use_double_mul2) { for (i = 0; i < n; i++) double_h[i] = to_double(rep(h[i])); double_MixedMul2(t, double_h, double_A, n, double_limit); } else if (use_long_mul1) { for (i = 0; i < n; i++) long_h[i] = to_long(rep(h[i])); long_MixedMul1(t, long_h, long_A, n); } else if (use_long_mul2) { for (i = 0; i < n; i++) long_h[i] = to_long(rep(h[i])); long_MixedMul2(t, long_h, long_A, n, long_limit); } else MixedMul(t, h, A); // t = h*A SubDiv(e, t, zz_p::modulus()); // e = (e-t)/p MulAdd(x, prod, h); // x = x + prod*h mul(prod, prod, zz_p::modulus()); } vec_ZZ num, denom; ZZ d, d_mod_prod, tmp1; num.SetLength(n); denom.SetLength(n); d = 1; d_mod_prod = 1; for (i = 0; i < n; i++) { rem(x[i], x[i], prod); MulMod(x[i], x[i], d_mod_prod, prod); if (!ReconstructRational(num[i], denom[i], x[i], prod, num_bound, den_bound)) LogicError("solve1 internal error: rat recon failed!"); mul(d, d, denom[i]); if (i != n-1) { if (denom[i] != 1) { div(den_bound, den_bound, denom[i]); mul(bound1, num_bound, den_bound); mul(bound1, bound1, 2); div(tmp1, prod, zz_p::modulus()); while (tmp1 > bound1) { prod = tmp1; div(tmp1, prod, zz_p::modulus()); } rem(tmp1, denom[i], prod); rem(d_mod_prod, d_mod_prod, prod); MulMod(d_mod_prod, d_mod_prod, tmp1, prod); } } } tmp1 = 1; for (i = n-1; i >= 0; i--) { mul(num[i], num[i], tmp1); mul(tmp1, tmp1, denom[i]); } x_out.SetLength(n); for (i = 0; i < n; i++) { x_out[i] = num[i]; } d_out = d; }