38 std::unique_ptr<helpers::tmatrix<unsigned int>>
TPM::s2t =
nullptr;
39 std::unique_ptr<helpers::tmatrix<unsigned int>>
TPM::t2s =
nullptr;
76 (*
s2t)(a,a+
L) = (*
s2t)(a+
L,a) = tel++;
80 for(
int b=a+1;b<
L;b++)
81 (*
s2t)(a,b) = (*
s2t)(b,a) = tel++;
85 for(
int b=a+1;b<M;b++)
86 (*
s2t)(a,b) = (*
s2t)(b,a) = tel++;
90 for(
int b=L+a+1;b<M;b++)
92 (*s2t)(a,b) = (*
s2t)(b,a) = tel++;
96 for(
int b=a%L+1;b<
L;b++)
98 (*s2t)(a,b) = (*
s2t)(b,a) = tel++;
103 for(
int b=a+1;b<M;b++)
105 (*t2s)((*s2t)(a,b),0) = a;
106 (*t2s)((*s2t)(a,b),1) = b;
151 return sign * (*this)(0,i,j);
161 output <<
"Block: " << std::endl;
162 for(
int i=0;i<tpm.
L;i++)
163 for(
int j=i;j<tpm.
L;j++)
164 output << i <<
"\t" << j <<
"\t|\t" << (*tpm.
t2s)(i,0) <<
" " << (*tpm.
t2s)(i,1) <<
" ; " << (*tpm.
t2s)(j,0) <<
" " << (*tpm.
t2s)(j,1) <<
"\t\t" << tpm(0,i,j) << std::endl;
168 output <<
"Vector (4x): " << std::endl;
170 output << i <<
"\t|\t" << (*tpm.
t2s)(tpm.
L+i,0) <<
" " << (*tpm.
t2s)(tpm.
L+i,1) <<
"\t\t" << tpm(0,i) << std::endl;
183 void TPM::ham(std::function<
double(
int,
int)> &T, std::function<
double(
int,
int,
int,
int)> &V)
186 auto calc_elem = [
this,&T,&V] (
int i,
int j) {
201 result += (T(a_,a_) + T(b_,b_))/(
N - 1.0);
206 if(b==(a+
L) && d==(c+
L))
207 result += V(a_,b_,c_,d_);
210 if(i==j && a<
L && b<
L && a!=b)
211 result += V(a_,b_,c_,d_) - V(a_,b_,d_,c_);
214 if(i==j && a>=
L && b>=
L && a!=b)
215 result += V(a_,b_,c_,d_) - V(a_,b_,d_,c_);
218 if(i==j && a<L && b>=
L && a%
L!=b%
L)
219 result += V(a_,b_,c_,d_);
222 if(i==j && a>=L && b<L && a%L!=b%L)
223 result += V(a_,b_,c_,d_);
233 hamB(i,j) = hamB(j,i) = calc_elem(i,j);
237 for(
int i=0;i<hamV.gn();i++)
240 hamV[i] = 0.5*calc_elem(L+i,L+i) + 0.5*calc_elem(L*L+i,L*L+i);
245 hid_t file_id, group_id, dataset_id;
249 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
252 group_id = H5Gopen(file_id,
"/integrals", H5P_DEFAULT);
255 dataset_id = H5Dopen(group_id,
"OEI", H5P_DEFAULT);
260 status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, OEI.
gMatrix());
263 status = H5Dclose(dataset_id);
268 dataset_id = H5Dopen(group_id,
"TEI", H5P_DEFAULT);
271 status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, TEI.
gMatrix());
274 status = H5Dclose(dataset_id);
277 status = H5Gclose(group_id);
280 status = H5Fclose(file_id);
294 std::function<double(int,int)> getT = [&OEI] (
int a,
int b) ->
double {
return OEI(a,b); };
295 std::function<double(int,int,int,int)> getV = [&TEI,
this] (
int a,
int b,
int c,
int d) ->
double {
return TEI(a*L + b,c*L + d); };
306 hid_t dataset_id, attribute_id, dataspace_id;
312 dataspace_id = H5Screate_simple(1, &dimblock, NULL);
314 dataset_id = H5Dcreate(group_id,
"Block", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
318 status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
321 status = H5Sclose(dataspace_id);
324 status = H5Dclose(dataset_id);
330 dataspace_id = H5Screate_simple(1, &dimblock, NULL);
332 dataset_id = H5Dcreate(group_id,
"Vector", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
336 status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);
339 status = H5Sclose(dataspace_id);
342 status = H5Dclose(dataset_id);
346 dataspace_id = H5Screate(H5S_SCALAR);
348 attribute_id = H5Acreate (group_id,
"L", H5T_STD_I64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
349 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
L );
352 status = H5Aclose(attribute_id);
355 attribute_id = H5Acreate (group_id,
"N", H5T_STD_I64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
356 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
N );
359 status = H5Aclose(attribute_id);
362 status = H5Sclose(dataspace_id);
367 dataspace_id = H5Screate_simple(1, &dims, NULL);
369 int typeofcalculation[6];
371 typeofcalculation[0] = 1;
374 typeofcalculation[1] = 1;
376 typeofcalculation[1] = 0;
380 typeofcalculation[2] = 1;
382 typeofcalculation[2] = 0;
386 typeofcalculation[3] = 1;
388 typeofcalculation[3] = 0;
392 typeofcalculation[4] = 1;
394 typeofcalculation[4] = 0;
398 typeofcalculation[5] = 1;
400 typeofcalculation[5] = 0;
403 attribute_id = H5Acreate (group_id,
"Type", H5T_STD_I64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
404 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &typeofcalculation[0] );
407 status = H5Aclose(attribute_id);
410 status = H5Sclose(dataspace_id);
420 hid_t file_id, group_id;
423 file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
425 group_id = H5Gcreate(file_id,
"/RDM", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
429 status = H5Gclose(group_id);
432 status = H5Fclose(file_id);
444 hid_t file_id, group_id;
447 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
450 group_id = H5Gopen(file_id,
"/RDM", H5P_DEFAULT);
455 status = H5Gclose(group_id);
458 status = H5Fclose(file_id);
473 dataset_id = H5Dopen(group_id,
"Block", H5P_DEFAULT);
476 status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
getMatrix(0).gMatrix());
479 status = H5Dclose(dataset_id);
483 dataset_id = H5Dopen(group_id,
"Vector", H5P_DEFAULT);
486 status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
getVector(0).gVector());
489 status = H5Dclose(dataset_id);
501 for(
int i = 0;i<
n;++i)
506 const double s_a = ( 1.0 - 2 * (a /
L) )/2.0;
507 const double s_b = ( 1.0 - 2 * (b /
L) )/2.0;
509 spin += ( (1 + s_a*s_a + s_b*s_b)/(
N - 1.0) + 2*s_a*s_b ) * (*
this)(a,b,a,b);
513 for(
int a = 0;a <
L;++a)
514 for(
int b = 0;b <
L;++b)
515 spin += (*
this)(a,L+b,a+
L,b);
542 for(
int i=0;i<lineq.
gnr();i++)
548 assert(0 &&
"You should not be here!");
553 (*
this)(0,i,i) -= trace;
558 (*
this)(0,i) -= trace;
614 double tmp =
trace() / (
N*(
N-1)/2.0);
618 (*
this)(0,i,i) += tmp - 2 * tpm(0,i,i);
621 spm.
bar2(1.0/(
N/2.0-1.0),tpm);
626 int a = (*t2s)(L+i,0);
627 int b = (*t2s)(L+i,1);
629 (*this)(0,i) += tmp - spm(0,a) - spm(0,b);
635 void TPM::Q(
double alpha,
double beta,
double gamma,
const TPM &tpm,
bool inverse)
639 beta = (beta*alpha + beta*gamma*2*
L - 2.0*gamma*gamma)/(alpha * (gamma*(2*
L - 2.0) - alpha) * ( alpha + beta*2*
L*(2*
L - 1.0) - 2.0*gamma*(2*
L - 1.0) ) );
640 gamma = gamma/(alpha*(gamma*((2*
L) - 2.0) - alpha));
645 spm.
bar3(gamma, tpm);
650 double tmp = beta *
trace();
654 (*
this)(0,i,i) += tmp - 2 * spm(0,i);
659 int a = (*t2s)(L+i,0);
660 int b = (*t2s)(L+i,1);
662 (*this)(0,i) += tmp - spm(0,a) - spm(0,b);
677 double rr = r.
ddot(r);
685 Hb.
H(t,grad,S, lineq);
687 ward = rr/grad.
ddot(Hb);
690 this->
daxpy(ward, grad);
700 grad.
dscal(rr/rr_old);
709 std::cout <<
"Too many cg iterations: " << iter <<
"\t" << rr << std::endl;
769 double tolerance = 1.0e-5*t;
771 if(tolerance < 1.0e-12)
785 hulp.
L_map(S,S_delta);
791 double b = -1.0/eigen.
min();
795 double ham_delta = ham.
ddot(*
this);
797 while(b - a > tolerance)
801 if( (ham_delta - t*eigen.
lsfunc(c)) < 0.0)
819 hid_t file_id, dataset_id;
822 std::unique_ptr<Matrix> rdm_tmp(
new Matrix (
L*(2*
L-1)));
824 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
827 dataset_id = H5Dopen(file_id,
"/matrix", H5P_DEFAULT);
830 status = H5Dread(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdm_tmp->
gMatrix());
833 status = H5Dclose(dataset_id);
836 status = H5Fclose(file_id);
856 for(
int i=0;i<lineq.
gnr();++i)
874 std::vector<TPM> list;
889 constr(0,i-L) = 1.0/(
N/2.0-1)/4.0;
892 list.push_back(std::move(constr));
913 return (*
this)(0,i-
L);
932 b += (4.0*
N*
N + 2.0*
N - 4.0*
N*M + M*M - M)/(
N*
N*(
N - 1.0)*(
N - 1.0));
933 c += (2.0*
N - M)/((
N - 1.0)*(
N - 1.0));
960 this->
Q(a,b,c,tpm_d);
988 double rr = r.
ddot(r);
1003 ward = rr/b.
ddot(Hb);
1006 this->
daxpy(ward,b);
1032 std::vector<double> B11(
L,0);
1033 std::vector<double> B22(
L,0);
1035 for(
int a=0;a<
L;a++)
1036 for(
int b=a+1;b<
L;b++)
1040 B11[a] += block(0,0);
1041 B22[b] += block(1,1);
1046 const int a = (*t2s)(L+i,0);
1047 const int b = (*t2s)(L+i,1);
1051 (*this)(0,i) = 0.25*(2.0/(
N-1.0)*(phm[0](a,a)+phm[0](b,b)+B11[a]+B11[b]+B22[a]+B22[b]) - block(0,0) - block(1,1) + 2*phm[0](a,b));
1054 for(
int a=0;a<
L;a++)
1056 for(
int b=a+1;b<
L;b++)
1059 (*this)(0,a,b) = (*
this)(0,b,a) = -block(0,1);
1062 (*this)(0,a,a) = 1.0/(
N-1.0)*(B11[a]+B22[a]+phm[0](a,a));
1089 std::vector<double> Elevels(
L);
1092 for(
int i=0;i<
L;i++)
1095 std::vector<double> x(L);
1098 for(
int a=0;a<
L;a++)
1102 double bright = 0.0;
1105 bright += elem*elem;
1109 bright = 1.0/std::sqrt(bright);
1116 auto calc_elem = [
this,&g,&Elevels,&x] (
int i,
int j) {
1117 int a = (*t2s)(i,0);
1118 int b = (*t2s)(i,1);
1119 int c = (*t2s)(j,0);
1120 int d = (*t2s)(j,1);
1131 result += (Elevels[a_] + Elevels[b_])*1.0/(
N-1.0);
1134 result -= g * x[a_] * x[a_];
1136 else if(a_ == b_ && c_ == d_)
1137 result -= g * x[a_] * x[c_];
1144 for(
int i=0;i<
L;++i)
1145 for(
int j=i;j<
L;++j)
1146 hamB(i,j) = hamB(j,i) = calc_elem(i,j);
1150 for(
int i=0;i<hamV.gn();i++)
1153 hamV[i] = 0.5*calc_elem(L+i,L+i) + 0.5*calc_elem(L*L+i,L*L+i);
1170 const double cos = std::cos(angle);
1171 const double sin = std::sin(angle);
1172 const double cos2 = cos*cos;
1173 const double sin2 = sin*sin;
1174 const double cos4 = cos2*cos2;
1175 const double sin4 = sin2*sin2;
1176 const double cos2sin2 = cos2*sin2;
1178 for(
int p=0;p<
L;p++)
1183 rdmB(k,p) = rdmB(p,k) = cos2*(*this)(0,k,p)+sin2*(*
this)(0,l,p);
1185 rdmB(l,p) = rdmB(p,l) = cos2*(*this)(0,l,p)+sin2*(*
this)(0,k,p);
1187 int idx1 = (*s2t)(k,p) - L;
1188 int idx2 = (*s2t)(l,p) - L;
1190 rdmV[idx1] = cos2 * (*this)(k,p,k,p) + sin2 * (*
this)(l,p,l,p);
1191 rdmV[idx2] = cos2 * (*this)(l,p,l,p) + sin2 * (*
this)(k,p,k,p);
1195 rdmB(k,k) = cos4 * (*this)(0,k,k) + 2 * cos2sin2 * (*
this)(0,k,l) + sin4 * (*
this)(0,l,l) + \
1196 2 * cos2sin2 * (*
this)(k,l,k,l);
1199 rdmB(l,l) = cos4 * (*this)(0,l,l) + 2 * cos2sin2 * (*
this)(0,k,l) + sin4 * (*
this)(0,k,k) + \
1200 2 * cos2sin2 * (*
this)(k,l,k,l);
1203 rdmB(k,l) = cos2sin2 * (*this)(0,k,k) + (cos4 + sin4) * (*this)(0,k,l) + cos2sin2 * (*
this)(0,l,l) - \
1204 2 * cos2sin2 * (*
this)(k,l,k,l);
1205 rdmB(l,k) = rdmB(k,l);
1207 int idx = (*s2t)(k,l) - L;
1208 rdmV[idx] += cos2sin2*((*this)(0,k,k)+(*
this)(0,l,l)-2*(*
this)(0,k,l))+(cos4+sin4)*(*
this)(k,l,k,l);
1211 (*this) = std::move(new_rdm);
1227 auto A = [&] (
int a,
int b,
int a2,
int b2) ->
double {
return ham(0,a,b)*(*this)(0,a2,b2) + 2*
ham(a,b,a,b)*(*this)(a2,b2,a2,b2); };
1228 auto B = [&] (
int a,
int b,
int a2,
int b2) ->
double {
return ham(0,a,b)*(*this)(a2,b2,a2,b2) +
ham(a,b,a,b)*((*this)(0,a2,b2) - (*
this)(a2,b2,a2,b2)); };
1230 for(
int a=0;a<
L;a++)
1235 for(
int b=0;b<
L;b++)
1239 energy += A(a,b,a,b);
1241 energy += 2 * std::cos(theta)*std::cos(theta) * ( A(k,a,k,a) + A(l,a,l,a) ) + 2 * std::sin(theta)*std::sin(theta) * ( A(k,a,l,a) + A(l,a,k,a) );
1245 energy += std::cos(theta)*std::cos(theta)*std::cos(theta)*std::cos(theta) * (A(l,l,l,l)+A(k,k,k,k)+2*A(k,l,k,l));
1248 energy += std::sin(theta)*std::sin(theta)*std::sin(theta)*std::sin(theta) * (A(k,k,l,l)+A(l,l,k,k)+2*A(k,l,k,l));
1251 energy += std::cos(theta)*std::cos(theta)*std::sin(theta)*std::sin(theta) * 2.0 * (A(l,l,k,l)+A(k,l,l,l)+A(k,l,k,k)+A(k,k,k,l) + \
1252 B(l,l,k,l)+B(k,l,l,l)+B(k,l,k,k)+B(k,k,k,l) -2*B(k,l,k,l));
1271 for(
int i=0;i<2*
L;i++)
1273 rot(k,k) = std::cos(theta);
1274 rot(l,l) = std::cos(theta);
1275 rot(k,l) = -1.0*std::sin(theta);
1276 rot(l,k) = std::sin(theta);
1278 rot(k+L,k+L) = std::cos(theta);
1279 rot(l+L,l+L) = std::cos(theta);
1280 rot(k+L,l+L) = -1.0*std::sin(theta);
1281 rot(l+L,k+L) = std::sin(theta);
1283 for(
int a=0;a<2*
L;a++)
1284 for(
int b=0;b<2*
L;b++)
1285 for(
int c=0;c<2*
L;c++)
1286 for(
int d=0;d<2*
L;d++)
1288 if(fabs((*
this)(a,b,c,d)) < 1e-14)
1291 for(
int a2=0;a2<2*
L;a2++)
1292 for(
int b2=0;b2<2*
L;b2++)
1293 for(
int c2=0;c2<2*
L;c2++)
1294 for(
int d2=0;d2<2*
L;d2++)
1296 if(fabs(
ham(a2,b2,c2,d2)) < 1e-14)
1299 energy += 0.25 *
ham(a,b,c,d) * rot(a,a2) * rot(b,b2) * \
1300 rot(c,c2)* rot(d,d2)* (*this)(a2,b2,c2,d2);
1319 double theta = start_angle;
1321 auto A = [&] (
int a,
int b,
int a2,
int b2) ->
double {
return ham(a,a+
L,b,b+
L)*(*this)(a2,a2+
L,b2,b2+
L) + 2*
ham(a,b,a,b)*(*this)(a2,b2,a2,b2); };
1322 auto B = [&] (
int a,
int b,
int a2,
int b2) ->
double {
return ham(a,a+
L,b,b+
L)*(*this)(a2,b2,a2,b2) +
ham(a,b,a,b)*((*this)(a2,a2+
L,b2,b2+
L) - (*
this)(a2,b2,a2,b2)); };
1328 for(
int a=0;a<
L;a++)
1333 sum1 += A(k,a,k,a) + A(l,a,l,a);
1334 sum2 += A(k,a,l,a) + A(l,a,k,a);
1337 const double cos4 = A(l,l,l,l) + A(k,k,k,k) + 2*A(k,l,k,l);
1338 const double sin4 = A(k,k,l,l) + A(l,l,k,k) + 2*A(k,l,k,l);
1339 const double cos2sin2 = A(l,l,k,l) + A(k,l,l,l) + A(k,l,k,k) + A(k,k,k,l) + \
1340 B(l,l,k,l) + B(k,l,l,l) + B(k,l,k,k) + B(k,k,k,l) - 2*B(l,k,l,k);
1342 auto gradient = [&cos4,&sin4,&cos2sin2,&sum1,&sum2] (
double t) ->
double {
1343 return -4*std::sin(t)*std::cos(t) * (std::cos(t)*std::cos(t)*(cos4 + sin4 - 2 * cos2sin2) + cos2sin2 - sin4 + sum1 - sum2);
1346 auto hessian = [&cos4,&sin4,&cos2sin2,&sum1,&sum2] (
double t) ->
double {
1347 return ((-cos4-sin4+2*cos2sin2) * 16 * std::cos(t)*std::cos(t) + (12*cos4+20*sin4-8*sum1+8*sum2-32*cos2sin2))*std::cos(t)*std::cos(t)-4*sin4+4*sum1-4*sum2+4*cos2sin2;
1350 int max_iters = 100;
1353 for(
int iter=0;iter<max_iters;iter++)
1355 new_theta = theta - gradient(theta)/hessian(theta);
1359 if(fabs(gradient(theta)) < 1e-12)
1371 return std::make_pair(theta, hessian(theta)>0);
1383 double TPM::calc_rotate_slow(
int k,
int l,
double theta, std::function<
double(
int,
int)> &T, std::function<
double(
int,
int,
int,
int)> &V)
const
1392 rot(k,k) = std::cos(theta);
1393 rot(l,l) = std::cos(theta);
1394 rot(k,l) = -1*std::sin(theta);
1395 rot(l,k) = std::sin(theta);
1397 for(
int a=0;a<
L;a++)
1398 for(
int b=0;b<
L;b++)
1399 for(
int a2=0;a2<
L;a2++)
1400 for(
int b2=0;b2<
L;b2++)
1402 energy += 2.0/(
N-1.0) * (rot(a,a2)*rot(a,b2)+rot(b,a2)*rot(b,b2))*(*
this)(a,b,a,b)*T(a2,b2);
1405 energy += 2.0/(
N-1.0)*rot(a,a2)*rot(a,b2)*(*this)(a,a+
L,a,a+
L)*T(a2,b2);
1407 for(
int c2=0;c2<
L;c2++)
1408 for(
int d2=0;d2<
L;d2++)
1409 energy += V(a2,b2,c2,d2) * ( \
1410 rot(a,a2)*rot(a,b2)*rot(b,c2)*rot(b,d2)* (*this)(a,a+
L,b,b+
L) + \
1411 rot(a,a2)*rot(b,b2)*( \
1412 2*rot(a,c2)*rot(b,d2) -
1413 rot(b,c2)*rot(a,d2) ) * \
1431 double TPM::calc_rotate(
int k,
int l,
double theta, std::function<
double(
int,
int)> &T, std::function<
double(
int,
int,
int,
int)> &V)
const
1435 const TPM &rdm = *
this;
1437 double energy = 4/(
N-1.0)*(T(k,k)+T(l,l)) * rdm(k,l,k,l);
1439 double cos2 = 2.0/(
N-1.0)*(T(k,k)*rdm(k,k+
L,k,k+
L)+T(l,l)*rdm(l,l+
L,l,l+
L));
1441 double sin2 = 2.0/(
N-1.0)*(T(l,l)*rdm(k,k+
L,k,k+
L)+T(k,k)*rdm(l,l+
L,l,l+
L));
1444 double sincos = 2.0/(
N-1.0)*T(k,l)*(rdm(l,l+
L,l,l+
L)-rdm(k,k+
L,k,k+
L));
1446 for(
int a=0;a<
L;a++)
1451 energy += 2.0/(
N-1.0) * T(a,a) * (rdm(a,a+L,a,a+L)+2*rdm(a,k,a,k)+2*rdm(a,l,a,l));
1453 for(
int b=0;b<
L;b++)
1458 energy += 2.0/(
N-1.0) * (T(a,a)+T(b,b)) * rdm(a,b,a,b);
1460 energy += V(a,a,b,b) * rdm(a,a+L,b,b+L);
1462 energy += (2*V(a,b,a,b)-V(a,b,b,a)) * rdm(a,b,a,b);
1465 cos2 += 2*V(k,k,a,a)*rdm(k,k+L,a,a+L)+2*V(l,l,a,a)*rdm(l,l+L,a,a+L)+2*(2*V(k,a,k,a)-V(k,a,a,k)+2.0/(
N-1.0)*T(k,k))*rdm(k,a,k,a)+2*(2*V(l,a,l,a)-V(l,a,a,l)+2.0/(
N-1.0)*T(l,l))*rdm(l,a,l,a);
1467 sin2 += 2*V(l,l,a,a)*rdm(k,k+L,a,a+L)+2*V(k,k,a,a)*rdm(l,l+L,a,a+L)+2*(2*V(k,a,k,a)-V(k,a,a,k)+2.0/(
N-1.0)*T(k,k))*rdm(l,a,l,a)+2*(2*V(l,a,l,a)-V(l,a,a,l)+2.0/(
N-1.0)*T(l,l))*rdm(k,a,k,a);
1469 sincos += 2*V(k,l,a,a)*(rdm(l,l+L,a,a+L)-rdm(k,k+L,a,a+L))+2*(2*V(k,a,l,a)-V(k,a,a,l)+2.0/(
N-1.0)*T(k,l))*(rdm(l,a,l,a)-rdm(k,a,k,a));
1472 const double cos4 = V(k,k,k,k)*rdm(k,k+L,k,k+L)+V(l,l,l,l)*rdm(l,l+L,l,l+L)+2*V(k,k,l,l)*rdm(k,k+L,l,l+L)+2*(2*V(k,l,k,l)-V(k,k,l,l))*rdm(k,l,k,l);
1474 const double sin4 = V(k,k,k,k)*rdm(l,l+L,l,l+L)+V(l,l,l,l)*rdm(k,k+L,k,k+L)+2*V(k,k,l,l)*rdm(k,k+L,l,l+L)+2*(2*V(k,l,k,l)-V(k,k,l,l))*rdm(k,l,k,l);
1477 const double cos2sin2 = (2*V(k,k,l,l)+V(k,l,k,l))*(rdm(k,k+L,k,k+L)+rdm(l,l+L,l,l+L))+((V(k,k,k,k)+V(l,l,l,l)-2*(V(k,l,k,l)+V(k,k,l,l))))*rdm(k,k+L,l,l+L)+(V(k,k,k,k)+V(l,l,l,l)-6*V(k,k,l,l)+2*V(k,l,k,l))*rdm(k,l,k,l);
1480 const double sin3cos = V(k,l,k,k)*rdm(l,l+L,l,l+L)-V(k,l,l,l)*rdm(k,k+L,k,k+L)-(V(k,l,k,k)-V(k,l,l,l))*(rdm(k,k+L,l,l+L)+rdm(k,l,k,l));
1483 const double cos3sin = V(k,l,l,l)*rdm(l,l+L,l,l+L)-V(k,l,k,k)*rdm(k,k+L,k,k+L)+(V(k,l,k,k)-V(k,l,l,l))*(rdm(k,k+L,l,l+L)+rdm(k,l,k,l));
1485 const double cos = std::cos(theta);
1486 const double sin = std::sin(theta);
1488 energy += cos*cos*cos*cos*cos4;
1490 energy += sin*sin*sin*sin*sin4;
1492 energy += cos*cos*cos2;
1494 energy += sin*sin*sin2;
1496 energy += 2*sin*cos*sincos;
1498 energy += 2*cos*cos*sin*sin*cos2sin2;
1500 energy += 4*cos*sin*sin*sin*sin3cos;
1502 energy += 4*cos*cos*cos*sin*cos3sin;
1577 std::pair<double,bool>
TPM::find_min_angle(
int k,
int l,
double start_angle, std::function<
double(
int,
int)> &T, std::function<
double(
int,
int,
int,
int)> &V)
const
1581 double theta = start_angle;
1583 const TPM &rdm = *
this;
1585 double cos2 = 2.0/(
N-1.0)*(T(k,k)*rdm(k,k+
L,k,k+
L)+T(l,l)*rdm(l,l+
L,l,l+
L));
1587 double sin2 = 2.0/(
N-1.0)*(T(l,l)*rdm(k,k+
L,k,k+
L)+T(k,k)*rdm(l,l+
L,l,l+
L));
1590 double sincos = 2.0/(
N-1.0)*T(k,l)*(rdm(l,l+
L,l,l+
L)-rdm(k,k+
L,k,k+
L));
1592 for(
int a=0;a<
L;a++)
1597 cos2 += 2*V(k,k,a,a)*rdm(k,k+L,a,a+L)+2*V(l,l,a,a)*rdm(l,l+L,a,a+L)+2*(2*V(k,a,k,a)-V(k,a,a,k)+2.0/(
N-1.0)*T(k,k))*rdm(k,a,k,a)+2*(2*V(l,a,l,a)-V(l,a,a,l)+2.0/(
N-1.0)*T(l,l))*rdm(l,a,l,a);
1599 sin2 += 2*V(l,l,a,a)*rdm(k,k+L,a,a+L)+2*V(k,k,a,a)*rdm(l,l+L,a,a+L)+2*(2*V(k,a,k,a)-V(k,a,a,k)+2.0/(
N-1.0)*T(k,k))*rdm(l,a,l,a)+2*(2*V(l,a,l,a)-V(l,a,a,l)+2.0/(
N-1.0)*T(l,l))*rdm(k,a,k,a);
1601 sincos += 2*V(k,l,a,a)*(rdm(l,l+L,a,a+L)-rdm(k,k+L,a,a+L))+2*(2*V(k,a,l,a)-V(k,a,a,l)+2.0/(
N-1.0)*T(k,l))*(rdm(l,a,l,a)-rdm(k,a,k,a));
1604 const double cos4 = V(k,k,k,k)*rdm(k,k+L,k,k+L)+V(l,l,l,l)*rdm(l,l+L,l,l+L)+2*V(k,k,l,l)*rdm(k,k+L,l,l+L)+2*(2*V(k,l,k,l)-V(k,k,l,l))*rdm(k,l,k,l);
1606 const double sin4 = V(k,k,k,k)*rdm(l,l+L,l,l+L)+V(l,l,l,l)*rdm(k,k+L,k,k+L)+2*V(k,k,l,l)*rdm(k,k+L,l,l+L)+2*(2*V(k,l,k,l)-V(k,k,l,l))*rdm(k,l,k,l);
1609 const double cos2sin2 = (2*V(k,k,l,l)+V(k,l,k,l))*(rdm(k,k+L,k,k+L)+rdm(l,l+L,l,l+L))+((V(k,k,k,k)+V(l,l,l,l)-2*(V(k,l,k,l)+V(k,k,l,l))))*rdm(k,k+L,l,l+L)+(V(k,k,k,k)+V(l,l,l,l)-6*V(k,k,l,l)+2*V(k,l,k,l))*rdm(k,l,k,l);
1612 const double sin3cos = V(k,l,k,k)*rdm(l,l+L,l,l+L)-V(k,l,l,l)*rdm(k,k+L,k,k+L)-(V(k,l,k,k)-V(k,l,l,l))*(rdm(k,k+L,l,l+L)+rdm(k,l,k,l));
1615 const double cos3sin = V(k,l,l,l)*rdm(l,l+L,l,l+L)-V(k,l,k,k)*rdm(k,k+L,k,k+L)+(V(k,l,k,k)-V(k,l,l,l))*(rdm(k,k+L,l,l+L)+rdm(k,l,k,l));
1620 auto gradient = [&] (
double theta) ->
double {
1621 double cos = std::cos(theta);
1622 double sin = std::sin(theta);
1624 double res = 16*(cos3sin-sin3cos)*cos*cos*cos*cos - 4*(cos4+sin4-2*cos2sin2)*sin*cos*cos*cos + 4*(sincos-3*cos3sin+5*sin3cos)*cos*cos + 2*(2*sin4-cos2+sin2-2*cos2sin2)*sin*cos-2*sincos-4*sin3cos;
1630 auto hessian = [&] (
double theta) ->
double {
1631 double cos = std::cos(theta);
1632 double sin = std::sin(theta);
1634 double res = -16*(cos4+sin4-2*cos2sin2)*cos*cos*cos*cos+64*(sin3cos-cos3sin)*sin*cos*cos*cos+4*(3*cos4+5*sin4-cos2+sin2-8*cos2sin2)*cos*cos-8*(sincos-3*cos3sin+5*sin3cos)*sin*cos+2*(cos2-2*sin4-sin2+2*cos2sin2);
1646 const int max_iters = 20;
1647 const double convergence = 1e-12;
1649 double change = gradient(theta)*theta+hessian(theta)*theta*theta/2.0;
1656 for(iter=0;iter<max_iters;iter++)
1658 double dx = gradient(theta)/hessian(theta);
1662 if(fabs(dx) < convergence)
1667 std::cout <<
"Reached max iters in find_min_angle: " << k <<
" " << l << std::endl;
1669 if(hessian(theta)<0)
1670 std::cout <<
"Found max!" << std::endl;
1672 return std::make_pair(theta, hessian(theta)>0);
1684 void TPM::rotate(
int k,
int l,
double angle, std::function<
double(
int,
int)> &T, std::function<
double(
int,
int,
int,
int)> &V)
1691 const double cos = std::cos(angle);
1692 const double sin = std::sin(angle);
1693 const double cos2 = cos*cos;
1694 const double sin2 = sin*sin;
1695 const double cos4 = cos2*cos2;
1696 const double sin4 = sin2*sin2;
1697 const double cossin = cos*sin;
1698 const double cos2sin2 = cos2*sin2;
1699 const double cos3sin = cos2*cossin;
1700 const double cossin3 = cossin*sin2;
1702 for(
int p=0;p<
L;p++)
1708 rdmB(k,p) = rdmB(p,k) = cos2*V(k,k,p,p)-2*cossin*V(k,l,p,p)+sin2*V(l,l,p,p);
1710 rdmB(l,p) = rdmB(p,l) = cos2*V(l,l,p,p)+2*cossin*V(k,l,p,p)+sin2*V(k,k,p,p);
1712 int idx = (*s2t)(k,p) - L;
1715 rdmV[idx] = 1.0/(
N-1.0) * (T(p,p) + cos2*T(k,k)-2*cossin*T(k,l)+sin2*T(l,l));
1716 rdmV[idx] += cos2*(V(k,p,k,p)-0.5*V(k,p,p,k))-2*cossin*(V(k,p,l,p)-0.5*V(k,p,p,l))+sin2*(V(l,p,l,p)-0.5*V(l,p,p,l));
1718 idx = (*s2t)(l,p) - L;
1721 rdmV[idx] = 1.0/(
N-1.0) * (T(p,p) + cos2*T(l,l)+2*cossin*T(k,l)+sin2*T(k,k));
1722 rdmV[idx] += cos2*(V(l,p,l,p)-0.5*V(l,p,p,l))+2*cossin*(V(l,p,k,p)-0.5*V(k,p,p,l))+sin2*(V(k,p,k,p)-0.5*V(k,p,p,k));
1726 rdmB(k,k) = 2.0/(
N-1.0) * (cos2*T(k,k)-2*cossin*T(k,l)+sin2*T(l,l));
1727 rdmB(k,k) += cos4*V(k,k,k,k)+sin4*V(l,l,l,l)+cos2sin2*(4*V(k,k,l,l)+2*V(k,l,k,l))-4*cossin3*V(k,l,l,l)-4*cos3sin*V(k,l,k,k);
1730 rdmB(l,l) = 2.0/(
N-1.0) * (cos2*T(l,l)+2*cossin*T(k,l)+sin2*T(k,k));
1731 rdmB(l,l) += sin4*V(k,k,k,k)+cos4*V(l,l,l,l)+cos2sin2*(4*V(k,k,l,l)+2*V(k,l,k,l))+4*cossin3*V(k,l,k,k)+4*cos3sin*V(k,l,l,l);
1734 rdmB(k,l) = rdmB(l,k) = cos2sin2*(V(k,k,k,k)+V(l,l,l,l)-2*(V(k,l,k,l)+V(k,k,l,l)))+(cos4+sin4)*V(k,k,l,l)+2*(cos3sin-cossin3)*(V(k,l,k,k)-V(k,l,l,l));
1737 int idx = (*s2t)(k,l) - L;
1738 rdmV[idx] = 1.0/(
N-1.0)*(T(k,k)+T(l,l)) + cos2sin2*(0.5*(V(k,k,k,k)+V(l,l,l,l))-3*V(k,k,l,l)+V(k,l,k,l))+(cos4+sin4)*(V(k,l,k,l)-0.5*V(k,k,l,l))+(cos3sin-cossin3)*(V(k,l,k,k)-V(k,l,l,l));
1743 hid_t file_id, group_id;
1746 file_id = H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1748 group_id = H5Gcreate(file_id,
"/RDM", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1752 status = H5Gclose(group_id);
1755 status = H5Fclose(file_id);
1761 hid_t dataset_id, attribute_id, dataspace_id;
1769 for(
int a=0;a<M;a++)
1770 for(
int b=0;b<M;b++)
1771 for(
int c=0;c<M;c++)
1772 for(
int d=0;d<M;d++)
1774 int idx1 = (*s2t)(a,b);
1775 int idx2 = (*s2t)(c,d);
1777 if(idx1>=0 && idx2>=0)
1778 fullTPM(idx1, idx2) = (*this)(a,b,c,d);
1782 hsize_t dimblock =
n*
n;
1784 dataspace_id = H5Screate_simple(1, &dimblock, NULL);
1786 dataset_id = H5Dcreate(group_id,
"TPM", H5T_IEEE_F64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1788 status = H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, fullTPM.
gMatrix());
1791 status = H5Sclose(dataspace_id);
1794 dataspace_id = H5Screate(H5S_SCALAR);
1796 attribute_id = H5Acreate (dataset_id,
"M", H5T_STD_I64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
1797 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &M );
1800 status = H5Aclose(attribute_id);
1803 attribute_id = H5Acreate (dataset_id,
"N", H5T_STD_I64LE, dataspace_id, H5P_DEFAULT, H5P_DEFAULT);
1804 status = H5Awrite (attribute_id, H5T_NATIVE_INT, &
N );
1807 status = H5Aclose(attribute_id);
1810 status = H5Sclose(dataspace_id);
1813 status = H5Dclose(dataset_id);
1829 hid_t file_id, group_id, attribute_id;
1832 file_id = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
1835 group_id = H5Gopen(file_id,
"/RDM", H5P_DEFAULT);
1838 attribute_id = H5Aopen(group_id,
"L", H5P_DEFAULT);
1841 status = H5Aread(attribute_id, H5T_NATIVE_INT, &L);
1844 status = H5Aclose(attribute_id);
1847 attribute_id = H5Aopen(group_id,
"N", H5P_DEFAULT);
1850 status = H5Aread(attribute_id, H5T_NATIVE_INT, &N);
1853 status = H5Aclose(attribute_id);
1856 status = H5Gclose(group_id);
1859 status = H5Fclose(file_id);
void ReadFromFile(std::string filename)
double calc_rotate_slow_doci(const TPM &, int, int, double) const
static TPM CreateFromFile(std::string filename)
void ReadFromFileFull(std::string filename)
const Matrix & getBlock(int a, int b) const
void bar2(double, const TPM &)
double ge_ortho(int) const
double line_search(double t, SUP &, const TPM &) const
int n
dimension of the full TPM
std::pair< double, bool > find_min_angle_doci(const TPM &, int, int, double=0) const
void ham(std::function< double(int, int)> &T, std::function< double(int, int, int, int)> &V)
void HF_molecule(std::string filename)
void WriteFullToFile(std::string filename) const
double ddot(const Container &) const
double calc_rotate_doci(const TPM &, int, int, double) const
double calc_rotate_slow(int k, int l, double theta, std::function< double(int, int)> &T, std::function< double(int, int, int, int)> &V) const
void L_map(const SUP &, const SUP &)
void setMatrixDim(int, int, int)
int InverseS(TPM &, const Lineq &)
std::ostream & operator<<(std::ostream &output, const doci2DM::BlockStructure< MyBlockType > &blocks_p)
double operator()(int a, int b, int c, int d) const
void rotate(int, int, double, std::function< double(int, int)> &, std::function< double(int, int, int, int)> &)
int gdimVector(int) const
double lsfunc(double) const
void constr_grad(double t, const SUP &, const TPM &, const Lineq &)
void H(double t, const TPM &, const SUP &, const Lineq &)
double calc_rotate(int k, int l, double theta, std::function< double(int, int)> &T, std::function< double(int, int, int, int)> &V) const
std::pair< double, bool > find_min_angle(int k, int l, double start_angle, std::function< double(int, int)> &T, std::function< double(int, int, int, int)> &V) const
void rotate_doci(int, int, double)
#define HDF5_STATUS_CHECK(status)
Container & daxpy(double alpha, const Container &)
void Proj_E(const Lineq &, int option=0)
double getDiag(int, int) const
int L
the size of the sp DOCI space (there are 2*L sp states)
int gdimMatrix(int) const
void bar3(double, const TPM &)
const TPM & gE_ortho(int) const
void WriteToFile(hid_t &group_id) const
static std::unique_ptr< helpers::tmatrix< unsigned int > > t2s
table translating two particles indices to single particle indices
static std::unique_ptr< helpers::tmatrix< unsigned int > > s2t
table translating single particles indices to two particle indices
void L_map(const Container &, const Container &)
std::vector< TPM > DOCI_constrains() const
void setVectorDim(int, int, int)
void collaps(const SUP &, const Lineq &)
int solve(double t, const SUP &, TPM &, const Lineq &)
void L_map(const BlockMatrix &, const BlockMatrix &)