static int coefficient_pp_cont_special(const lp_polynomial_context_t* ctx, coefficient_t* pp, coefficient_t* cont, const coefficient_t* C) { if (coefficient_is_linear(C)) { // Just get the constants and GCD coefficient_t gcd; coefficient_construct_copy(ctx, &gcd, coefficient_lc(C)); if (coefficient_lc_sgn(ctx, &gcd) < 0) { coefficient_neg(ctx, &gcd, &gcd); } // Get the GCD of all leading coefficient (including the constant) const coefficient_t* C_it = C; while (C_it->type == COEFFICIENT_POLYNOMIAL) { C_it = COEFF(C_it, 0); coefficient_gcd(ctx, &gcd, &gcd, coefficient_lc(C_it)); } if (coefficient_lc_sgn(ctx, C) < 0) { coefficient_neg(ctx, &gcd, &gcd); } // Now divide C/gcd to get the pp if (pp) { coefficient_assign(ctx, pp, C); coefficient_div_constant(ctx, pp, &gcd.value.num); } if (cont) { coefficient_swap(&gcd, cont); } coefficient_destruct(&gcd); return 1; } return 0; }
void SingleSlater<dcomplex>::CDIIS() { int N = this->lenCoeff_; ComplexMatrix B(N,N); dcomplex *coef = new dcomplex[N]; int *iPiv = new int[N]; int NRHS = 1, INFO = -1; int NBSq = this->nBasis_*this->nBasis_*this->nTCS_*this->nTCS_; for(auto j = 0; j < (N-1); j++) for(auto k = 0; k <= j ; k++) { ComplexMap EJA(this->ErrorAlphaMem_ + (j%(N-1))*NBSq,this->nTCS_*this->nBasis_,this->nTCS_*this->nBasis_); ComplexMap EKA(this->ErrorAlphaMem_ + (k%(N-1))*NBSq,this->nTCS_*this->nBasis_,this->nTCS_*this->nBasis_); B(j,k) = -EJA.frobInner(EKA); if(!this->isClosedShell && this->Ref_ != TCS) { ComplexMap EJB(this->ErrorBetaMem_ + (j%(N-1))*NBSq,this->nBasis_,this->nBasis_); ComplexMap EKB(this->ErrorBetaMem_ + (k%(N-1))*NBSq,this->nBasis_,this->nBasis_); B(j,k) += -EJB.frobInner(EKB); } B(k,j) = B(j,k); } for (auto l=0; l<N-1; l++) { B(N-1,l)=-1.0; B(l,N-1)=-1.0; } B(N-1,N-1)=0; for(auto k = 0; k < N; k++) coef[k] = 0.0; coef[N-1]=-1.0; /* zgesv_(&N,&NRHS,B.data(),&N,iPiv,coef,&N,&INFO); */ ComplexVecMap COEFF(coef,N); VectorXcd RHS(COEFF); COEFF = B.fullPivLu().solve(RHS); this->fockA_->setZero(); if(!this->isClosedShell && this->Ref_ != TCS) this->fockB_->setZero(); for(auto j = 0; j < N-1; j++) { ComplexMap FA(this->FADIIS_ + (j%(N-1))*NBSq,this->nTCS_*this->nBasis_,this->nTCS_*this->nBasis_); *this->fockA_ += coef[j]*FA; if(!this->isClosedShell && this->Ref_ != TCS) { ComplexMap FB(this->FBDIIS_ + (j%(N-1))*NBSq,this->nBasis_,this->nBasis_); *this->fockB_ += coef[j]*FB; } } delete [] coef; delete [] iPiv; } // CDIIS
void coefficient_pp_cont(const lp_polynomial_context_t* ctx, coefficient_t* pp, coefficient_t* cont, const coefficient_t* C) { TRACE("coefficient", "coefficient_pp_cont()\n"); STAT(coefficient, pp_cont) ++; if (trace_is_enabled("coefficient")) { tracef("C = "); coefficient_print(ctx, C, trace_out); tracef("\n"); } assert(ctx->K == lp_Z); int special = coefficient_pp_cont_special(ctx, pp, cont, C); if (special) { return; } switch (C->type) { case COEFFICIENT_NUMERIC: if (cont) { if (cont->type == COEFFICIENT_POLYNOMIAL) { coefficient_destruct(cont); coefficient_construct_copy(ctx, cont, C); } else { integer_assign(ctx->K, &cont->value.num, &C->value.num); } } if (pp) { if (pp->type == COEFFICIENT_POLYNOMIAL) { coefficient_destruct(pp); coefficient_construct_from_int(ctx, pp, 1); } else { integer_assign_int(ctx->K, &pp->value.num, 1); } } break; case COEFFICIENT_POLYNOMIAL: { int i; coefficient_t gcd; // Compute the gcd of coefficients starting with LC coefficient_construct_copy(ctx, &gcd, coefficient_lc(C)); // Make if positive in case it's the only one if (coefficient_lc_sgn(ctx, &gcd) < 0) { coefficient_neg(ctx, &gcd, &gcd); } // Compute the rest of the gcd for (i = SIZE(C)-2; i >= 0 ; -- i) { if (!coefficient_is_zero(ctx, COEFF(C, i))) { coefficient_gcd(ctx, &gcd, &gcd, COEFF(C, i)); if (coefficient_is_one(ctx, &gcd)) { break; } } } // GCD is positive, so if the leading coefficient of C is negative, flip it if (coefficient_lc_sgn(ctx, C) < 0) { coefficient_neg(ctx, &gcd, &gcd); } if (pp) { // Now compute the pp coefficient_div(ctx, pp, C, &gcd); assert(coefficient_is_normalized(ctx, pp)); } if (cont) { coefficient_swap(&gcd, cont); assert(coefficient_is_normalized(ctx, cont)); } coefficient_destruct(&gcd); break; } default: assert(0); break; } if (trace_is_enabled("coefficient")) { tracef("coefficient_pp_cont() => "); if (pp) { tracef("pp = "); coefficient_print(ctx, pp, trace_out); tracef("\n"); } if (cont) { tracef("cont = "); coefficient_print(ctx, cont, trace_out); tracef("\n"); } } }