/* main method that inverts an nxn matrix A and returns U and A inverse in its parameters double *a = square invertible matrix A that is to be inverted int n = dimension of A double *u = the orthogonalized matrix U returned in this double *b = the inverse of A returned in this */ void inv_double_gs(double *a, int n, double *u, double *b) { Matrix aMat = createMatrix(a,n); // an nxn identity matrix Matrix id = idMat(n); // transpose aMat so as to run GS on its columns transposeMatrix(aMat); // run GS ... orthogonalizes aMat by columns gramSchmidt(aMat,id); // aMat is now U transpose // get G matrix transposeMatrix(id); //printMatrix(aMat); //print U transpose //printMatrix(id); //print G // A inverse = G * U transpose Matrix ainv = initMatrix(n); matMul(id,aMat,ainv); //printMatrix(ainv); //print inverse of A //return U in double *u and A inverse in double *b params transposeMatrix(aMat); flattenMatrix(aMat,u); flattenMatrix(ainv,b); // clean up all matrices destroyMatrix(aMat); destroyMatrix(id); destroyMatrix(ainv); }
//! Compute Lanczos basis static void computeNormalized(ordinal_type k, const vectorspace_type& vs, const operator_type& A, const vector_type& u_init, matrix_type& u, Teuchos::Array<value_type>& alpha, Teuchos::Array<value_type>& beta, Teuchos::Array<value_type>& nrm_sqrd) { // u[i-1], u[i], u[i+1] vector_type u0, u1, u2; // set starting vector u0 = Teuchos::getCol(Teuchos::View, u, 0); u0.assign(u_init); u1 = u0; vector_type v = vs.create_vector(); for (ordinal_type i=0; i<k; i++) { // Compute (u_i,u_i) beta[i] = std::sqrt(vs.inner_product(u1, u1)); u1.scale(1.0/beta[i]); nrm_sqrd[i] = value_type(1.0); // Compute v = A*u_i A.apply(u1, v); // Compute (v,u_i) alpha[i] = vs.inner_product(u1, v); // Compute u_{i+1} = v - alpha_i*u_i - beta_i*u_{i-1} if (i < k-1) { u2 = Teuchos::getCol(Teuchos::View, u, i+1); if (i == 0) vs.add2(value_type(1), v, -alpha[i], u1, u2); else vs.add3(value_type(1), v, -alpha[i], u1, -beta[i], u0, u2); gramSchmidt(i+1, vs, u, u2); } // std::cout << "i = " << i // << " alpha = " << alpha[i] << " beta = " << beta[i] // << " nrm = " << nrm_sqrd[i] << std::endl; TEUCHOS_TEST_FOR_EXCEPTION(nrm_sqrd[i] < 0, std::logic_error, "Stokhos::LanczosProjPCEBasis::lanczos(): " << " Polynomial " << i << " out of " << k << " has norm " << nrm_sqrd[i] << "!"); // Shift -- these are just pointer copies u0 = u1; u1 = u2; } }
// The main execution int main(void) { int bla; bla = 0; Start: srand(time(0)); //srand(0); char filestring[500]; snprintf(filestring, 500, "dim%usd%u-LLL.txt", N, SEED); importBasis(filestring); gramSchmidt(); initKlein(); initParams(); initHashes(); initStack(); printf("===== HashSieve ======\n" ); printf("Dimension (N): %8d\n", N); printf("Hash length (K): %7d\n", K); printf("Hash tables (T): %7d\n", T); printf("Random seed: %8d\n", SEED); //printf("Probe level: %8d\n", PROBE); //printf("Hypersimplex: %8d\n", SIMPLEX); printf("Target norm^2: %8d\n", Target); printf("------------------------\n"); // Some dummy variables used in the algorithm int i,j,k,m,n,t; LatticeVector** Candidates; LatticeVector* v; LatticeVector* w; int vHash[T]; // "Temporary" variable for hashes of a target vector v and its rotations LatticeVector vrot[N]; int vHashp; // Shifted hashes of v used for probing only int wHash[T]; // "Temporary" variable for hashes of a candidate vector w long long int vw; long long int vwAbs; long long int vwAbsDouble; long long int NCandidates; int vReduced; time_t start = time(NULL); time_t now; time_t end; int rot; LatticeVector *shortest; // The main algorithm loop while(Iteration < MAX_ITERATIONS && Collisions2 < MAX_COLLISIONS_2){ Iteration++; // Get vector from stack, or sample a new one if the stack is empty if(StackLength == 0){ if(VectorsLength == MAX_VECTORS){ perror("Vector list overflow...\n"); goto End; } sampleKlein(&Vectors[VectorsLength++]); //sampleSimple(&Vectors[VectorsLength++]); while(Vectors[VectorsLength-1].Norm2 == 0 && Collisions1 < MAX_COLLISIONS_1){ Collisions1++; sampleKlein(&Vectors[VectorsLength-1]); //sampleSimple(&Vectors[VectorsLength-1]); } v = &Vectors[VectorsLength-1]; } else{ v = Stack[--StackLength]; } vReduced = 0; // Check each table for candidate near list vectors for(t = 0; t < T; t++){ // Compute v's hash value vHash[t] = lshash(v, t); Hashes += K; Candidates = HashTables[t][vHash[t]].Pointers; NCandidates = HashTables[t][vHash[t]].Length; // Go through the list to find reducing vectors for(j = NCandidates - 1; j >= 0; j--){ w = Candidates[j]; vw = ip(v, w); Comparisons++; vwAbs = (vw > 0 ? vw : -vw); vwAbsDouble = (vwAbs << 1); // Reduce v with w if possible if(vwAbsDouble > w->Norm2){ add(v, w, vw); Reductions1++; vReduced = 1; goto vEnd; } // Reduce w with v if possible if(vwAbsDouble > v->Norm2){ // Remove w from the hash tables for(int tt = 0; tt < T; tt++){ wHash[tt] = lshash(w, tt); Hashes += K; bucketRemove(&HashTables[tt][wHash[tt]], w); } // Reduce w with v add(w, v, vw); Reductions2++; if(w->Norm2 > 0) Stack[StackLength++] = w; else Collisions2++; } } } vEnd: // We have reached a decision for vector v // Push v to stack, list, or delete altogether if(vReduced == 0){ if(v->Norm2 > 0){ // Push v to the hash tables for(t = 0; t < T; t++) bucketAdd(&HashTables[t][vHash[t]], v); // Check for new minimum if(v->Norm2 < MinNorm2){ now = time(NULL); printf("New minimum: %11llu (%5d sec)\n", v->Norm2, (now - start)); MinNorm2 = v->Norm2; } if(v->Norm2 <= Target){ now = time(NULL); printf("Target found: %10llu (%5d sec)\n", v->Norm2, (now - start)); break; } } else{ Collisions2++; } } else{ // Append v to the stack Stack[StackLength++] = v; } } End: end = time(NULL); printf("------------------------\n"); // Formatting the time taken int Time = end - start; int Timesec = Time % 60; int Timemin = (Time / 60) % 60; int Timehr = (Time / 3600) % 24; int Timeday = (Time / 86400); if(Timeday == 0) printf("Time: %02u:%02u:%02u (hh:mm:ss)\n", Timehr, Timemin, Timesec); else printf("Time: (%3ud) %02u:%02u:%02u (hh:mm:ss)\n", Timeday, Timehr, Timemin, Timesec); // Formatting the main space costs double Space = (T * VectorsLength * sizeof(void*)) + (VectorsLength * N * sizeof(Vectors[0].Crd[0])); if(Space < 1000) printf("Est. space: %12f (bytes)\n", Space); else if (Space < 1000000) printf("Est. space: %12f (kB)\n", Space / 1000); else if (Space < 1000000000) printf("Est. space: %12f (MB)\n", Space / 1000000); else if (Space < 1000000000000) printf("Est. space: %12f (GB)\n", Space / 1000000000); else printf("Est. space: %12f (TB)\n", Space / 1000000000000); printf("------------------------\n"); printf("Iterations: %10llu\n", Iteration); printf("Inner products\n"); printf("- Comparing:%12llu\n", Comparisons); printf("- Hashing: %13llu\n", Hashes); printf("- Total: %13llu\n", (Comparisons + Hashes)); printf("Reductions v: %10llu\n", Reductions1); printf("Reductions w: %10llu\n", Reductions2); printf("Vectors: %10llu\n", VectorsLength); printf("List length: %10llu\n", VectorsLength - Collisions2 - StackLength); printf("Stack length: %10llu\n", StackLength); printf("Collisions\n"); printf("- Sampling 0: %10llu\n", Collisions1); printf("- Reducing: %10llu\n", Collisions2); printf("- Total: %10llu\n", Collisions1 + Collisions2); printf("Shortest: %10llu\n\n", MinNorm2); bla++; if(bla < 1){ goto Start; } }
bool fromJson(const rapidjson::Value &v, Mat4f &dst) { if (v.IsArray()) { ASSERT(v.Size() == 16, "Cannot convert Json Array to 4x4 Matrix: Invalid size"); for (unsigned i = 0; i < 16; ++i) dst[i] = as<float>(v[i]); return true; } else if (v.IsObject()) { Vec3f x(1.0f, 0.0f, 0.0f); Vec3f y(0.0f, 1.0f, 0.0f); Vec3f z(0.0f, 0.0f, 1.0f); Vec3f pos(0.0f); fromJson(v, "position", pos); bool explicitX = false, explicitY = false, explicitZ = false; Vec3f lookAt; if (fromJson(v, "look_at", lookAt)) { z = lookAt - pos; explicitZ = true; } explicitY = fromJson(v, "up", y); explicitX = fromJson(v, "x_axis", x) || explicitX; explicitY = fromJson(v, "y_axis", y) || explicitY; explicitZ = fromJson(v, "z_axis", z) || explicitZ; int id = (explicitZ ? 4 : 0) + (explicitY ? 2 : 0) + (explicitX ? 1 : 0); switch (id) { case 0: gramSchmidt(z, y, x); break; case 1: gramSchmidt(x, z, y); break; case 2: gramSchmidt(y, z, x); break; case 3: gramSchmidt(y, x, z); break; case 4: gramSchmidt(z, y, x); break; case 5: gramSchmidt(z, x, y); break; case 6: gramSchmidt(z, y, x); break; case 7: gramSchmidt(z, y, x); break; } if (x.cross(y).dot(z) < 0.0f) { if (!explicitX) x = -x; else if (!explicitY) y = -y; else z = -z; } Vec3f scale; if (fromJson(v, "scale", scale)) { x *= scale.x(); y *= scale.y(); z *= scale.z(); } Vec3f rot; if (fromJson(v, "rotation", rot)) { Mat4f tform = Mat4f::rotYXZ(rot); x = tform*x; y = tform*y; z = tform*z; } dst = Mat4f( x[0], y[0], z[0], pos[0], x[1], y[1], z[1], pos[1], x[2], y[2], z[2], pos[2], 0.0f, 0.0f, 0.0f, 1.0f ); return true; } return false; }