예제 #1
0
파일: gcd.c 프로젝트: SRI-CSL/libpoly
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
예제 #3
0
파일: gcd.c 프로젝트: SRI-CSL/libpoly
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"); }
  }
}