static void MakeQ(int n, int spl, const Matrix_t **endo) { int i; int dim = endo[0]->Nor; Matrix_t *q = MatAlloc(endo[0]->Field,spl,dim*dim); char fn[200]; for (i = 0; i < spl; ++i) { int j; Matrix_t *y = MatInverse(Trans[n]), *x; MatMul(y,endo[i]); x = MatTransposed(y); MatFree(y); for (j = 0; j < dim; ++j) MatCopyRegion(q,i,j * dim,x,j,0,1,-1); MatFree(x); } sprintf(fn,"%s.q.%d",TkiName,n+1); MESSAGE(2,("Writing %s\n",fn)); #if 0 if (InfoM.Cf[TKInfo.CfIndex[0][n]].peakword < 0) MatMulScalar(q,FF_ZERO); #endif MatSave(q,fn); MatFree(q); }
//---------------------------------------------------------------------------- // Main function int main(int argc, char* argv[]) { int i,j; double **Result_Seq; int no_thrd; if(argc != 3) { fprintf(stderr, "missing arguments\n", argv[0]); exit(1); } //N =3; //no_thrd = 2; N = atoi(argv[1]); no_thrd = atoi(argv[2]); InitializeMatrix(); Result_Seq = MatMul(); // row and column initialization row =0; col=0; MatMul_thrd(no_thrd); if(Check_result(Result_Seq)) printf("\n----------------Results are same for both versions-------------------\n\n"); else printf("\n-----#####----Error: Both result are not same-------####---------\n\n"); return 0; }
// Run a single benchmark for multiplying m x k x n with num_steps of recursion. // To just call GEMM, set num_steps to zero. // The median of five trials is printed to std::cout. // If run_check is true, then it also void SingleBenchmark(int m, int k, int n, int alg) { // Run a set number of trials and pick the median time. int num_trials = 5; std::vector<double> times(num_trials); for (int trial = 0; trial < kNumTrials; ++trial) { Matrix<double> A = RandomMatrix<double>(m, k); Matrix<double> B = RandomMatrix<double>(k, n); Matrix<double> C(m, n); if (alg == CLASSICAL) { times[trial] = Time([&] { MatMul(A, B, C); }); } else if (alg == STRASSEN) { times[trial] = Time([&] { strassen::FastMatmul(A, B, C, 1); }); } else if (alg == STRASSEN_SCALED) { times[trial] = Time([&] { Matrix<double> A_roi = A; Matrix<double> B_roi = B; std::vector<double> r_roi, s_roi; Scaling(A_roi, B_roi, kNumScalingSteps, r_roi, s_roi, OUTSIDE_INSIDE); strassen::FastMatmul(A, B, C, 1); PostProcessScaling(C, r_roi, s_roi); }); } } // Spit out the median time std::sort(times.begin(), times.end()); size_t ind = num_trials / 2; std::cout << " " << m << " " << k << " " << n << " " << " " << times[ind] << "; "; }
static void gkond(const Lat_Info *li, int i, Matrix_t *b, Matrix_t *k, Matrix_t *w, const char *name) { char fn[LAT_MAXBASENAME+10]; Matrix_t *x1, *x2; x1 = MatDup(k); MatMul(x1,w); x2 = QProjection(b,x1); sprintf(fn,"%s%s.%s",li->BaseName,Lat_CfName(li,i),name); MatSave(x2,fn); MatFree(x1); MatFree(x2); }
int main(int argc, char **argv) { int m = 8000; int k = 3600; int n = 3600; int numsteps = 1; Matrix<double> A = RandomMatrix<double>(m, k); Matrix<double> B = RandomMatrix<double>(k, n); Matrix<double> C1(m, n), C2(m, n); Time([&] { MatMul(A, B, C1); }, "Classical gemm"); Time([&] { grey433_29_234::FastMatmul(A, B, C2, numsteps); }, "Fast (4, 3, 3)"); // Test for correctness. std::cout << "Maximum relative difference: " << MaxRelativeDiff(C1, C2) << std::endl; return 0; }
int main(int argc, char **argv) { int m = 2000; int k = 1200; int n = 2000; int numsteps = 1; Matrix<double> A = RandomMatrix<double>(m, k); Matrix<double> B = RandomMatrix<double>(k, n); Matrix<double> C1(m, n), C2(m, n); Time([&] { MatMul(A, B, C1); }, "Classical gemm"); Time([&] { classical222_8_24::FastMatmul(A, B, C2, numsteps); }, "Classical recursive (2, 2, 2)"); // Test for correctness. std::cout << "Maximum relative difference: " << MaxRelativeDiff(C1, C2) << std::endl; return 0; }
int main(int argc, char** args) { Matrix a; mat_init(a, HEIGHT_OF_A, WIDTH_OF_A); Matrix b; mat_init(b, HEIGHT_OF_B, WIDTH_OF_B); Matrix c; mat_init(c, HEIGHT_OF_A, WIDTH_OF_B); mat_print(a, "The matrix A:\n"); mat_print(b, "The matrix B:\n"); printf("APPLYING KERNEL...\n\n"); MatMul(a, b, c); // MatMul_Fast(a, b, c); mat_print(c, "The result:\n"); mat_free(a); mat_free(b); mat_free(c); }
int main(int argc, char **argv) { // if (argc != 2) { // printf("usage: n\n"); // return -1; // } //int nnn = atoi(argv[1]); //int n = 1 << nnn; int n = N; srand(time(0)); Matrix A, B, C; A.width = A.height = n; A.elements = (float *)malloc(sizeof(float) * n * n); B.width = B.height = n; B.elements = (float *)malloc(sizeof(float) * n * n); C.width = C.height = n; C.elements = (float *)malloc(sizeof(float) * n * n); fill_Matrix(A); //print_Matrix(A); //printf("\n"); fill_Matrix(B); //print_Matrix(B); //printf("\n"); stopwatch_restart(); MatMul(A, B, C); printf("time = %llu us \n", (long long unsigned)stopwatch_record()); //print_Matrix(C); }
int main (int argc, char *argv[]) { int i, j, N, M; TYPE *A, *B, *C; if (argc == 3){ N = atoi(argv[1]); M = atoi(argv[2]); } else { N = 512; M = 2; } A = (TYPE *) calloc(N*N,sizeof(TYPE)); B = (TYPE *) calloc(N*N,sizeof(TYPE)); C = (TYPE *) calloc(N*N,sizeof(TYPE)); for (i = 0; i < N; i++) for (j = 0; j < N; j++) { A[i*N+j] = (TYPE) rand(); B[i*N+j] = (TYPE) rand(); } MatMul(A,B,C,N,M); Print(A,N,"mmmthra.txt"); Print(B,N,"mmmthrb.txt"); Print(C,N,"mmmthrc.txt"); for (i = 0; i < N; i++) for (j = 0; j < N; j++) { __builtin_ia32_clflush((const void *)(A+i*N+j)); __builtin_ia32_clflush((const void *)(B+i*N+j)); __builtin_ia32_clflush((const void *)(C+i*N+j)); } free(A); free(B); free(C); return 0; }
int main(int argc, char **argv) { int m = 90; int k = 90; int n = 90; int numsteps = 1; Matrix<double> A = RandomMatrix<double>(m, k); Matrix<double> B = RandomMatrix<double>(k, n); Matrix<double> C1(m, n), C2(m, n); MatMul(A, B, C1); for (int numsteps = 1; numsteps <= 2; ++numsteps) { double lambda = DBL_EPSILON; std::cout << numsteps << std::endl; while (lambda < 1) { smirnov333_20_182_approx::FastMatmul(A, B, C2, numsteps, lambda); std::cout << lambda << ", " << MaxRelativeDiff(C1, C2) << "; "; lambda *= 2; } std::cout << std::endl; } return 0; }
void affTransDist(int* pMatch, int nMatch, double* pAff1, int nFeat1, double* pAff2, int nFeat2, double* pBoolSing, double* pBoolRefl, double* pDist, double* pFlip) { int i,j,idx1i,idx2i,idx1j,idx2j; double T1i[6], T2i[6], T12i[6], T21i[6], T1i_inv[6], T2i_inv[6], T_Refl[6], Temp[6]; double P1j[2], P2j[2], P1j_tran[2], P2j_tran[2]; double dist1, dist2; bool bSing, bRefl; bSing = (bool)(*pBoolSing); bRefl = (bool)(*pBoolRefl); double* pDistFlip; if(bSing) pDistFlip = new double [nMatch*nMatch]; for(i = 0; i < nMatch*nMatch; i++) pDist[i] = 0; if(bSing) for(i = 0; i < nMatch*nMatch; i++) pDistFlip[i] = 0; T_Refl[0] = 1; T_Refl[1] = 0; T_Refl[2] = 0; T_Refl[3] = 0; T_Refl[4] = -1; T_Refl[5] = 0; for(i = 0; i < nMatch; i++) { idx1i = pMatch[i]-1; idx2i = pMatch[i+nMatch]-1; T1i[0] = pAff1[idx1i]; T1i[1] = pAff1[idx1i+1*nFeat1]; T1i[2] = pAff1[idx1i+2*nFeat1]; T1i[3] = pAff1[idx1i+3*nFeat1]; T1i[4] = pAff1[idx1i+4*nFeat1]; T1i[5] = pAff1[idx1i+5*nFeat1]; T2i[0] = pAff2[idx2i]; T2i[1] = pAff2[idx2i+1*nFeat2]; T2i[2] = pAff2[idx2i+2*nFeat2]; T2i[3] = pAff2[idx2i+3*nFeat2]; T2i[4] = pAff2[idx2i+4*nFeat2]; T2i[5] = pAff2[idx2i+5*nFeat2]; for(j = 0; j < nMatch; j++) { if(i == j) continue; idx1j = pMatch[j]-1; idx2j = pMatch[j+nMatch]-1; P1j[0] = pAff1[idx1j+2*nFeat1]; P1j[1] = pAff1[idx1j+5*nFeat1]; P2j[0] = pAff2[idx2j+2*nFeat2]; P2j[1] = pAff2[idx2j+5*nFeat2]; MatInv(T1i,T1i_inv); MatInv(T2i,T2i_inv); if(bRefl) { MatMul(T2i,T_Refl,Temp,1); MatMul(Temp,T1i_inv,T12i,1); MatMul(T1i,T_Refl,Temp,1); MatMul(Temp,T2i_inv,T21i,1); } else { MatMul(T2i,T1i_inv,T12i,1); MatMul(T1i,T2i_inv,T21i,1); } MatMul(T12i,P1j,P1j_tran,2); MatMul(T21i,P2j,P2j_tran,2); dist1 = (P1j[0]-P2j_tran[0])*(P1j[0]-P2j_tran[0])+(P1j[1]-P2j_tran[1])*(P1j[1]-P2j_tran[1]); dist2 = (P2j[0]-P1j_tran[0])*(P2j[0]-P1j_tran[0])+(P2j[1]-P1j_tran[1])*(P2j[1]-P1j_tran[1]); pDist[i+nMatch*j] = (sqrt(dist1)+sqrt(dist2))/2; if(bSing) { MatMul(T21i,P1j,P1j_tran,2); MatMul(T12i,P2j,P2j_tran,2); dist1 = (P1j[0]-P2j_tran[0])*(P1j[0]-P2j_tran[0])+(P1j[1]-P2j_tran[1])*(P1j[1]-P2j_tran[1]); dist2 = (P2j[0]-P1j_tran[0])*(P2j[0]-P1j_tran[0])+(P2j[1]-P1j_tran[1])*(P2j[1]-P1j_tran[1]); pDistFlip[i+nMatch*j] = (sqrt(dist1)+sqrt(dist2))/2; } } } for(j = 0; j < nMatch-1; j++) for(i = j+1; i < nMatch; i++) { pDist[j+nMatch*i] = (pDist[j+nMatch*i]+pDist[i+nMatch*j])/2; pDist[i+nMatch*j] = pDist[j+nMatch*i]; } if(bSing) { for(j = 0; j < nMatch-1; j++) for(i = j+1; i < nMatch; i++) { pDistFlip[j+nMatch*i] = (pDistFlip[j+nMatch*i]+pDistFlip[i+nMatch*j])/2; pDistFlip[i+nMatch*j] = pDistFlip[j+nMatch*i]; } for(i = 0; i < nMatch*nMatch; i++) pFlip[i] = 0; for(i = 0; i < nMatch*nMatch; i++) if(pDist[i] > pDistFlip[i]) pFlip[i] = 1; for(i = 0; i < nMatch*nMatch; i++) if(pFlip[i]) pDist[i] = pDistFlip[i]; } if(bSing) delete [] pDistFlip; return; }
/* *--------------------------------------------------------- * Compute a rotation matrix around an arbitrary axis * specified by 2 points p1 and p2; theta is the angle * between the two planes that share the same edge * defined by p1 and p2 *--------------------------------------------------------- */ int MxRotateAxisAlain(Point3D p1, Point3D p2, double theta, Matrix4 *TM, Matrix4 *iTM) { Point3D p; double dist, cosX, sinX, cosY, sinY; Matrix4 m1, m2, Identity; loadIdentity( &Identity ); p.x = p2.x - p1.x; p.y = p2.y - p1.y; p.z = p2.z - p1.z; if( V3Length( &p ) < 0.0 ) return(FALSE); dist = sqrt( p.y * p.y + p.z * p.z ); if(dist < DAMN_SMALL){ cosX = 1.0; sinX = 0.0; } else{ cosX = p.z / dist; sinX = -p.y / dist; } cosY = dist; sinY = -p.x; loadIdentity( TM ); TM->element[3][0] = -p1.x; TM->element[3][1] = -p1.y; TM->element[3][2] = -p1.z; MatrixCopy( TM, &m1); loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = sinX; m2.element[1][2] = -sinX; m2.element[2][2] = cosX; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = sinY; m2.element[0][2] = -sinY; m2.element[2][2] = cosY; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); MatRotateZ( theta, &m2 ); MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = -sinY; m2.element[0][2] = sinY; m2.element[2][2] = cosY; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = -sinX; m2.element[1][2] = sinX; m2.element[2][2] = cosX; MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); loadIdentity( &m2 ); m2.element[3][0] = p1.x; m2.element[3][1] = p1.y; m2.element[3][2] = p1.z; MatMul( &m1, &m2, TM ); return( MxInvert(TM, iTM) ); }
int main (int argc, char* argv[]){ int i, j, option; int size = 100; int b_print = 0; int range = 100; double **A, **T, **S; double *b; double temp; char* OUTPATH = "data_input"; FILE* fp; srand(time(NULL)); while ((option = getopt(argc, argv, "s:b:po:")) != -1) switch(option){ case 's': size = strtol(optarg, NULL, 10); break; case 'b': range = strtol(optarg, NULL, 10);break; case 'p': b_print = 1; break; case 'o': OUTPATH = optarg; break; case '?': printf("Unexpected Options. \n"); return -1; } /*Generate the data*/ A = CreateMat(size, size); T = CreateMat(size, size); S = CreateMat(size, size); b = malloc(size * sizeof(double)); for (i = 0; i < size; ++i) for (j = 0; j < size; ++j){ A[i][j] = 0; T[i][j] = 0; } MatGen(size, T, (double)range); GenPerm(size, A); MatMul(size, T, A, S); for (i = 0; i < size; ++i){ temp = (double)(rand() % (int)(range * DECIMAL)) / DECIMAL; if (rand() % 2) temp *= -1; b[i] = temp; } /*Output the data*/ if ((fp = fopen(OUTPATH,"w")) == NULL){ printf("Fail to open a file to save the data. \n"); return -2; } fprintf(fp, "%d\n\n", size); for (i = 0; i < size; ++i){ for (j = 0; j < size; ++j) fprintf(fp, "%lf\t", S[i][j]); fprintf(fp, "\n"); } fprintf(fp, "\n"); for (i = 0; i < size; ++i) fprintf(fp, "%lf\n", b[i]); fclose(fp); /*Print the result if neccesary*/ if (b_print){ printf("The problem size is %d.\n", size); printf("============\n The A is \n============\n"); PrintMat(S, size, size); printf("============\n The b is \n============\n"); PrintVec(b, size); } DestroyMat(A, size); DestroyMat(T, size); DestroyMat(S, size); free(b); return 0; }
void FastMatmulRecursive(LockAndCounter& locker, MemoryManager<Scalar>& mem_mngr, Matrix<Scalar>& A, Matrix<Scalar>& B, Matrix<Scalar>& C, int total_steps, int steps_left, int start_index, double x, int num_threads, Scalar beta) { // Update multipliers C.UpdateMultiplier(A.multiplier()); C.UpdateMultiplier(B.multiplier()); A.set_multiplier(Scalar(1.0)); B.set_multiplier(Scalar(1.0)); // Base case for recursion if (steps_left == 0) { MatMul(A, B, C); return; } Matrix<Scalar> A11 = A.Subblock(2, 2, 1, 1); Matrix<Scalar> A12 = A.Subblock(2, 2, 1, 2); Matrix<Scalar> A21 = A.Subblock(2, 2, 2, 1); Matrix<Scalar> A22 = A.Subblock(2, 2, 2, 2); Matrix<Scalar> B11 = B.Subblock(2, 2, 1, 1); Matrix<Scalar> B12 = B.Subblock(2, 2, 1, 2); Matrix<Scalar> B21 = B.Subblock(2, 2, 2, 1); Matrix<Scalar> B22 = B.Subblock(2, 2, 2, 2); Matrix<Scalar> C11 = C.Subblock(2, 2, 1, 1); Matrix<Scalar> C12 = C.Subblock(2, 2, 1, 2); Matrix<Scalar> C21 = C.Subblock(2, 2, 2, 1); Matrix<Scalar> C22 = C.Subblock(2, 2, 2, 2); // Matrices to store the results of multiplications. #ifdef _PARALLEL_ Matrix<Scalar> M1(mem_mngr.GetMem(start_index, 1, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M2(mem_mngr.GetMem(start_index, 2, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M3(mem_mngr.GetMem(start_index, 3, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M4(mem_mngr.GetMem(start_index, 4, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M5(mem_mngr.GetMem(start_index, 5, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M6(mem_mngr.GetMem(start_index, 6, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M7(mem_mngr.GetMem(start_index, 7, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M8(mem_mngr.GetMem(start_index, 8, total_steps - steps_left, M), C11.m(), C11.m(), C11.n(), C.multiplier()); #else Matrix<Scalar> M1(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M2(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M3(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M4(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M5(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M6(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M7(C11.m(), C11.n(), C.multiplier()); Matrix<Scalar> M8(C11.m(), C11.n(), C.multiplier()); #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) bool sequential1 = should_launch_task(8, total_steps, steps_left, start_index, 1, num_threads); bool sequential2 = should_launch_task(8, total_steps, steps_left, start_index, 2, num_threads); bool sequential3 = should_launch_task(8, total_steps, steps_left, start_index, 3, num_threads); bool sequential4 = should_launch_task(8, total_steps, steps_left, start_index, 4, num_threads); bool sequential5 = should_launch_task(8, total_steps, steps_left, start_index, 5, num_threads); bool sequential6 = should_launch_task(8, total_steps, steps_left, start_index, 6, num_threads); bool sequential7 = should_launch_task(8, total_steps, steps_left, start_index, 7, num_threads); bool sequential8 = should_launch_task(8, total_steps, steps_left, start_index, 8, num_threads); #else bool sequential1 = false; bool sequential2 = false; bool sequential3 = false; bool sequential4 = false; bool sequential5 = false; bool sequential6 = false; bool sequential7 = false; bool sequential8 = false; #endif // M1 = (1 * A11) * (1 * B11) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential1) shared(mem_mngr, locker) untied { #endif M1.UpdateMultiplier(Scalar(1)); M1.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A11, B11, M1, total_steps, steps_left - 1, (start_index + 1 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 1, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M2 = (1 * A12) * (1 * B21) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential2) shared(mem_mngr, locker) untied { #endif M2.UpdateMultiplier(Scalar(1)); M2.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A12, B21, M2, total_steps, steps_left - 1, (start_index + 2 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 2, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M3 = (1 * A11) * (1 * B12) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential3) shared(mem_mngr, locker) untied { #endif M3.UpdateMultiplier(Scalar(1)); M3.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A11, B12, M3, total_steps, steps_left - 1, (start_index + 3 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 3, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M4 = (1 * A12) * (1 * B22) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential4) shared(mem_mngr, locker) untied { #endif M4.UpdateMultiplier(Scalar(1)); M4.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A12, B22, M4, total_steps, steps_left - 1, (start_index + 4 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 4, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M5 = (1 * A21) * (1 * B11) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential5) shared(mem_mngr, locker) untied { #endif M5.UpdateMultiplier(Scalar(1)); M5.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A21, B11, M5, total_steps, steps_left - 1, (start_index + 5 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 5, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M6 = (1 * A22) * (1 * B21) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential6) shared(mem_mngr, locker) untied { #endif M6.UpdateMultiplier(Scalar(1)); M6.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A22, B21, M6, total_steps, steps_left - 1, (start_index + 6 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 6, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M7 = (1 * A21) * (1 * B12) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential7) shared(mem_mngr, locker) untied { #endif M7.UpdateMultiplier(Scalar(1)); M7.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A21, B12, M7, total_steps, steps_left - 1, (start_index + 7 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 7, num_threads)) { # pragma omp taskwait # if defined(_PARALLEL_) && (_PARALLEL_ == _HYBRID_PAR_) SwitchToDFS(locker, num_threads); # endif } #endif // M8 = (1 * A22) * (1 * B22) #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) # pragma omp task if(sequential8) shared(mem_mngr, locker) untied { #endif M8.UpdateMultiplier(Scalar(1)); M8.UpdateMultiplier(Scalar(1)); FastMatmulRecursive(locker, mem_mngr, A22, B22, M8, total_steps, steps_left - 1, (start_index + 8 - 1) * 8, x, num_threads, Scalar(0.0)); #ifndef _PARALLEL_ #endif #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) locker.Decrement(); } if (should_task_wait(8, total_steps, steps_left, start_index, 8, num_threads)) { # pragma omp taskwait } #endif M_Add1(M1, M2, C11, x, false, beta); M_Add2(M3, M4, C12, x, false, beta); M_Add3(M5, M6, C21, x, false, beta); M_Add4(M7, M8, C22, x, false, beta); // Handle edge cases with dynamic peeling #if defined(_PARALLEL_) && (_PARALLEL_ == _BFS_PAR_ || _PARALLEL_ == _HYBRID_PAR_) if (total_steps == steps_left) { mkl_set_num_threads_local(num_threads); mkl_set_dynamic(0); } #endif DynamicPeeling(A, B, C, 2, 2, 2, beta); }
bool CFallingStuffFX::Update(float tmFrameTime) { // Base class update first m_vLastPos = m_vPos; if (!CBaseFX::Update(tmFrameTime)) return false; //increment our emission time by the elapsed frame time m_tmElapsedEmission += tmFrameTime; if (!IsShuttingDown() && !IsSuspended() && (m_tmElapsedEmission > GetProps()->m_tmFallingStuffFXEmission)) { ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(m_scale, m_scale, m_scale); LTVector vInterp; LTVector vInterpCur = m_vPos; // Calculate interpolant for particle system if (GetProps()->m_nFallingStuffFXEmission) { vInterp = m_vPos - m_vLastPos; vInterp /= (float)GetProps()->m_nFallingStuffFXEmission; } for (uint32 i = 0; i < GetProps()->m_nFallingStuffFXEmission; i ++) { ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATABLESPRITE; // Compute the initial position float xRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); float zRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); ocs.m_Pos = m_vPos + (m_vRight * xRand) + (m_vUp * zRand); ocs.m_Scale = vScale; strcpy(ocs.m_Filename, GetProps()->m_sSpriteName); // Move the start point vInterpCur += vInterp; HLOCALOBJ hNewSprite = m_pLTClient->CreateObject(&ocs); if (hNewSprite) { // Create a new sprite FALLING_THING *pNewSprite = debug_new( FALLING_THING ); if (GetProps()->m_nImpactCreate) { if (g_dwSplash > (uint32)GetProps()->m_nImpactCreate) { pNewSprite->m_bSplash = true; g_dwSplash = 0; } else { pNewSprite->m_bSplash = false; } } else { pNewSprite->m_bSplash = false; } g_dwSplash ++; if (pNewSprite) { LTVector v; // Compute the initial velocity v = m_vPlaneDir * GetProps()->m_fVel; pNewSprite->m_hObject = hNewSprite; pNewSprite->m_vVel = v; pNewSprite->m_tmElapsed = 0.0f; pNewSprite->m_vPos = ocs.m_Pos; pNewSprite->m_vLastPos = ocs.m_Pos; m_collSprites.AddTail(pNewSprite); } } } m_tmElapsedEmission = 0.0f; // And store the last position m_vLastPos = m_vPos; } LTMatrix mSpin; if (GetProps()->m_bUseSpin) { // Setup rotation LTMatrix vRight; LTMatrix vUp; LTMatrix vForward; LTMatrix vTmp; Mat_SetupRot(&vRight, &m_vRight, m_xRot); Mat_SetupRot(&vUp, &m_vUp, m_yRot); Mat_SetupRot(&vForward, &m_vPlaneDir, m_zRot); MatMul(&vTmp, &vRight, &vUp); MatMul(&mSpin, &vTmp, &vForward); m_xRot += GetProps()->m_vRotAdd.x * tmFrameTime; m_yRot += GetProps()->m_vRotAdd.y * tmFrameTime; m_zRot += GetProps()->m_vRotAdd.z * tmFrameTime; } // Get the camera rotation LTRotation orient; m_pLTClient->GetObjectRotation(m_hCamera, &orient); LTRotation dRot(orient); LTVector vF = orient.Forward(); float rot = (float)atan2(vF.x, vF.z); // Update the sprites.... CLinkListNode<FALLING_THING *> *pNode = m_collSprites.GetHead(); CLinkListNode<FALLING_THING *> *pDelNode; while (pNode) { pDelNode = NULL; FALLING_THING *pSprite = pNode->m_Data; //adjust our elapsed time pSprite->m_tmElapsed += tmFrameTime; // Check for expiration if (pSprite->m_tmElapsed > GetProps()->m_tmSpriteLifespan) { // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); pDelNode = pNode; } else { // Update !! pSprite->m_vLastPos = pSprite->m_vPos; pSprite->m_vPos += (pSprite->m_vVel * tmFrameTime); // Rotate if neccessary TVector3<float> vPos = pSprite->m_vPos; if (GetProps()->m_bUseSpin) { MatVMul_InPlace(&mSpin, &vPos); } // Add in wind vPos += (GetProps()->m_vWind * GetProps()->m_fWindAmount) * tmFrameTime; // Setup the new sprite position LTVector vPos2 = vPos; m_pLTClient->SetObjectPos(pSprite->m_hObject, &vPos2); // Setup the colour float r, g, b, a; m_pLTClient->GetObjectColor(pSprite->m_hObject, &r, &g, &b, &a); CalcColour(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &r, &g, &b, &a); m_pLTClient->SetObjectColor(pSprite->m_hObject, r, g, b, a); // Setup the scale float scale = 0.1f; CalcScale(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &scale); LTVector vScale; vScale.Init(scale, scale * GetProps()->m_fStretchMul, scale); m_pLTClient->SetObjectScale(pSprite->m_hObject, &vScale); // Setup the rotation dRot = LTRotation(0, 0, 0, 1); LTRotation orient(dRot); orient.Rotate( orient.Up(), rot ); m_pLTClient->SetObjectRotation(pSprite->m_hObject, &orient); // Check to see if we need to start a splash sprite if (pSprite->m_bSplash) { ClientIntersectQuery ciq; ClientIntersectInfo cii; ciq.m_From = pSprite->m_vLastPos; ciq.m_To = pSprite->m_vPos; if ((GetProps()->m_sImpactSpriteName[0]) && (m_pLTClient->IntersectSegment(&ciq, &cii))) { // Create a splash sprite SPLASH *pSplash = debug_new( SPLASH ); ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(0.0f, 0.0f, 0.0f); ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_ROTATABLESPRITE | FLAG_NOLIGHT; ocs.m_Pos = cii.m_Point + (cii.m_Plane.m_Normal * 2.0f); ocs.m_Scale = vScale; LTRotation dOrient( cii.m_Plane.m_Normal, LTVector(0.0f, 1.0f, 0.0f) ); strcpy(ocs.m_Filename, GetProps()->m_sImpactSpriteName); pSplash->m_hObject = m_pLTClient->CreateObject(&ocs); pSplash->m_scale = 0.0f; LTRotation orient(dRot); m_pLTClient->SetObjectRotation(pSplash->m_hObject, &orient); pSplash->m_tmElapsed = 0.0f; m_collSplashes.AddTail(pSplash); // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); // Delete the sprite pDelNode = pNode; } } } pNode = pNode->m_pNext; if (pDelNode) m_collSprites.Remove(pDelNode); } // Update our splashes CLinkListNode<SPLASH *> *pSplashNode = m_collSplashes.GetHead(); while (pSplashNode) { CLinkListNode<SPLASH *> *pDelNode = NULL; SPLASH *pSplash = pSplashNode->m_Data; //update the elapsed time on the splash pSplash->m_tmElapsed += tmFrameTime; // Calculate the new scale float scale = GetProps()->m_fImpactScale1 + ((GetProps()->m_fImpactScale2 - GetProps()->m_fImpactScale1) * (pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan)); LTVector vScale(scale, scale, scale); m_pLTClient->SetObjectScale(pSplash->m_hObject, &vScale); float r, g, b, a; m_pLTClient->GetObjectColor(pSplash->m_hObject, &r, &g, &b, &a); a = (float)(int)(pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan); if (a < 0.0f) a = 0.0f; if (a > 1.0f) a = 1.0f; m_pLTClient->SetObjectColor(pSplash->m_hObject, r, g, b, a); if (pSplash->m_tmElapsed > GetProps()->m_tmImpactLifespan) { m_pLTClient->RemoveObject(pSplash->m_hObject); pDelNode = pSplashNode; } pSplashNode = pSplashNode->m_pNext; if (pDelNode) m_collSplashes.Remove(pDelNode); } // Success !! return true; }
static void kond(int mod, int cf) { const Lat_Info *li = &ModList[mod].Info; char fn[LAT_MAXBASENAME+10]; Matrix_t *peakword, *kern, *m, *k, *pw; int j, pwr; /* Make the peak word, find its stable power, and calculate both kernel and image. ------------------------------------------ */ peakword = WgMakeWord(ModList[mod].Wg,li->Cf[cf].peakword); MatInsert_(peakword,li->Cf[cf].peakpol); pw = MatDup(peakword); StablePower_(peakword,&pwr,&kern); MESSAGE(0,("pwr=%d, nul=%d, ",pwr,kern->Nor)); if (kern->Nor != li->Cf[cf].mult * li->Cf[cf].spl) MTX_ERROR("Something is wrong here!"); MatEchelonize(peakword); /* Write out the image ------------------- */ if (!opt_n) { sprintf(fn,"%s%s.im",li->BaseName,Lat_CfName(li,cf)); MatSave(peakword,fn); } /* Write out the `uncondense matrix' --------------------------------- */ m = QProjection(peakword,kern); k = MatInverse(m); MatFree(m); MatMul(k,kern); sprintf(fn,"%s%s.k",li->BaseName,Lat_CfName(li,cf)); MatSave(k,fn); /* Condense all generators ----------------------- */ MESSAGE(1,("(")); for (j = 0; j < li->NGen; ++j) { sprintf(fn,"%dk",j+1); gkond(li,cf,peakword,k,ModList[mod].Rep->Gen[j],fn); MESSAGE(1,("%d",j+1)); } MESSAGE(1,(")")); /* Condense the peak word ---------------------- */ gkond(li,cf,peakword,k,pw,"np"); /* Calculate the semisimplicity basis. ----------------------------------- */ if (opt_b) { Matrix_t *seed, *partbas; int pos = CfPosition(li,cf); seed = MatNullSpace_(pw,0); partbas = SpinUp(seed,ModList[mod].Rep,SF_EACH|SF_COMBINE|SF_STD,NULL,NULL); MatFree(seed); MESSAGE(0,(", %d basis vectors",partbas->Nor)); if (MatCopyRegion(ModList[mod].SsBasis,pos,0,partbas,0,0,-1,-1) != 0) { MTX_ERROR1("Error making basis - '%s' is possibly not semisimple", li->BaseName); } MatFree(partbas); } MatFree(pw); MESSAGE(0,("\n")); MatFree(k); MatFree(kern); MatFree(peakword); }
MTX_DEFINE_FILE_INFO /// @addtogroup mat /// @{ //////////////////////////////////////////////////////////////////////////////////////////////////// /// Stable power of a matrix. /// This function takes a square matrix M and finds an integer n>0 such that /// ker(M<sup>n</sup>) = ker(M<sup>n+1</sup>). /// @a ker must be a pointer to a variable of type Matrix_t*, /// where the stable kernel will be stored. Both @a pwr and @a ker may be /// NULL if the corresponding information is not needed. /// /// Note that the number $n$ found by StablePower_() is not guararanteed /// to be minimal. In fact, n will always be a power of two since the /// function only examines matrices of the form M<sup>2<sup>k</sup></sup>. /// /// This function modifies the matrix. To avoid this, use StablePower(). /// @param mat The matrix. /// @param pwr Stable power. /// @param ker Kernel of the stable power. /// @return 0 on success, -1 on error. int StablePower_(Matrix_t *mat, int *pwr, Matrix_t **ker) { // check the arguments. if (!MatIsValid(mat)) { MTX_ERROR1("mat: %E",MTX_ERR_BADARG); return -1; } if (mat->Nor != mat->Noc) { MTX_ERROR1("%E",MTX_ERR_NOTSQUARE); return -1; } // calculate the stable power int p = 1; Matrix_t *k1 = MatNullSpace(mat); if (k1 == NULL) { return -1; } if (MatMul(mat,mat) == NULL) { MatFree(k1); return -1; } Matrix_t *k2 = MatNullSpace(mat); if (k2 == NULL) { MatFree(k1); return -1; } while (k2->Nor > k1->Nor) { p *= 2; MatFree(k1); k1 = k2; if (MatMul(mat,mat) == NULL) { MatFree(k1); return -1; } k2 = MatNullSpace(mat); if (k2 == NULL) { MatFree(k1); return -1; } } MatFree(k2); // return the result if (ker != NULL) { *ker = k1; } else { MatFree(k1); } if (pwr != NULL) { *pwr = p; } return 0; }
// Sets up pParams. // pPos and pRotation are the view position and orientation. // pRect is the rectangle on the screen that the viewing window maps into. // pScale is an extra scale that scales all the coordinates up. bool d3d_InitFrustum2(ViewParams *pParams, ViewBoxDef *pViewBox, float screenMinX, float screenMinY, float screenMaxX, float screenMaxY, const LTMatrix *pMat, const LTVector& vScale, ViewParams::ERenderMode eMode) { LTMatrix mTempWorld, mRotation, mScale; LTMatrix mFOVScale, mBackTransform; LTMatrix mDevice, mBackTranslate; float leftX, rightX, topY, bottomY, normalZ; uint32 i; LTVector forwardVec, zPlanePos, vTrans; LTMatrix mProjectionTransform; //mUnit, mPerspective; pParams->m_mIdentity.Identity(); pParams->m_mInvView = *pMat; // Here's how the viewing works: // The world to camera transformation rotates and translates // the world into camera space. // The camera to clip transformation just scales the sides so the // field of view is 90 degrees (faster to clip in). // Clipping takes place on NEARZ and g_ViewParams.m_FarZ. // In terms of Z buffer calculations, the maximum Z is MAX_FARZ (that way, // when the farZ clipping plane is changed, sz and rhw stay the same). /////// Copy stuff in and setup view limits. memcpy(&pParams->m_ViewBox, pViewBox, sizeof(pParams->m_ViewBox)); pMat->GetTranslation(pParams->m_Pos); pParams->m_FarZ = pViewBox->m_FarZ; if(pParams->m_FarZ < 3.0f) pParams->m_FarZ = 3.0f; if(pParams->m_FarZ > MAX_FARZ) pParams->m_FarZ = MAX_FARZ; pParams->m_NearZ = pViewBox->m_NearZ; pParams->m_Rect.left = (int)RoundFloatToInt(screenMinX); pParams->m_Rect.top = (int)RoundFloatToInt(screenMinY); pParams->m_Rect.right = (int)RoundFloatToInt(screenMaxX); pParams->m_Rect.bottom = (int)RoundFloatToInt(screenMaxY); /////// Setup all the matrices. // Setup the rotation and translation transforms. mRotation = *pMat; mRotation.SetTranslation(0.0f, 0.0f, 0.0f); Mat_GetBasisVectors(&mRotation, &pParams->m_Right, &pParams->m_Up, &pParams->m_Forward); // We want to transpose (ie: when we're looking left, rotate the world to the right..) MatTranspose3x3(&mRotation); mBackTranslate.Init( 1, 0, 0, -pParams->m_Pos.x, 0, 1, 0, -pParams->m_Pos.y, 0, 0, 1, -pParams->m_Pos.z, 0, 0, 0, 1); MatMul(&mTempWorld, &mRotation, &mBackTranslate); // Scale it to get the full world transform. mScale.Init( vScale.x, 0, 0, 0, 0, vScale.y, 0, 0, 0, 0, vScale.z, 0, 0, 0, 0, 1); MatMul(&pParams->m_mView, &mScale, &mTempWorld); // Shear so the center of projection is (0,0,COP.z) LTMatrix mShear; mShear.Init( 1.0f, 0.0f, -pViewBox->m_COP.x/pViewBox->m_COP.z, 0.0f, 0.0f, 1.0f, -pViewBox->m_COP.y/pViewBox->m_COP.z, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); // Figure out X and Y scale to get frustum into unit slopes. float fFovXScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[0]; float fFovYScale = pViewBox->m_COP.z / pViewBox->m_WindowSize[1]; // Squash the sides to 45 degree angles. mFOVScale.Init( fFovXScale, 0.0f, 0.0f, 0.0f, 0.0f, fFovYScale, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); // Setup the projection transform. d3d_SetupPerspectiveMatrix(&mProjectionTransform, pViewBox->m_NearZ, pParams->m_FarZ); // Setup the projection space (-1<x<1) to device space transformation. pParams->m_fScreenWidth = (screenMaxX - screenMinX); pParams->m_fScreenHeight = (screenMaxY - screenMinY); // Setup the device transform. It subtracts 0.4 to account for the FP's tendency // to slip above and below 0.5. Mat_Identity(&mDevice); mDevice.m[0][0] = pParams->m_fScreenWidth * 0.5f - 0.0001f; mDevice.m[0][3] = screenMinX + pParams->m_fScreenWidth * 0.5f; mDevice.m[1][1] = -(pParams->m_fScreenHeight * 0.5f - 0.0001f); mDevice.m[1][3] = screenMinY + pParams->m_fScreenHeight * 0.5f; // Precalculate useful matrices. pParams->m_DeviceTimesProjection = mDevice * mProjectionTransform; pParams->m_FullTransform = pParams->m_DeviceTimesProjection * mFOVScale * mShear * pParams->m_mView; pParams->m_mProjection = mProjectionTransform * mFOVScale * mShear; /////// Setup the view frustum points in camera space. float xNearZ, yNearZ, xFarZ, yFarZ; xNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z; yNearZ = (pParams->m_NearZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z; xFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[0]) / pViewBox->m_COP.z; yFarZ = (pParams->m_FarZ * pViewBox->m_WindowSize[1]) / pViewBox->m_COP.z; pParams->m_ViewPoints[0].Init(-xNearZ, yNearZ, pParams->m_NearZ); // Near Top Left pParams->m_ViewPoints[1].Init(xNearZ, yNearZ, pParams->m_NearZ); // Near Top Right pParams->m_ViewPoints[2].Init(-xNearZ, -yNearZ, pParams->m_NearZ); // Near Bottom Left pParams->m_ViewPoints[3].Init(xNearZ, -yNearZ, pParams->m_NearZ); // Near Bottom Right pParams->m_ViewPoints[4].Init(-xFarZ, yFarZ, pParams->m_FarZ); // Far Top Left pParams->m_ViewPoints[5].Init(xFarZ, yFarZ, pParams->m_FarZ); // Far Top Right pParams->m_ViewPoints[6].Init(-xFarZ, -yFarZ, pParams->m_FarZ); // Far Bottom Left pParams->m_ViewPoints[7].Init(xFarZ, -yFarZ, pParams->m_FarZ); // Far Bottom Right // Transform them into world space. for(i=0; i < 8; i++) { MatVMul_InPlace_Transposed3x3(&pParams->m_mView, &pParams->m_ViewPoints[i]); pParams->m_ViewPoints[i] += pParams->m_Pos; } // Get the AABB of the view frustum pParams->m_ViewAABBMin = pParams->m_ViewPoints[0]; pParams->m_ViewAABBMax = pParams->m_ViewPoints[0]; for(i=1; i < 8; i++) { VEC_MIN(pParams->m_ViewAABBMin, pParams->m_ViewAABBMin, pParams->m_ViewPoints[i]); VEC_MAX(pParams->m_ViewAABBMax, pParams->m_ViewAABBMax, pParams->m_ViewPoints[i]); } /////// Setup the camera-space clipping planes. leftX = pViewBox->m_COP.x - pViewBox->m_WindowSize[0]; rightX = pViewBox->m_COP.x + pViewBox->m_WindowSize[0]; topY = pViewBox->m_COP.y + pViewBox->m_WindowSize[1]; bottomY = pViewBox->m_COP.y - pViewBox->m_WindowSize[1]; normalZ = pViewBox->m_COP.z; LTPlane CSClipPlanes[NUM_CLIPPLANES]; CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Init(0.0f, 0.0f, 1.0f); // Near Z CSClipPlanes[CPLANE_NEAR_INDEX].m_Dist = 1.0f; CSClipPlanes[CPLANE_FAR_INDEX].m_Normal.Init(0.0f, 0.0f, -1.0f); // Far Z CSClipPlanes[CPLANE_FAR_INDEX].m_Dist = -pParams->m_FarZ; CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Init(normalZ, 0.0f, -leftX); // Left CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Init(-normalZ, 0.0f, rightX); // Right CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Init(0.0f, -normalZ, topY); // Top CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Init(0.0f, normalZ, -bottomY); // Bottom CSClipPlanes[CPLANE_LEFT_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_TOP_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_RIGHT_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Normal.Norm(); CSClipPlanes[CPLANE_LEFT_INDEX].m_Dist = CSClipPlanes[CPLANE_RIGHT_INDEX].m_Dist = 0.0f; CSClipPlanes[CPLANE_TOP_INDEX].m_Dist = CSClipPlanes[CPLANE_BOTTOM_INDEX].m_Dist = 0.0f; // Now setup the world space clipping planes. mBackTransform = pParams->m_mView; MatTranspose3x3(&mBackTransform); for(i=0; i < NUM_CLIPPLANES; i++) { if(i != CPLANE_NEAR_INDEX && i != CPLANE_FAR_INDEX) { MatVMul_3x3(&pParams->m_ClipPlanes[i].m_Normal, &mBackTransform, &CSClipPlanes[i].m_Normal); pParams->m_ClipPlanes[i].m_Dist = pParams->m_ClipPlanes[i].m_Normal.Dot(pParams->m_Pos); } } // The Z planes need to be handled a little differently. forwardVec.Init(mRotation.m[2][0], mRotation.m[2][1], mRotation.m[2][2]); zPlanePos = forwardVec * pViewBox->m_NearZ; zPlanePos += pParams->m_Pos; MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal, &mBackTransform, &CSClipPlanes[CPLANE_NEAR_INDEX].m_Normal); pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Dist = pParams->m_ClipPlanes[CPLANE_NEAR_INDEX].m_Normal.Dot(zPlanePos); zPlanePos = forwardVec * pParams->m_FarZ; zPlanePos += pParams->m_Pos; MatVMul_3x3(&pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal, &mBackTransform, &CSClipPlanes[CPLANE_FAR_INDEX].m_Normal); pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Dist = pParams->m_ClipPlanes[CPLANE_FAR_INDEX].m_Normal.Dot(zPlanePos); // Remember AABB Corners the planes are pointing at for (uint32 nPlaneLoop = 0; nPlaneLoop < NUM_CLIPPLANES; ++nPlaneLoop) { pParams->m_AABBPlaneCorner[nPlaneLoop] = GetAABBPlaneCorner(pParams->m_ClipPlanes[nPlaneLoop].m_Normal); } // Default the world transform to identity pParams->m_mInvWorld.Identity(); //setup the environment mapping info pParams->m_mWorldEnvMap.SetBasisVectors(&pParams->m_Right, &pParams->m_Up, &pParams->m_Forward); //turn off glowing by default pParams->m_eRenderMode = eMode; d3d_SetupSkyStuff(g_pSceneDesc->m_SkyDef, pParams); return true; }
static void MakePQ(int n, int mj, int nj) { MatRep_t *rep_m; Matrix_t *estar[MAXENDO], *endo[MAXENDO], *e, *ei; char fn[200]; int dim = InfoM.Cf[mj].dim; int spl = InfoM.Cf[mj].spl; int i; Matrix_t *p; MESSAGE(1,("Condensing %s%s x ",InfoM.BaseName,Lat_CfName(&InfoM,mj))); MESSAGE(1,("%s%s, [E:k]=%d\n",InfoN.BaseName,Lat_CfName(&InfoN,nj),spl)); /* Read the generators for the constituent of M and make the endomorphism ring. --------------------------------------------------------- */ rep_m = Lat_ReadCfGens(&InfoM,mj,InfoM.Cf[mj].peakword >= 0 ? LAT_RG_STD : 0); MESSAGE(2,("Calculating endomorphism ring\n")); MkEndo(rep_m,InfoM.Cf + mj,endo,MAXENDO); MrFree(rep_m); /* Calculate the Q matrix ---------------------- */ MESSAGE(2,("Calculating embedding of E\n")); MakeQ(n,spl,(const Matrix_t **)endo); /* Calculate the E* matrices Note: We should use the symmetry under i<-->k here! --------------------------------------------------- */ MESSAGE(2,("Calculating projection on E\n")); MESSAGE(2,(" E* matrices\n")); e = MatAlloc(FfOrder,spl,spl); for (i = 0; i < spl; ++i) { PTR pptr = MatGetPtr(e,i); int k; for (k = 0; k < spl; ++k) { FEL f; Matrix_t *x = MatDup(endo[i]); MatMul(x,endo[k]); f = MatTrace(x); FfInsert(pptr,k,f); MatFree(x); } } ei = MatInverse(e); MatFree(e); for (i = 0; i < spl; ++i) { int k; PTR p; estar[i] = MatAlloc(FfOrder,dim,dim); p = MatGetPtr(ei,i); for (k = 0; k < spl; ++k) MatAddMul(estar[i],endo[k],FfExtract(p,k)); } MatFree(ei); /* Transpose the E* matrices. This simplifies the calculation of tr(z E*) below. ----------------------------------------------- */ MESSAGE(2,(" Transposing E* matrices\n")); for (i = 0; i < spl; ++i) { Matrix_t *x = MatTransposed(estar[i]); MatFree(estar[i]); estar[i] = x; } /* Calculate the P matrix ---------------------- */ MESSAGE(2,(" P matrix\n")); p = MatAlloc(FfOrder,dim*dim,spl); for (i = 0; i < dim; ++i) { int j; for (j = 0; j < dim; ++j) { int r; PTR pptr = MatGetPtr(p,i*dim + j); Matrix_t *x = MatAlloc(FfOrder,dim,dim); MatCopyRegion(x,0,i,Trans[n],0,j,dim,1); for (r = 0; r < spl; ++r) { FEL f = MatProd(x,estar[r]); FfInsert(pptr,r,f); } MatFree(x); } } sprintf(fn,"%s.p.%d",TkiName,n+1); MESSAGE(2,("Writing %s\n",fn)); #if 0 if (InfoM.Cf[mj].peakword < 0) MatMulScalar(p,FF_ZERO); #endif MatSave(p,fn); /* Clean up -------- */ MatFree(p); for (i = 0; i < spl; ++i) MatFree(endo[i]); }
/* *--------------------------------------------------------- * Compute a rotation matrix around an arbitrary axis * specified by 2 points p1 and p2; theta is the angle * between the two planes that share the same edge * defined by p1 and p2 * * The matrix TM is the matrix that brings the plane of * face 'n' into face 'p'; Matrix iTM is the matrix * that brings the plane of face 'p' into 'n' * 'p' and 'n' are the names of faces according to the * winged edge data structure; 'p' is the previous face * and 'n' is the next face *--------------------------------------------------------- */ int MxRotateAxis(Point3D p1, Point3D p2, double theta, Matrix4 *TM, Matrix4 *iTM) { Point3D p; double dist, cosX, sinX, cosY, sinY, det; Matrix4 m1, m2; p.x = p2.x - p1.x; p.y = p2.y - p1.y; p.z = p2.z - p1.z; if( V3Length( &p ) < 0.0 ) return(FALSE); V3Normalize( &p ); dist = sqrt( p.y * p.y + p.z * p.z ); /* maybe the 2 points are already aligned with the X-axis */ if(dist < DAMN_SMALL || dist == 0.0){ cosX = 1.0; sinX = 0.0; } else{ cosX = p.z / dist; sinX = p.y / dist; } /* fprintf(stderr, "p: x = %3.2f y = %3.2f z = %3.2f dist = %3.2f\n", p.x, p.y, p.z, dist); */ cosY = dist; sinY = -p.x; loadIdentity( TM ); loadIdentity( &m1 ); /* inverse translation matrix */ m1.element[0][3] = p1.x; m1.element[1][3] = p1.y; m1.element[2][3] = p1.z; /* fprintf(stderr,"Inverse Translation:\n"); printMatrix( m1 ); */ /* Inverse Rotation around X */ loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = -sinX; m2.element[1][2] = sinX; m2.element[2][2] = cosX; /* fprintf(stderr,"Inverse Rotation around X:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); /* Inverse Rotation around Y */ loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = sinY; m2.element[0][2] = -sinY; m2.element[2][2] = cosY; /* fprintf(stderr,"Inverse Rotation around Y:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); /* Rotation around Z */ loadIdentity( &m2 ); m2.element[0][0]= cos( theta ); m2.element[1][0]= -sin( theta ); m2.element[0][1]= sin( theta ); m2.element[1][1]= cos( theta ); /* fprintf(stderr,"Rotation around Z:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); /* Rotation around Y */ loadIdentity( &m2 ); m2.element[0][0] = cosY; m2.element[2][0] = -sinY; m2.element[0][2] = sinY; m2.element[2][2] = cosY; /* fprintf(stderr,"Rotation around Y:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); /* Rotation around X */ loadIdentity( &m2 ); m2.element[1][1] = cosX; m2.element[2][1] = sinX; m2.element[1][2] = -sinX; m2.element[2][2] = cosX; /* fprintf(stderr,"Rotation around X:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); MatrixCopy( TM, &m1 ); /* Translation matrix */ loadIdentity( &m2 ); m2.element[0][3] = -p1.x; m2.element[1][3] = -p1.y; m2.element[2][3] = -p1.z; /* fprintf(stderr,"Translation matrix:\n"); printMatrix( m2 ); */ MatMul( &m1, &m2, TM ); det = MxInvert(TM, iTM); if(det < L_EPSILON && det > -L_EPSILON) return( FALSE ); /*return( MxInvert(TM, iTM) );*/ else return ( TRUE ); }