#include <math_tools.h>

Protected Member Functions | |
| math_tools () | |
| Default constructor, does nothing. | |
| ~math_tools () | |
| Default destructor, does nothing. | |
| double * | newton_step (int dim, double **_Hi, double *g) |
| Computes the Newton-Raphson optimization step. | |
| double ** | update_bfgs (int dim, double *_var_dif, double *grad_dif, double **_Hi_old) |
| Performs bfgs update on inverse of hessian matrix. | |
| double ** | update_ms (int dim, double *_var_dif, double *_grad_dif, double **_Hi_old) |
| Performs update on inverse of hessian matrix attributed to Murtah and Sargent among many others. | |
| double ** | rep_reduce (char *label, double **rep_matrix, int reps) |
| Reduces a set of representation vectors. | |
| double ** | rep_project (char *label, int dim_vec, double **result_vecs, int *irrep_proj) |
| Projects out irrep components from a reducible representation. | |
| double ** | orthogonalize (int nvecs, int dimvecs, double **vecs, int normalize, double norm_tol, int *nindep) |
| Othogonalizes a set of vectors. | |
General implementations of basic mathematical algorithms. The only dependency other than standard libraries is the PSI 3.0 library libciomr.
Definition at line 22 of file math_tools.h.
| double * math_tools::newton_step | ( | int | dim, | |
| double ** | _Hi, | |||
| double * | g | |||
| ) | [protected] |
Computes the Newton-Raphson optimization step.
| dim | number of variables | |
| **_Hi | inverse hessian matrix | |
| *g | gradient vector |
Definition at line 25 of file math_tools.cc.
References init_array().
Referenced by psi::extrema::zmat::newton_step().
00025 { 00026 00027 int i, j; 00028 double *_s; 00029 00030 _s = init_array(dim); 00031 00032 for(i=0;i<dim;++i) 00033 for(j=0;j<dim;++j) 00034 _s[i] += -1.0 * _Hi[i][j] * g[j]; 00035 00036 return _s; 00037 }
| double ** math_tools::update_bfgs | ( | int | dim, | |
| double * | _var_dif, | |||
| double * | _grad_dif, | |||
| double ** | _Hi_old | |||
| ) | [protected] |
Performs bfgs update on inverse of hessian matrix.
| dim | dimension of hessian inverse | |
| *_var_dif | difference of current and previous variable | |
| *grad_dif | difference of current and previous gradient | |
| **_Hi_old | inverse hessian from previous iteration |
Definition at line 52 of file math_tools.cc.
References free_matrix(), init_matrix(), and mmult().
Referenced by psi::extrema::coord_base::update_Hi().
00053 { 00054 00055 int i,j; 00056 double **temp_mat, **_Hi_new, **mat1, **mat2, **mat3, num1=0.0, num2=0.0; 00057 _Hi_new = init_matrix(dim,dim); 00058 temp_mat = init_matrix(1,dim); 00059 mat1 = init_matrix(dim,dim); 00060 mat2 = init_matrix(dim,dim); 00061 mat3 = init_matrix(dim,dim); 00062 00063 00064 mmult(&_grad_dif,0,_Hi_old,0,temp_mat,0,1,dim,dim,0); 00065 for(i=0;i<dim;++i) 00066 num1 += temp_mat[0][i]*_grad_dif[i]; 00067 00068 for(i=0;i<dim;++i) 00069 num2 += _var_dif[i]*_grad_dif[i]; 00070 00071 for(i=0;i<dim;++i) 00072 for(j=0;j<dim;++j) 00073 mat1[i][j] = _var_dif[i]*_var_dif[j]; 00074 00075 mmult(&_grad_dif,0,_Hi_old,0,temp_mat,0,1,dim,dim,0); 00076 for(i=0;i<dim;++i) 00077 for(j=0;j<dim;++j) 00078 mat2[i][j] = _var_dif[i]*temp_mat[0][j]; 00079 00080 free_matrix(temp_mat,1); 00081 temp_mat = init_matrix(dim,dim); 00082 for(i=0;i<dim;++i) 00083 for(j=0;j<dim;++j) 00084 temp_mat[i][j] = _grad_dif[i]*_var_dif[j]; 00085 mmult(_Hi_old,0,temp_mat,0,mat3,0,dim,dim,dim,0); 00086 00087 for(i=0;i<dim;++i) 00088 for(j=0;j<dim;++j) 00089 _Hi_new[i][j] = _Hi_old[i][j] + (1 + num1/num2)*(mat1[i][j]/num2) 00090 - mat2[i][j]/num2 - mat3[i][j]/num2; 00091 00092 free_matrix(temp_mat,dim); 00093 free_matrix(mat1,dim); 00094 free_matrix(mat2,dim); 00095 free_matrix(mat3,dim); 00096 00097 return _Hi_new; 00098 }
| double ** math_tools::update_ms | ( | int | dim, | |
| double * | _var_dif, | |||
| double * | _grad_dif, | |||
| double ** | _Hi_old | |||
| ) | [protected] |
Performs update on inverse of hessian matrix attributed to Murtah and Sargent among many others.
| dim | dimension of hessian inverse | |
| *_var_dif | difference of current and previous variable | |
| *_grad_dif | difference of current and previous gradient | |
| **_Hi_old | inverse hessian from previous iteration |
Definition at line 114 of file math_tools.cc.
References free_matrix(), init_array(), and init_matrix().
Referenced by psi::extrema::coord_base::update_Hi().
00115 { 00116 00117 int i, j; 00118 double div, *temp_arr, **temp_mat, **_Hi_new; 00119 00120 /*allocate memory*/ 00121 temp_arr = init_array(dim); 00122 temp_mat = init_matrix(dim,dim); 00123 _Hi_new = init_matrix(dim,dim); 00124 00125 for(i=0;i<dim;++i) { 00126 for(j=0;j<dim;++j) { 00127 temp_arr[i] += _Hi_old[i][j] * _grad_dif[j]; 00128 } 00129 } 00130 00131 for(i=0;i<dim;++i) { 00132 temp_arr[i] = 0.0; 00133 for(j=0;j<dim;++j) 00134 temp_arr[i] += _Hi_old[i][j] * _grad_dif[j]; 00135 } 00136 for(i=0;i<dim;++i) 00137 temp_arr[i] = _var_dif[i] - temp_arr[i]; 00138 00139 for(i=0;i<dim;++i) 00140 for(j=0;j<dim;++j) 00141 temp_mat[i][j] = temp_arr[i]*temp_arr[j]; 00142 00143 div = 0.0; 00144 for(i=0;i<dim;++i) 00145 div += temp_arr[i] * _grad_dif[i]; 00146 00147 for(i=0;i<dim;++i) 00148 for(j=0;j<dim;++j) 00149 _Hi_new[i][j] = _Hi_old[i][j] + temp_mat[i][j]/div; 00150 00151 /*free up memory*/ 00152 free(temp_arr); 00153 free_matrix(temp_mat,dim); 00154 00155 return _Hi_new; 00156 }
| double ** math_tools::rep_reduce | ( | char * | label, | |
| double ** | rep_matrix, | |||
| int | num_reps | |||
| ) | [protected] |
Reduces a set of representation vectors.
| label | the point group label | |
| rep_matrix | the matrix of representations, each representation should be a row of this matrix whose length = number of irreps Parses input |
Definition at line 24 of file symmetry.cc.
References psi::extrema::char_table::ctable, init_matrix(), psi::extrema::char_table::num_irreps, and psi::extrema::char_table::ops_coeffs.
00024 { 00025 00026 int i,j, vec, rep, pg_order=0; 00027 char_table ctab(label); 00028 double **coef_matrix, red_coef; 00029 00030 coef_matrix = init_matrix(num_reps,ctab.num_irreps); 00031 00032 for(i=0;i<ctab.num_irreps;++i) 00033 pg_order += ctab.ops_coeffs[i]; 00034 00035 int prod; 00036 for(rep=0;rep<num_reps;++rep) { 00037 for(i=0;i<ctab.num_irreps;++i) { 00038 red_coef = 0.0; 00039 for(j=0;j<ctab.num_irreps;++j) { 00040 prod = ctab.ctable[i][j] * ctab.ops_coeffs[j]; 00041 red_coef += rep_matrix[rep][j] * (double) prod; 00042 } 00043 coef_matrix[rep][i] = red_coef/(double)pg_order; 00044 } 00045 } 00046 00047 return coef_matrix; 00048 }
| double ** math_tools::rep_project | ( | char * | label, | |
| int | dim_vec, | |||
| double ** | result_vecs, | |||
| int * | irrep_proj | |||
| ) | [protected] |
Projects out irrep components from a reducible representation.
| label | point group label | |
| num_vars | dimension of the vector | |
| vectors | resulting from each symmetry operation | |
| irrep_proj | 1 if irrep should be projected out and returned |
Definition at line 62 of file symmetry.cc.
References psi::extrema::char_table::ctable, init_matrix(), psi::extrema::char_table::num_irreps, and psi::extrema::char_table::ops_coeffs.
00063 { 00064 00065 int i,j,ir, proj_num, num_projections, pg_order; 00066 double **projected; 00067 char_table c(label); 00068 00069 num_projections=0; 00070 for(ir=0;ir<c.num_irreps;++ir) 00071 if( irrep_proj[ir] ) 00072 ++num_projections; 00073 projected = init_matrix(num_projections,dim_vec); 00074 00075 pg_order=0; 00076 for(i=0;i<c.num_irreps;++i) 00077 pg_order += c.ops_coeffs[i]; 00078 00079 /* project out desired irreps */ 00080 proj_num = 0; 00081 for(ir=0;ir<c.num_irreps;++ir) 00082 if( irrep_proj[ir] ) { 00083 for(i=0;i<c.num_irreps;++i) 00084 for(j=0;j<dim_vec;++j) { 00085 projected[proj_num][j] += c.ctable[ir][i]* 00086 result_vecs[i][j]; 00087 } 00088 for(i=0;i<dim_vec;++i) 00089 projected[proj_num][i] /= (double) pg_order; 00090 ++proj_num; 00091 } 00092 00093 return projected; 00094 }
| double ** math_tools::orthogonalize | ( | int | nvecs, | |
| int | dimvecs, | |||
| double ** | vecs, | |||
| int | normalize, | |||
| double | norm_tol, | |||
| int * | nindep | |||
| ) | [protected] |
Othogonalizes a set of vectors.
| nvecs | number of vectors to orthogonalize | |
| dimvecs | length of each vector | |
| vec | nvec x dimvecs matrix containing vectors | |
| nindep | where number of independent vectors is saved | |
| norm_tol | norm of vectors big enough to keep | |
| normalize | 1 if vectors should be normalized as well /*------------------------------------------------------------------------ |
Definition at line 111 of file symmetry.cc.
References ALMOST_ZERO, init_array(), and init_matrix().
00113 { 00114 00115 int i,j,k,p, num_big=0; 00116 double **omat_temp, **omat, norm, dot1, dot2, *temp; 00117 00118 temp = init_array(dimvecs); 00119 00120 /* max number of independent vectors is nvecs */ 00121 omat_temp = init_matrix(nvecs,dimvecs); 00122 00123 /* start with first vector */ 00124 for(i=0;i<dimvecs;++i) 00125 omat_temp[0][i] = vecs[0][i]; 00126 00127 /* make each vector orthogonal to all previous vectors */ 00128 for(i=1;i<nvecs;++i) { 00129 for(k=0;k<dimvecs;++k) 00130 omat_temp[i][k] = vecs[i][k]; 00131 for(j=0;j<i;++j) { 00132 dot1=dot2=0.0; 00133 for(k=0;k<dimvecs;++k) { 00134 dot1 += vecs[i][k]*omat_temp[j][k]; 00135 dot2 += omat_temp[j][k]*omat_temp[j][k]; 00136 } 00137 if( (fabs(dot1)>ALMOST_ZERO) && (dot2>ALMOST_ZERO) ) { 00138 for(k=0;k<dimvecs;++k) 00139 omat_temp[i][k] -= dot1/dot2 * omat_temp[j][k]; 00140 } 00141 } 00142 } 00143 00144 /* if norm greater than tolerance, copy over to omat */ 00145 for(i=0;i<nvecs;++i) { 00146 norm = 0.0; 00147 for(j=0;j<dimvecs;++j) 00148 norm += omat_temp[i][j]*omat_temp[i][j]; 00149 if(norm>norm_tol) 00150 ++num_big; 00151 } 00152 00153 omat = init_matrix(num_big,dimvecs); 00154 00155 p=0; 00156 for(i=0;i<nvecs;++i) { 00157 norm = 0.0; 00158 for(j=0;j<dimvecs;++j) 00159 norm += omat_temp[i][j]*omat_temp[i][j]; 00160 if(norm>norm_tol) { 00161 for(j=0;j<dimvecs;++j) 00162 omat[p][j] = omat_temp[i][j]; 00163 ++p; 00164 } 00165 } 00166 00167 (*nindep) = num_big; 00168 00169 if(normalize) 00170 for(i=0;i<num_big;++i) { 00171 norm=0; 00172 for(j=0;j<dimvecs;++j) 00173 norm += omat[i][j] * omat[i][j]; 00174 for(j=0;j<dimvecs;++j) 00175 omat[i][j] /= sqrt(norm); 00176 } 00177 00178 return omat; 00179 }
1.5.4