void pitch_matrices(VMATRIX *M, double pitch) /* transform element matrix to reflect pitching of element (rotation * about horizontal transverse axis) */ { static VMATRIX input, output; static long initialized=0; static VMATRIX Mr; if (pitch==0) return; if (!initialized) { long i; initialized = 1; initialize_matrices(&input, 1); initialize_matrices(&output, 1); initialize_matrices(&Mr, M->order); for (i=0; i<6; i++) input.R[i][i] = output.R[i][i] = 1; } input.C[3] = pitch; output.C[3] = -pitch; concat_matrices(&Mr, M, &input, 0); concat_matrices(M, &output, &Mr, 0); }
void yaw_matrices(VMATRIX *M, double yaw) /* transform element matrix to reflect yawing of element (rotation * about vertical axis) */ { static VMATRIX input, output; static long initialized=0; static VMATRIX Mr; if (yaw==0) return; if (!initialized) { long i; initialized = 1; initialize_matrices(&input, 1); initialize_matrices(&output, 1); initialize_matrices(&Mr, M->order); for (i=0; i<6; i++) input.R[i][i] = output.R[i][i] = 1; } input.C[1] = yaw; output.C[1] = -yaw; concat_matrices(&Mr, M, &input, 0); concat_matrices(M, &output, &Mr, 0); }
microseconds MatrixMul::mult_blas(const Args & args, std::mt19937 & gen) { std::cout << "Test: BLAS "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); double * A = new double[m * k]; double * B = new double[k * l]; double * C = new double[m * l]; initialize_matrices(A, A + m*k, B, B + k*l, gen, cur_args); auto start = std::chrono::high_resolution_clock::now(); cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, m, l, k, 1.0, A, k, B, l, 0.0, C, l); auto end = std::chrono::high_resolution_clock::now(); if( args.test ) { verify_results(C, C + m*l); } auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; delete[] A; delete[] B; delete[] C; return time; }
int main() { int a[3][3]; int b[3][3]; int c[3][3]; //Q2: define pointers (5) //Define pointers ap, bp, and cp to the matrices that are defined above //CODE HERE int *ap = a, *bp = b, *cp = c; //Uncomment these once you've defined your matrices initialize_matrices(ap, bp, cp); printf("Matrix a:\n"); fill_matrix(ap); printf("Matrix b:\n"); fill_matrix(bp); add_matrices(ap, bp, cp); print_sum_matrix(cp); return 0; }
microseconds MatrixMul::blitz(const Args & args, std::mt19937 & gen) { std::cout << "Test: blitz++ "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); blitz::Array<double, 2> C(m, l), B(k, l), A(m, k); initialize_matrices(A.begin(), A.end(), B.begin(), B.end(), gen, cur_args); auto start = std::chrono::high_resolution_clock::now(); blitz::firstIndex i; blitz::secondIndex j; blitz::thirdIndex n; C = blitz::sum(A(i,n) * B(n,j), n); auto end = std::chrono::high_resolution_clock::now(); if( args.test ) { verify_results(C.begin(), C.end()); } auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
int main() { int a[3][3]; int b[3][3]; int c[3][3]; //Q2: define pointers (5) //Define pointers ap, bp, and cp to the matrices that are defined above //SOLUTION CODE int* ap = &a[0][0]; int* bp = &b[0][0]; int* cp = &c[0][0]; //SOLUTION CODE initialize_matrices(ap, bp, cp); printf("Matrix a:\n"); fill_matrix(ap); printf("Matrix b:\n"); fill_matrix(bp); add_matrices(ap, bp, cp); print_sum_matrix(cp); return 0; }
int main(int argc, char **argv) { /*char logfile_name[100]; FILE *logfile_handle;*/ //n = 500; if(argc > 1){ n = atoi(argv[1]); } //sprintf(logfile_name, "logfile_dgemm.txt"); //logfile_handle = freopen(logfile_name, "w", stdout); mem_size = n * n * sizeof(double); a = (double*)malloc(mem_size); b = (double*)malloc(mem_size); c = (double*)malloc(mem_size); if(0 == a || 0 == b || 0 == c){ printf("memory allocation failed"); return 0; } /* matrices initialisation */ initialize_matrices(); /* naive matrix multiplication */ optimized_matrix_multiplication_algo(); return(0); }
std::auto_ptr<MAST::FlutterSolutionBase> MAST::TimeDomainFlutterSolver::analyze(const Real v_ref, const MAST::FlutterSolutionBase* prev_sol) { RealMatrixX a, b; libMesh::out << " ====================================================" << std::endl << "Eigensolution for V = " << std::setw(10) << v_ref << std::endl; initialize_matrices(v_ref, a, b); LAPACK_DGGEV ges; ges.compute(a, b); ges.scale_eigenvectors_to_identity_innerproduct(); MAST::TimeDomainFlutterSolution* root = new MAST::TimeDomainFlutterSolution; root->init(*this, v_ref, flight_condition->ref_chord, ges); if (prev_sol) root->sort(*prev_sol); libMesh::out << "Finished Eigensolution" << std::endl << " ====================================================" << std::endl; return std::auto_ptr<MAST::FlutterSolutionBase> (root); }
/*--------------------------------------------------------------------------- * * Compute matrix product using recursive tiling. * * Input * int argc - length of argv[] array * char* argv[] - pointer to command line parameter array * int verbosity - program verification: verbosity > 0 gives more output * char* order - string indicating loop order, e.g., "ijk" or "jki" * * Output * double - elapsed time for product computation */ double multiply_by_recursive_blocks( int argc, char* argv[], int verbosity, char* order ) { int rows, cols, mids, block_size; double **a, **b, **c; double t1, t2; double sec; double gflop_count; /* * process command line arguments */ rows = atoi( argv[0] ); mids = atoi( argv[1] ); cols = atoi( argv[2] ); block_size = atoi( argv[3] ); gflop_count = 2.0 * rows * mids * cols / 1.0e9; if ( verbosity > 0 ) { printf( "Recursive blocks(%3s): rows = %d, mids = %d, columns = %d\n", order, rows, mids, cols ); printf( "block size = %d\n", block_size ); } /* * allocate and initialize matrices */ a = (double**) allocateMatrix( rows, mids ); b = (double**) allocateMatrix( mids, cols ); c = (double**) allocateMatrix( rows, cols ); initialize_matrices( a, b, c, rows, cols, mids, verbosity ); /* * compute product */ t1 = wtime(); mm_rec( c, a, b, 0, 0, 0, 0, 0, 0, rows, mids, cols, cols, block_size ); t2 = wtime(); sec = t2 - t1; if ( verbosity > 1 ) printf( "checksum = %f\n", checksum( c, rows, cols ) ); printf( "blocks(%3s): %6.3f secs %6.3f gflops ", order, sec, gflop_count / sec ); printf( "( %5d x %5d x %5d ) ( %6d )\n", rows, mids, cols, block_size ); /* * clean up */ deallocateMatrix( a ); deallocateMatrix( b ); deallocateMatrix( c ); return t2 - t1; }
microseconds MatrixMul::plain_call(const Args & args, std::mt19937 & gen) { std::cout << "Test: plain call "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); double * A = new double[m*k]; double * B = new double[k*l]; double * C = new double[m*l]; /** Initialize **/ initialize_matrices(A, A + m*k, B, B + k*l, gen, cur_args); /** Compute **/ auto start = std::chrono::high_resolution_clock::now(); for(uint32_t i = 0; i < m;++i) { for(uint32_t n = 0; n < l; ++n) { C[i*l + n] = A[i*k] * B[n]; } for(uint32_t j = 1; j < k; ++j) { for(uint32_t n = 0; n < l; ++n) { C[i*l + n] += A[i*k + j] * B[j*l + n]; } } } auto end = std::chrono::high_resolution_clock::now(); if( args.test ) { verify_results(C, C + m*l); } delete[] A; delete[] B; delete[] C; auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
VMATRIX *rotation_matrix(double tilt) { VMATRIX *Rot; double sin_tilt, cos_tilt; log_entry("rotation_matrix"); if (fabs(tilt-PI/2)<1e-12) { sin_tilt = 1; cos_tilt = 0; } else if (fabs(tilt-PI)<1e-12) { sin_tilt = 0; cos_tilt = -1; } else { sin_tilt = sin(tilt); cos_tilt = cos(tilt); } Rot = tmalloc(sizeof(*Rot)); initialize_matrices(Rot, 1); /* Rotation matrix for (x, y) */ Rot->R[0][0] = cos_tilt ; Rot->R[0][2] = sin_tilt ; Rot->R[2][0] = -sin_tilt ; Rot->R[2][2] = cos_tilt ; /* Rotation matrix for (x', y') */ Rot->R[1][1] = cos_tilt ; Rot->R[1][3] = sin_tilt ; Rot->R[3][1] = -sin_tilt ; Rot->R[3][3] = cos_tilt ; Rot->R[4][4] = Rot->R[5][5] = 1; log_exit("rotation_matrix"); return(Rot); }
microseconds MatrixMul::mult_blaze(const Args & args, std::mt19937 & gen) { std::cout << "Test: Blaze "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); blaze::DynamicMatrix<double, blaze::rowMajor> A(m, k), B(k, l), C(m, l); initialize_matrices(A.data(), A.data() + m*k, B.data(), B.data() + k*l, gen, cur_args); auto start = std::chrono::high_resolution_clock::now(); C = A * B; auto end = std::chrono::high_resolution_clock::now(); if( args.test ) { verify_results(C.data(), C.data() + m*l); } auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
microseconds MatrixMul::boost_ublas(const Args & args, std::mt19937 & gen) { std::cout << "Test: boost uBLAS "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); boost::numeric::ublas::matrix<double> A(m, k), B(k, l), C(m, l); initialize_matrices(A.data().begin(), A.data().end(), B.data().begin(), B.data().end(), gen, cur_args); auto start = std::chrono::high_resolution_clock::now(); noalias(C) = prod( A, B ); auto end = std::chrono::high_resolution_clock::now(); if( args.test ) { verify_results(C.data().begin(), C.data().end()); } auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
microseconds MatrixMul::op_overl(const Args & args, std::mt19937 & gen) { std::cout << "Test: operator overloading "; const MatrixMulArgs & cur_args = dynamic_cast<const MatrixMulArgs&>(args); uint32_t m, k, l; get_matrix_sizes(cur_args, m, k, l); MatrixMul::Matrix<double> A(m,k), B(k,l), C(m,l); /** Initialize **/ initialize_matrices(A.data, A.data + m*k, B.data, B.data + k*l, gen, cur_args); /** Compute **/ auto start = std::chrono::high_resolution_clock::now(); C = A*B; auto end = std::chrono::high_resolution_clock::now(); /*if( args.test ) { verify_results(C, C + m*l); } delete[] A; delete[] B; delete[] C;*/ auto time = std::chrono::duration_cast<std::chrono::microseconds>( end - start); std::cout << time.count() << std::endl; return time; }
void run_no_events() { initialize_matrices() ; multiply_matrices() ; }
/*--------------------------------------------------------------------------- * * Compute matrix product using tiling. The loop order used for the tile * products is specified in string variable "mode". * * Input * int argc - length of argv[] array * char* argv[] - pointer to command line parameter array * int verbosity - program verification: verbosity > 0 gives more output * char* order - string indicating loop order, e.g., "ijk" or "jki" * * Output * double - elapsed time for product computation */ double multiply_by_tiles( int argc, char* argv[], int verbosity, char* order ) { int rows, cols, mids; int rows_per_tile, cols_per_tile, mids_per_tile; int row_start, row_end; int col_start, col_end; int mid_start, mid_end; double **a, **b, **c; double t1, t2; double sec; double gflop_count; /* * process command line arguments */ rows = atoi( argv[0] ); mids = atoi( argv[1] ); cols = atoi( argv[2] ); rows_per_tile = atoi( argv[3] ); mids_per_tile = atoi( argv[4] ); cols_per_tile = atoi( argv[5] ); gflop_count = 2.0 * rows * mids * cols / 1.0e9; if ( verbosity > 0 ) { printf( "Tiles(%3s): rows = %d, mids = %d, columns = %d\n", order, rows, mids, cols ); printf( "block rows = %d, mids = %d, columns = %d\n", rows_per_tile, mids_per_tile, cols_per_tile ); } /* * allocate and initialize matrices */ a = (double**) allocateMatrix( rows, mids ); b = (double**) allocateMatrix( mids, cols ); c = (double**) allocateMatrix( rows, cols ); initialize_matrices( a, b, c, rows, cols, mids, verbosity ); /* * compute product */ t1 = wtime(); for ( row_start = 0; row_start < rows; row_start += rows_per_tile ) { row_end = row_start + rows_per_tile - 1; if ( row_end >= rows ) row_end = rows - 1; for ( col_start = 0; col_start < cols; col_start += cols_per_tile ) { col_end = col_start + cols_per_tile - 1; if ( col_end >= cols ) col_end = cols - 1; for ( mid_start = 0; mid_start < mids; mid_start += mids_per_tile ) { mid_end = mid_start + mids_per_tile - 1; if ( mid_end >= mids ) mid_end = mids - 1; do_product( a, b, c, row_start, row_end, col_start, col_end, mid_start, mid_end ); } } } t2 = wtime(); sec = t2 - t1; if ( verbosity > 1 ) printf( "checksum = %f\n", checksum( c, rows, cols ) ); printf( "tiles(%3s): %6.3f secs %6.3f gflops ", order, sec, gflop_count / sec ); printf( "( %5d x %5d x %5d ) ( %4d x %4d x %4d )\n", rows, mids, cols, rows_per_tile, mids_per_tile, cols_per_tile ); /* * clean up */ deallocateMatrix( a ); deallocateMatrix( b ); deallocateMatrix( c ); return t2 - t1; }
void tilt_matrices(VMATRIX *M, double tilt) { static VMATRIX Rot, IRot; static long initialized=0; VMATRIX Mr; double sin_tilt, cos_tilt; log_entry("tilt_matrices"); if (tilt==0) { log_exit("tilt_matrices"); return; } if (!initialized) { initialized = 1; initialize_matrices(&Rot, 1); initialize_matrices(&IRot, 1); } initialize_matrices(&Mr, M->order); if (fabs(tilt-PI/2)<1e-12) { sin_tilt = 1; cos_tilt = 0; } else if (fabs(tilt+PI/2)<1e-12) { sin_tilt = -1; cos_tilt = 0; } else if (fabs(tilt-PI)<1e-12 || fabs(tilt+PI)<1e-12) { sin_tilt = 0; cos_tilt = -1; } else { sin_tilt = sin(tilt); cos_tilt = cos(tilt); } /* Rotation matrix for (x, y) */ IRot.R[0][0] = Rot.R[0][0] = cos_tilt ; IRot.R[0][2] = -(Rot.R[0][2] = sin_tilt); IRot.R[2][0] = -(Rot.R[2][0] = -sin_tilt); IRot.R[2][2] = Rot.R[2][2] = cos_tilt ; /* Rotation matrix for (x', y') */ IRot.R[1][1] = Rot.R[1][1] = cos_tilt ; IRot.R[1][3] = -(Rot.R[1][3] = sin_tilt); IRot.R[3][1] = -(Rot.R[3][1] = -sin_tilt); IRot.R[3][3] = Rot.R[3][3] = cos_tilt ; IRot.R[4][4] = IRot.R[5][5] = Rot.R[4][4] = Rot.R[5][5] = 1; concat_matrices(&Mr, M, &Rot, 0); concat_matrices(M , &IRot, &Mr , 0); free_matrices(&Mr); log_exit("tilt_matrices"); }
/*--------------------------------------------------------------------------- * * Compute matrix product using BLAS routine DGEMM. * * Input * int argc - length of argv[] array * char* argv[] - pointer to command line parameter array * int verbosity - program verification: verbosity > 0 gives more output * * Output * double - elapsed time for product computation */ double multiply_by_blas( int argc, char* argv[], int verbosity ) { int rows, cols, mids; double **a, **b, **c; double t1, t2; double sec; double gflop_count; /* * process command line arguments */ rows = atoi( argv[0] ); mids = atoi( argv[1] ); cols = atoi( argv[2] ); gflop_count = 2.0 * rows * mids * cols / 1.0e9; if ( verbosity > 0 ) { printf( "BLAS: rows = %d, mids = %d, columns = %d\n", rows, mids, cols ); } /* * allocate and initialize matrices */ a = (double**) allocateMatrix( rows, mids ); b = (double**) allocateMatrix( mids, cols ); c = (double**) allocateMatrix( rows, cols ); initialize_matrices( a, b, c, rows, cols, mids, verbosity ); /* * compute product: There is an implicit matrix transpose when * passing from Fortran to C and vice-versa. To compute C := * alpha * A * B + beta * C we use dgemm() to compute C' := alpha * * B' * A' + beta * C'. The first two arguments to dgemm() are * 'N' indicating we don't want a transpose in addition to the * implicit one. The matrices A and B are passed in reverse order * so dgemm() receives (after the implicit transpose) B' and A'. * Arguments 3 and 4 are the dimensions of C' and argument 5 is * the column dimension of B' (and the row dimension of A'). */ t1 = wtime(); dgemm( 'N', 'N', cols, rows, mids, 1.0, &b[0][0], cols, &a[0][0], mids, 0.0, &c[0][0], cols ); t2 = wtime(); sec = t2 - t1; if ( verbosity > 1 ) printf( "checksum = %f\n", checksum( c, rows, cols ) ); printf( "BLAS: %6.3f secs %6.3f gflops ( %5d x %5d x %5d )\n", sec, gflop_count / sec, rows, mids, cols ); /* * clean up */ deallocateMatrix( a ); deallocateMatrix( b ); deallocateMatrix( c ); return t2 - t1; }
void computeHigherOrderChromaticities(LINE_LIST *beamline, double *clorb, RUN *run, long concatOrder, double deltaStep, long deltaPoints, long quickMode) { #define MAX_NDELTA_VALUES 101 /* must be at least 5 */ double trace[2][MAX_NDELTA_VALUES], delta[MAX_NDELTA_VALUES]; double eta[6]; double coef[MAX_NDELTA_VALUES], sCoef[MAX_NDELTA_VALUES], chi; long i, p; double c1; VMATRIX M1, M0, *Mp; if (deltaPoints>MAX_NDELTA_VALUES) bombElegant("too many points for higher-order chromaticity", NULL); if (deltaPoints<5) deltaPoints = 5; if (!(beamline->matrix)) bombElegant("no matrix for beamline (computeHigherOrderChromaticities)", NULL); beamline->chrom2[0] = beamline->chrom2[1] = 0; beamline->chrom3[0] = beamline->chrom3[1] = 0; initialize_matrices(&M0, 1); initialize_matrices(&M1, concatOrder); eta[0] = beamline->twiss0->etax; eta[1] = beamline->twiss0->etapx; eta[2] = beamline->twiss0->etay; eta[3] = beamline->twiss0->etapy; eta[4] = 0; eta[5] = 1; for (p=0; p<deltaPoints; p++) { delta[p] = (p-(deltaPoints/2+1))*deltaStep; for (i=0; i<6; i++) { M0.C[i] = (clorb?clorb[i]:0)+delta[p]*eta[i] + (i<4? sqr(delta[p])*beamline->eta2[i] + pow3(delta[p])*beamline->eta3[i] : 0); M0.R[i][i] = 1; } if (quickMode) concat_matrices(Mp=&M1, beamline->matrix, &M0, 0); else Mp = append_full_matrix(beamline->elem_twiss, run, &M0, concatOrder); for (i=0; i<2; i++) /* Tr[0,1][p] is the trace for x,y plane for point p */ trace[i][p] = Mp->R[2*i][2*i] + Mp->R[2*i+1][2*i+1]; if (!quickMode) { free_matrices(Mp); free(Mp); Mp = NULL; } } for (i=0; i<2; i++) { lsfn(delta, trace[i], NULL, deltaPoints, (long)(MIN(deltaPoints-2,5)), coef, sCoef, &chi, NULL); c1 = -coef[1]/(4*PI*sin(PIx2*beamline->tune[i])); beamline->chrom2[i] = ( 2*coef[2] + 8*sqr(PI)*sqr(c1)*cos(PIx2*beamline->tune[i]) )/(-4*PI*sin(PIx2*beamline->tune[i])); if (quickMode) beamline->chrom3[i] = 0; else beamline->chrom3[i] = ( 6*coef[3] - 16*pow3(PI*c1)*sin(PIx2*beamline->tune[i]) + 24*sqr(PI)*c1*beamline->chrom2[i]*cos(PIx2*beamline->tune[i]) )/(-4*PI*sin(PIx2*beamline->tune[i])); } free_matrices(&M0); free_matrices(&M1); }
int run_coupled_twiss_output(RUN *run, LINE_LIST *beamline, double *starting_coord) { char JOBVL, JOBVR; int N, LDA, LDVL, LDVR, lwork, info, i, j, k; double A[36], WR[6], WI[6], VL[36], VR[36], work[1000]; double emit[3], Norm[3], Vnorm[36]; double Amatrix[108], SigmaMatrix[6][6]; int matDim, eigenModesNumber; double transferMatrix[36]; VMATRIX *M, *M1; double **R; ELEMENT_LIST *eptr, *eptr0; long nElements, lastNElements, iElement; double betax1, betax2, betay1, betay2, etax, etay, tilt; if (!initialized) return 0; if (verbosity>1) fprintf(stdout, "\n* Computing coupled sigma matrix\n"); if (emittances_from_twiss_command) { if (!(beamline->flags&BEAMLINE_TWISS_DONE)) { fprintf(stderr, "emittances_from_twiss_command was set but twiss calculations not seen"); return(1); } if (!(beamline->flags&BEAMLINE_RADINT_DONE)) { fprintf(stderr, "emittances_from_twiss_command was set but radiation integral calculations not seen"); return(1); } emit_x = beamline->radIntegrals.ex0; sigma_dp = beamline->radIntegrals.sigmadelta; if (verbosity>1) fprintf(stdout, "Raw emittance = %e, momentum spread = %e\n", emit_x, sigma_dp); } fflush(stdout); emit[0] = emit_x; emit[1] = emit_x*emittance_ratio; /* Count the number of elements from the recirc element to the end. */ /* Also store the pointer to the recirc element. */ eptr = eptr0 = &(beamline->elem); nElements = lastNElements = beamline->n_elems; while (eptr) { if (eptr->type==T_RECIRC) { lastNElements = nElements; eptr0 = eptr; } eptr = eptr->succ; nElements--; } nElements = lastNElements; if (starting_coord) { /* use the closed orbit to compute the on-orbit R matrix */ M1 = tmalloc(sizeof(*M1)); initialize_matrices(M1, 1); for (i=0; i<6; i++) { M1->C[i] = starting_coord[i]; M1->R[i][i] = 1; } M = accumulate_matrices(eptr0, run, M1, concat_order, 0); free_matrices(M1); free(M1); M1 = NULL; } else M = accumulate_matrices(eptr0, run, NULL, concat_order, 0); R = M->R; if (verbosity > 2) { long order; order = M->order; M->order = 1; print_matrices(stdout, "One-turn matrix:", M); M->order = order; } /* Determination of matrix dimension for these calculations. */ if (calculate_3d_coupling != 1) { matDim=4; } else { if (abs(R[4][4])+abs(R[5][5])>=2) { printf("Either there is no cavity or 3rd mode is unstable. Only 2 modes will be calculated.\n"); matDim=4; } else { matDim=6; } } eigenModesNumber=matDim/2; /*--- Reducing matrix dimensions, A is reduced R */ for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { A[i*matDim+j]=R[j][i]; } } free_matrices(M); free(M); M = NULL; /*--- Changing time sign for symplecticity... */ if (matDim == 6) { for (i=0; i<6; i++) { A[24+i]=-1.0*A[24+i]; A[i*6+4]=-1.0*A[i*6+4]; } } if (verbosity > 3) { MatrixPrintout((double*)&A, &matDim, &matDim, 1); } /*--- Calculating eigenvectors using dgeev_ ... */ JOBVL='N'; JOBVR='V'; N=matDim; LDA=matDim; LDVL=1; LDVR=matDim; lwork=204; #if defined(SUNPERF) || defined(LAPACK) || defined(CLAPACK) dgeev_((char*)&JOBVL, (char*)&JOBVR, (int*)&N, (double*)&A, (int*)&LDA, (double*)&WR, (double*)&WI, (double*)&VL, (int*)&LDVL, (double*)&VR, (int*)&LDVR, (double*)&work, (int*)&lwork, (int*)&info); #else fprintf(stderr, "Error calling dgeev. You will need to install LAPACK and rebuild elegant\n"); return(1); #endif if (info != 0) { if (info < 0) { printf("Error calling dgeev, argument %d.\n", abs(info)); } if (info > 0) { printf("Error running dgeev, calculation of eigenvalue number %d failed.\n", info); } return(1); } if (verbosity > 0) { printf("Info: %d ; %f \n", info, work[0]); for(i=0; i<matDim; i++) { printf("%d: %9.6f + i* %10.6f\n",i,WR[i],WI[i]); } fflush(stdout); } if (verbosity > 1) { printf("Non-normalized vectors:\n"); MatrixPrintout((double*)&VR, &matDim, &matDim, 1); fflush(stdout); } /*--- Sorting of eigenvalues and eigenvectors according to (x,y,z)... */ SortEigenvalues((double*)&WR, (double*)&WI, (double*)&VR, matDim, eigenModesNumber, verbosity); /*--- Normalization of eigenvectors... */ for (k=0; k<eigenModesNumber; k++) { Norm[k]=0; for (i=0; i<eigenModesNumber; i++) { /* Index = Irow*matDim + Icolumn */ Norm[k]+=VR[2*k*matDim+2*i+1]*VR[(2*k+1)*matDim+2*i]-VR[2*k*matDim+2*i]*VR[(2*k+1)*matDim+2*i+1]; } Norm[k]=1.0/sqrt(fabs(Norm[k])); if (verbosity > 2) { printf("Norm[%d]= %12.4e \n",k,Norm[k]); } } for (k=0; k<eigenModesNumber; k++) { for (i=0; i<matDim; i++) { Vnorm[k*2*matDim+i]=VR[k*2*matDim+i]*Norm[k]; Vnorm[(k*2+1)*matDim+i]=VR[(k*2+1)*matDim+i]*Norm[k]; } } if (verbosity > 1) { printf("Normalized vectors:\n"); MatrixPrintout((double*)&Vnorm, &matDim, &matDim, 1); } if (SDDScoupledInitialized) { /*--- Prepare the output file */ if (!SDDS_StartPage(&SDDScoupled, nElements)) { fflush(stdout); SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } /*--- Loop over elements */ iElement=0; eptr = eptr0; while (eptr) { if (verbosity > 0) { printf("\nElement number %ld: %s\n", iElement, eptr->name); fflush(stdout); } if (!eptr->accumMatrix) { fprintf(stderr, "Error: no accumulated matrix found for element %s", eptr->name); return(1); } /*--- Reducing matrix dimensions */ R = eptr->accumMatrix->R; for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { transferMatrix[i*matDim+j]=R[j][i]; } } /*--- Changing time sign for symplecticity... */ if (matDim == 6) { for (i=0; i<6; i++) { transferMatrix[24+i]= -1.0*transferMatrix[24+i]; transferMatrix[i*6+4]=-1.0*transferMatrix[i*6+4]; } } /*--- Calculating A matrices (product of eigenvectors)... */ GetAMatrix((double*)&Vnorm, (double*)&transferMatrix, (double*)&Amatrix, &eigenModesNumber, &matDim); if (verbosity > 1) { for (k=0; k<eigenModesNumber; k++) { printf("A matrix for mode %d\n", k); MatrixPrintout((double*)&Amatrix[k*matDim*matDim], &matDim, &matDim, 1); } } /*--- Calculating sigma matrix... */ if (eigenModesNumber == 3) { emit[2]=sigma_dp*sigma_dp*Amatrix[2*matDim*matDim+4*matDim+4]; } for (i=0; i<matDim; i++) { for (j=0; j<matDim; j++) { SigmaMatrix[i][j]=0; for (k=0; k<eigenModesNumber; k++) { SigmaMatrix[i][j]+=emit[k]*Amatrix[k*matDim*matDim+i*matDim+j]; } } } if (verbosity > 0) { printf("Sigma matrix:\n"); MatrixPrintout((double*)&SigmaMatrix, &matDim, &matDim, 2); } tilt=0.5*atan(2*SigmaMatrix[0][2]/(SigmaMatrix[0][0]-SigmaMatrix[2][2])); if (SDDScoupledInitialized) { /*--- Calculating beam sizes: 0-SigmaX, 1-SigmaXP, 2-SigmaY, 3-SigmaYP, 4-BeamTilt, 5-BunchLength */ if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, "ElementName", eptr->name, "s", eptr->end_pos, "Sx", sqrt(SigmaMatrix[0][0]), "Sxp", sqrt(SigmaMatrix[1][1]), "Sy", sqrt(SigmaMatrix[2][2]), "Syp", sqrt(SigmaMatrix[3][3]), "xyTilt", tilt, "Ss", eigenModesNumber==3?sqrt(SigmaMatrix[4][4]):-1, NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } if (verbosity > 0) { printf("SigmaX = %12.4e, SigmaY = %12.4e, Beam tilt = %12.4e \n", sqrt(SigmaMatrix[0][0]), sqrt(SigmaMatrix[2][2]), 0.5*atan(2*SigmaMatrix[0][2]/(SigmaMatrix[0][0]-SigmaMatrix[2][2]))); printf("SigmaXP = %12.4e, SigmaYP = %12.4e, \n", sqrt(SigmaMatrix[1][1]), sqrt(SigmaMatrix[3][3])); if (eigenModesNumber==3) { printf("Bunch length = %12.4e \n", sqrt(SigmaMatrix[4][4])); } } betax1 = Amatrix[0]; betax2 = Amatrix[1*matDim*matDim]; betay1 = Amatrix[2*matDim+2]; betay2 = Amatrix[1*matDim*matDim+2*matDim+2]; etax = sqrt(Amatrix[2*matDim*matDim]*Amatrix[2*matDim*matDim+4*matDim+4]); etay = sqrt(Amatrix[2*matDim*matDim+2*matDim+2]*Amatrix[2*matDim*matDim+4*matDim+4]); if (SDDScoupledInitialized) { if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, "betax1", betax1, "betax2", betax2, "betay1", betay1, "betay2", betay2, "etax", etax, "etay", etay, NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } if (output_sigma_matrix) { char name[100]; for (i=0; i<matDim; i++) for (j=i; j<matDim; j++) { sprintf(name, "S%d%d", i+1, j+1); if (!SDDS_SetRowValues(&SDDScoupled, SDDS_SET_BY_NAME|SDDS_PASS_BY_VALUE, iElement, name, SigmaMatrix[i][j], NULL)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } } } } if (verbosity > 0) { printf("betax_1 = %12.4e, betax_2 = %12.4e \n", Amatrix[0], Amatrix[1*matDim*matDim]); printf("betay_1 = %12.4e, betay_2 = %12.4e \n", Amatrix[2*matDim+2], Amatrix[1*matDim*matDim+2*matDim+2]); printf("etax = %12.4e, etay = %12.4e \n", sqrt(Amatrix[2*matDim*matDim]*Amatrix[2*matDim*matDim+4*matDim+4]), sqrt(Amatrix[2*matDim*matDim+2*matDim+2]*Amatrix[2*matDim*matDim+4*matDim+4])); fflush(stdout); } if (eptr->type==T_MARK && ((MARK*)eptr->p_elem)->fitpoint) store_fitpoint_ctwiss_parameters((MARK*)eptr->p_elem, eptr->name, eptr->occurence, betax1, betax2, betay1, betay2, etax, etay, tilt); iElement++; eptr = eptr->succ; } if (SDDScoupledInitialized && !SDDS_WritePage(&SDDScoupled)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); return(1); } return(0); }
void MAST::NoniterativeUGFlutterSolver::calculate_sensitivity(MAST::FlutterRootBase& root, const libMesh::ParameterVector& params, const unsigned int i) { // make sure that the aero_structural_model is a valid pointer libmesh_assert(aero_structural_model); libMesh::out << " ====================================================" << std::endl << "UG Sensitivity Solution" << std::endl << " k_red = " << std::setw(10) << root.k_red << std::endl << " V_ref = " << std::setw(10) << root.V << std::endl; Complex eig = root.root, sens = 0., k_sens = 0., vref_sens = 0., den = 0.; // matrix to store the sensitivity of constraint wrt kref and vref // first row is constraint f1(k,v) = g = im(lambda)/re(lambda) = 0 // second row is constraint f2(k,v) = vref*sqrt(re(lambda))-1. = 0 RealMatrixX jac; // residual vector for the sensitivity problem, and total derivative vec // first row is for constraint f1(k,v) // first row is for constraint f2(k,v) RealVectorX res, dsens; jac.setZero(2,2); res.setZero(2); // get the sensitivity of the matrices ComplexMatrixX mat_A, mat_B, mat_A_sens, mat_B_sens; ComplexVectorX v; // initialize the baseline matrices initialize_matrices(root.k_red_ref, root.V_ref, mat_A, mat_B); // calculate the eigenproblem sensitivity initialize_matrix_sensitivity_for_param(params, i, root.k_red_ref, root.V_ref, mat_A_sens, mat_B_sens); // the eigenproblem is A x - lambda B x = 0 // therefore, the denominator is obtained from the inner product of // x^T B x // sensitivity is // -dlambda/dp x^T B x = - x^T (dA/dp - lambda dB/dp) // or // dlambda/dp = [x^T (dA/dp - lambda dB/dp)]/(x^T B x) // now calculate the quotient for sensitivity // numerator = ( dA/dp - lambda dB/dp) mat_B_sens *= -eig; mat_B_sens += mat_A_sens; v = mat_B_sens*root.eig_vec_right; den = root.eig_vec_left.dot(mat_B*root.eig_vec_right); sens = root.eig_vec_left.dot(v)/den; // sensitivity of f1(k,v) = im(lambda)/re(lambda) = 0 res(0) = sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2) * sens.real(); // sensitivity of f2(k,v) = vref*sqrt(real(lambda)) - 1 = 0 res(1) = root.V_ref*0.5*pow(eig.real(),-0.5)*sens.real(); // next we need the sensitivity of k_red before we can calculate // the sensitivity of flutter eigenvalue initialize_matrix_sensitivity_for_reduced_freq(root.k_red_ref, root.V_ref, mat_A_sens, mat_B_sens); // now calculate the quotient for sensitivity wrt k_red // calculate numerator mat_B_sens *= -eig; mat_B_sens += mat_A_sens; v = mat_B_sens*root.eig_vec_right; k_sens = root.eig_vec_left.dot(v) / den; // use this to calculate the partial derivative of f1 wrt k_red jac(0,0) = k_sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2)*k_sens.real(); jac(1,0) = root.V_ref*0.5*pow(eig.real(),-0.5)*k_sens.real(); // next we need the sensitivity of Vref constraint before we can calculate // the sensitivity of flutter eigenvalue initialize_matrix_sensitivity_for_V_ref(root.k_red_ref, root.V_ref, mat_A_sens, mat_B_sens); // now calculate the quotient for sensitivity wrt k_red // calculate numerator mat_B_sens *= -eig; mat_B_sens += mat_A_sens; v = mat_B_sens*root.eig_vec_right; vref_sens = root.eig_vec_left.dot(v) / den; // use this to calculate the partial derivative of f2 wrt vref jac(0,1) = vref_sens.imag()/eig.real() - eig.imag()/pow(eig.real(),2)*vref_sens.real(); jac(1,1) = sqrt(eig.real()) + root.V_ref*0.5*pow(eig.real(),-0.5)*vref_sens.real(); // now invert the Jacobian to calculate the sensitivity dsens = -jac.inverse()*res; // finally add the correction to the flutter sensitivity sens += k_sens * dsens(0) + vref_sens * dsens(1); // set value in the return root root.has_sensitivity_data = true; root.root_sens = sens; root.V_sens = -.5*sens.real()/pow(eig.real(), 1.5); libMesh::out << "Finished UG Sensitivity Solution" << std::endl << " ====================================================" << std::endl; }
std::pair<bool, MAST::FlutterSolutionBase*> MAST::NoniterativeUGFlutterSolver::newton_search(const MAST::FlutterSolutionBase& init_sol, const unsigned int root_num, const Real tol, const unsigned int max_iters) { std::pair<bool, MAST::FlutterSolutionBase*> rval(false, NULL); // assumes that the upper k_val has +ve g val and lower k_val has -ve // k_val Real k_red, v_ref; unsigned int n_iters = 0; std::auto_ptr<MAST::FlutterSolutionBase> new_sol; RealVectorX res, sol, dsol; RealMatrixX jac; ComplexMatrixX mat_A, mat_B, mat_A_sens, mat_B_sens; ComplexVectorX v; res.resize(2); sol.resize(2); dsol.resize(2); jac.resize(2,2); // initialize the solution to the values of init_sol k_red = init_sol.get_root(root_num).k_red_ref; v_ref = init_sol.get_root(root_num).V_ref; sol(0) = k_red; sol(1) = v_ref; const MAST::FlutterSolutionBase* prev_sol = &init_sol; bool if_continue = true; while (if_continue) { // evaluate the residual and Jacobians std::auto_ptr<MAST::FlutterSolutionBase> ug_sol = this->analyze(k_red, v_ref, prev_sol); ug_sol->print(_output); // add the solution to this solver _insert_new_solution(v_ref, ug_sol.release()); // now get a pointer to the previous solution // get the solution from the database for this reduced frequency std::map<Real, MAST::FlutterSolutionBase*>::iterator it = _flutter_solutions.find(k_red); libmesh_assert(it != _flutter_solutions.end()); rval.second = it->second; prev_sol = it->second; // solve the Newton update problem const MAST::FlutterRootBase& root = prev_sol->get_root(root_num); Complex eig = root.root, eig_k_red_sens = 0., den = 0., eig_V_ref_sens = 0.; // initialize the baseline matrices initialize_matrices(k_red, v_ref, mat_A, mat_B); // solve the sensitivity problem // first with respect to k_red // next we need the sensitivity of k_red before we can calculate // the sensitivity of flutter eigenvalue initialize_matrix_sensitivity_for_reduced_freq(k_red, v_ref, mat_A_sens, mat_B_sens); // now calculate the quotient for sensitivity wrt k_red // calculate numerator mat_B_sens *= -eig; mat_B_sens += mat_A_sens; v = mat_B_sens*root.eig_vec_right; den = root.eig_vec_left.dot(mat_B*root.eig_vec_right); eig_k_red_sens = root.eig_vec_left.dot(v) / den; // next, sensitivity wrt V_ref initialize_matrix_sensitivity_for_V_ref(k_red, v_ref, mat_A_sens, mat_B_sens); // now calculate the quotient for sensitivity wrt V_ref // calculate numerator mat_B_sens *= -eig; mat_B_sens += mat_A_sens; v = mat_B_sens*root.eig_vec_right; den = root.eig_vec_left.dot(mat_B*root.eig_vec_right); eig_V_ref_sens = root.eig_vec_left.dot(v) / den; // residual res(0) = eig.imag()/eig.real(); res(1) = v_ref*sqrt(eig.real()) - 1.; // Jacobian jac(0,0) = eig_k_red_sens.imag()/eig.real() - eig.imag()*pow(eig.real(),-2)*eig_k_red_sens.real(); jac(0,1) = eig_V_ref_sens.imag()/eig.real() - eig.imag()*pow(eig.real(),-2)*eig_V_ref_sens.real(); jac(1,0) = 0.5*v_ref*pow(eig.real(),-0.5)*eig_k_red_sens.real(); jac(1,1) = sqrt(eig.real()) + 0.5*v_ref*pow(eig.real(),-0.5)*eig_V_ref_sens.real(); /*std::auto_ptr<MAST::FlutterSolutionBase> ug_dsol = this->analyze(k_red+.001, v_ref, prev_sol); Complex deig = ug_dsol->get_root(root_num).root; deig -= eig; deig /= .001; std::cout << "fd deig/dk: " << deig << std::endl; std::cout << "analytical: " << eig_k_red_sens << std::endl; ug_dsol.reset(this->analyze(k_red, v_ref+.001, prev_sol).release()); deig = ug_dsol->get_root(root_num).root; deig -= eig; deig /= .001; std::cout << "fd deig/dV: " << deig << std::endl; std::cout << "analytical: " << eig_V_ref_sens << std::endl;*/ // now calculate the updates // r0 + J *dx = 0 // => dx = - inv(J) * r0 // => x1 = x0 + dx dsol = -jac.inverse()*res; sol += dsol; // get the updated parameter values k_red = sol(0); v_ref = sol(1); // increment the iteration counter n_iters++; // set the flag if (fabs(root.g) < tol) { rval.first = true; return rval; } if (n_iters >= max_iters) if_continue = false; } // return false, along with the latest sol rval.first = false; return rval; }