Example #1
0
void LinearSolver::eigen_system( DENS_MAT & eigenvalues, DENS_MAT & eigenvectors, const DENS_MAT * M) /* const */
{
  initialize_matrix(); // no inverse needed
  const DENS_MAT * Kp = NULL;
  const DENS_MAT * Mp =M;
  DENS_MAT MM;
  DENS_MAT KM;
  if (constraintHandlerType_ == CONDENSE_CONSTRAINTS) { 
    Kp = &matrixFreeFree_;
    if (M) {
      DENS_MAT MfreeFixed; // not used
      M->row_partition(freeSet_,MM,MfreeFixed); 
      Mp = &MM;
    }
  }
  else { 
    if (matrixDense_.nRows() == 0) matrixDense_ =matrixSparse_->dense_copy();
    Kp = &matrixDense_;
  }
  if (!M) {
    MM.identity(Kp->nRows());
    Mp = &MM;
  }

  DENS_MAT eVecs, eVals;
  eVecs = eigensystem(*Kp,*Mp,eVals);
  eigenvalues.reset(nVariables_,1);
  eigenvectors.reset(nVariables_,nVariables_);
  set<int>::const_iterator itr;

  for (int i = 0; i < Kp->nRows(); i++) { // ordering is by energy not node
    eigenvalues(i,0) = eVals(i,0);
    int j = 0;
    for (itr = freeSet_.begin(); itr != freeSet_.end(); itr++,j++) {
      int jj = *itr;
      eigenvectors(jj,i) = eVecs(j,i); // transpose
    }
  }
}
Example #2
0
void p4_setPramsPartTest(p4_tree *aTree, int pNum)
{

  int mNum;
  int nNum, cNum, rNum;
  int dim;
  int i, j;
  int ret;
  double alpha, beta;
  p4_modelPart   *mp;
  //part           *dp;
  p4_gdasrv      *g;
  p4_rMatrix     *r;
  p4_node        *n;
  p4_comp        *c;
  p4_bigQAndEig  *aQE;

  printf("a p4_setPramsPartTest here.  pNum=%i\n", pNum);

#if 1
  mp = aTree->model->parts[pNum];
  if(mp->nCat > 1) {
    // Set gdasrv->rates using Yang's DiscreteGamma function.
    for(mNum = 0; mNum < mp->nGdasrvs; mNum++) {
      g = mp->gdasrvs[mNum];
      // All rates were set when the gdasrv was given its
      // val, in pf_p4_setGdasrvVal() in pfmodule.c.  We
      // need only re-do the ones with a free shape.
      if(g->free) {
	printf("part %i, gdasrv %i, is free, with val %f\n", pNum, mNum, g->val[0]);
	// int DiscreteGamma (double freqK[], double rK[], double alfa, double beta, int K, int median)
	// Here alfa = beta.  The freqK array is used as a
	// working space for internal calcs by
	// DiscreteGamma, but boringly ends up as all 1.0/K
	DiscreteGamma(g->freqs, g->rates, g->val[0], g->val[0], mp->nCat, 0);
	if(1) {
	  printf("gdasrv[%i] = %f, free=%i\n", mNum, g->val[0], g->free);
	  for(i = 0; i < mp->nCat; i++) {
	    printf("  %i  %f   %f\n", i, g->freqs[i], g->rates[i]);
	  }
	}
      }
    }
  }
#endif

#if 1
  // Set rMatrix for 2p (ie nst=2) models (k2p and hky)
  mp = aTree->model->parts[pNum];
  dim = mp->dim;
  for(mNum = 0; mNum < mp->nRMatrices; mNum++) {
    r = mp->rMatrices[mNum];
    if(r->free && (r->spec == RMATRIX_2P)) {
      //printf("part %i, rMatrix %i, is free.  spec = %i\n", pNum, mNum, r->spec);
      alpha = 1.0 / 3.0;
      beta = alpha * r->kappa[0];
      r->bigR[0][0] = 0.0;
      r->bigR[0][1] = alpha;
      r->bigR[0][2] = beta;
      r->bigR[0][3] = alpha;
      r->bigR[1][0] = alpha;
      r->bigR[1][1] = 0.0;
      r->bigR[1][2] = alpha;
      r->bigR[1][3] = beta;
      r->bigR[2][0] = beta;
      r->bigR[2][1] = alpha;
      r->bigR[2][2] = 0.0;
      r->bigR[2][3] = alpha;
      r->bigR[3][0] = alpha;
      r->bigR[3][1] = beta;
      r->bigR[3][2] = alpha;
      r->bigR[3][3] = 0.0;
    }
  }
#endif
	
  // bigQ
	
  /*
    Each part has a bigQAndEigThing.  It is nComps * nRMatrices.
    Each slot has a bigQAndEig struct, but at the start of play they
    are all empty.  They are only filled and the qEig calculated if
    needed.
  */

  //printf("about to set bigQ.\n");

  // Nasty surprise.  If a charFreq is zero, eg if the charFreq is
  // (0.4, 0.4, 0.2, 0.0), then the bigP's are *wrong* --- way
  // wrong.  However, its ok if eg the charFreq is (0.4, 0.4,
  // 0.199999, 0.000001).  In previous versions I used to check and
  // adjust, but here it is just prevented, elsewhere.  In
  // optimizations, the PIVEC_MIN is enforced.


#if 0
  // Check comps anyway.  This interferes with mcmc when I do verifyModelPrams().
  {
    double sum=0.0;

    mp = aTree->model->parts[pNum];
    //printf("    part %i, nComps=%i, nRMatrices=%i, nCat=%i\n", pNum, mp->nComps, mp->nRMatrices, mp->nCat);
    for(i = 0; i < mp->nComps; i++) {
      for(j = 0; j < mp->dim; j++) {
	if(mp->comps[i]->val[j] < (0.5 * PIVEC_MIN)) {
	  printf("p4_setPramsPart()  part %i, comp %i, value %i is %g   Bad.\n", pNum, i, j, mp->comps[i]->val[j]);
	  exit(1);
	}
      }
      // check that the sum is 1.0
      sum = 0.0;
      for(j = 0; j < mp->dim; j++) {
	sum += mp->comps[i]->val[j];
      }
      // normalize if needed
      if(fabs(sum - 1.0) > 1e-15) {
	printf("   ** p4_setPramsPart().  normalizing comp. diff=%f (%g)\n", fabs(sum - 1.0), fabs(sum - 1.0));
	if(fabs(sum - 1.0) > 0.001) {
	  printf("p4_setPramsPart()  part %i, comp %i, sum of vals = %f.  Bad.\n", pNum, i, sum);
	}
	for(j = 0; j < mp->dim; j++) {
	  mp->comps[i]->val[j] /= sum;
	}
      }
      // check again
      sum = 0.0;
      for(j = 0; j < mp->dim; j++) {
	sum += mp->comps[i]->val[j];
      }
      // if its wrong this time, give up  (diff of 1e-16 was too small, raised to 1e-14)
      if(fabs(sum - 1.0) > 1e-14) {
	printf("p4_setPramsPart()  part %i, comp %i, values do not sum to 1.0.  sum=%g\n", pNum, i, sum);
	printf("  sum - 1.0 = %g\n", sum - 1.0);
	exit(1);
      }
    }
  }
#endif

#if 1
  // Check comps anyway.  Same as above, but no normalizing.  Its only
  // a check -- it doesn't actually do anything.
  {
    double sum=0.0;

    mp = aTree->model->parts[pNum];
    //printf("    part %i, nComps=%i, nRMatrices=%i, nCat=%i\n", pNum, mp->nComps, mp->nRMatrices, mp->nCat);
    for(i = 0; i < mp->nComps; i++) {
      for(j = 0; j < mp->dim; j++) {
	if(mp->comps[i]->val[j] < (0.5 * PIVEC_MIN)) {
	  printf("p4_setPramsPart()  part %i, comp %i, value %i is %g   Bad.\n", pNum, i, j, mp->comps[i]->val[j]);
	  exit(1);
	}
      }
      // check
      sum = 0.0;
      for(j = 0; j < mp->dim; j++) {
	sum += mp->comps[i]->val[j];
      }
      // if its wrong this time, give up  (diff of 1e-16 was too small, raised to 1e-14)
      if(fabs(sum - 1.0) > 1e-14) {
	printf("**p4_setPramsPart()  part %i, comp %i, values do not sum to 1.0.  sum=%g\n", pNum, i, sum);
	printf("**  sum - 1.0 = %g\n", sum - 1.0);
	exit(1);
      }
    }
  }
#endif

#if 1
  // turn on all needsReset
  mp = aTree->model->parts[pNum];
  //printf("    part %i, nComps=%i, nRMatrices=%i, nCat=%i\n", pNum, mp->nComps, mp->nRMatrices, mp->nCat);
  for(i = 0; i < mp->nComps; i++) {
    for(j = 0; j < mp->nRMatrices; j++) {
      mp->bQETneedsReset[(i * mp->nRMatrices) + j] = 1;
    }
  }
	

  mp = aTree->model->parts[pNum];
  dim = mp->dim;
  for(nNum = 0; nNum < aTree->nNodes; nNum++) {
    n = aTree->nodes[nNum];
    if(n != aTree->root) {
      cNum = n->compNums[pNum];
      rNum = n->rMatrixNums[pNum];
      //printf("cNum = %i, rNum = %i\n", cNum, rNum);
      c = mp->comps[cNum];
      r = mp->rMatrices[rNum];
      aQE = aTree->model->parts[pNum]->bigQAndEigThing[cNum][rNum];
      if(mp->bQETneedsReset[(cNum * mp->nRMatrices) + rNum]) {
	//printf("Doing comp %i, rMatrix %i\n", cNum, rNum);
	if(!aQE->bigQ) {
	  aQE->bigQ = psdmatrix(dim);
	  setBigQFromRMatrixDotCharFreq(aQE->bigQ, r->bigR, c->val, dim);
	  normalizeBigQ(aQE->bigQ, c->val, dim);
	  aQE->qEig = allocEig(dim, aQE->bigQ);
	}
	else {
	  //dump_psdmatrix(r->bigR, dim);
	  //setBigQFromRMatrixDotCharFreq(m->bigQ, theRMatrix, theCharFreq, m->dim);
	  setBigQFromRMatrixDotCharFreq(aQE->bigQ, r->bigR, c->val, dim);
	  //dump_psdmatrix(aQE->bigQ, dim);
	  //normalizeBigQ(m->bigQ, theCharFreq, m->dim);
	  normalizeBigQ(aQE->bigQ, c->val, dim);
	  //dump_psdmatrix(aQE->bigQ, dim);
	}
	ret = eigensystem(aQE->qEig);
	if(ret) {
	  printf("There is a problem with the eigensystem.\n");
	  exit(1);
	}
	mp->bQETneedsReset[(cNum * mp->nRMatrices) + rNum] = 0;  // No need to do it again for this 
	// combination of cNum and rNum on another node.
      }
    }
  }
#endif 

#if 0
  for(cNum = 0; cNum < aTree->model->parts[pNum]->nComps; cNum++) {
    for(rNum = 0; rNum < aTree->model->parts[pNum]->nRMatrices; rNum++) {
      aQE = aTree->model->parts[pNum]->bigQAndEigThing[cNum][rNum];
      printf("cNum=%i, rNum=%i, mp->needsReset=%i, ", cNum, rNum, 
	     mp->bQETneedsReset[(cNum * mp->nRMatrices) + rNum]);
      printf("aQE->bigQ=%li\n", (long int)(aQE->bigQ));
    }
  }
#endif 
	

#if 0
  printf("bigQ\n");
  dump_psdmatrix(aTree->model->parts[pNum]->bigQAndEigThing[0][0]->bigQ, aTree->model->parts[pNum]->dim);
#endif

  
#if 1
  //printf("about to set bigP\n");
  // for each node except the root, "calculateBigPDecks()"
  for(nNum = 0; nNum < aTree->nNodes; nNum++) {
    if(nNum != NO_ORDER) {
      n = aTree->nodes[nNum];
      if(n != aTree->root) {
	p4_calculateBigPDecksPart(n, pNum);
      }
    }
  }
#endif

#if 0
  printf("bigP for node 1\n");
  dump_psdmatrix(aTree->nodes[1]->bigPDecks[0][0], aTree->model->parts[pNum]->dim);	
  //dump_psdmatrix(aTree->nodes[1]->bigPDecks[0][1], aTree->model->parts[pNum]->dim);
  //printf("bigP for node 2\n");
  //dump_psdmatrix(aTree->nodes[2]->bigPDecks[0][0], aTree->model->parts[pNum]->dim);	
#endif

}
Example #3
0
  void ContactAngle2::doFrame(int frame) {
    StuntDouble* sd;
    int i;

    // set up the bins for density analysis

    Mat3x3d hmat = info_->getSnapshotManager()->getCurrentSnapshot()->getHmat();
    RealType len = std::min(hmat(0, 0), hmat(1, 1));
    RealType zLen = hmat(2,2);

    RealType dr = len / (RealType) nRBins_;
    RealType dz = zLen / (RealType) nZBins_;

    std::vector<std::vector<RealType> > histo;
    histo.resize(nRBins_);
    for (unsigned int i = 0; i < histo.size(); ++i){
      histo[i].resize(nZBins_);
      std::fill(histo[i].begin(), histo[i].end(), 0.0);
    }      
        
    if (evaluator1_.isDynamic()) {
      seleMan1_.setSelectionSet(evaluator1_.evaluate());
    }
    
    Vector3d com(centroidX_, centroidY_, solidZ_);

    // now that we have the centroid, we can make cylindrical density maps
    Vector3d pos;
    RealType r;
    RealType z;
    
    for (sd = seleMan1_.beginSelected(i); sd != NULL;
         sd = seleMan1_.nextSelected(i)) {      
      pos = sd->getPos() - com;

      // r goes from zero upwards
      r = sqrt(pow(pos.x(), 2) + pow(pos.y(), 2));
      // z is possibly symmetric around 0
      z = pos.z();
          
      int whichRBin = int(r / dr);
      int whichZBin = int( (zLen/2.0 + z) / dz);
      
      if ((whichRBin < int(nRBins_)) && (whichZBin >= 0)
          && (whichZBin < int(nZBins_))) {
        histo[whichRBin][whichZBin] += sd->getMass();
      }
      
    }
    
    for(unsigned int i = 0 ; i < histo.size(); ++i){

      RealType rL = i * dr;
      RealType rU = rL + dr;
      RealType volSlice = NumericConstant::PI * dz * (( rU*rU ) - ( rL*rL ));

      for (unsigned int j = 0; j < histo[i].size(); ++j) {
        histo[i][j] *= PhysicalConstants::densityConvert / volSlice;
      }
    }

    std::vector<Vector<RealType, 2> > points;
    points.clear();
    
    for (unsigned int j = 0; j < nZBins_;  ++j) {

      // The z coordinates were measured relative to the selection
      // center of mass.  However, we're interested in the elevation
      // above the solid surface.  Also, the binning was done around
      // zero with enough bins to cover the zLength of the box:
      
      RealType thez =  com.z() - solidZ_  - zLen/2.0 + dz * (j + 0.5);
      bool aboveThresh = false;
      bool foundThresh = false;
      int rloc = 0;
      
      for (std::size_t i = 0; i < nRBins_;  ++i) {

        if (histo[i][j] >= threshDens_) aboveThresh = true;

        if (aboveThresh && (histo[i][j] <= threshDens_)) {
          rloc = i;
          foundThresh = true;
          aboveThresh = false;
        }

      }
      if (foundThresh) {
        Vector<RealType,2> point;
        point[0] = dr*(rloc+0.5);
        point[1] = thez;

        if (thez > bufferLength_) {
          points.push_back( point );
        }
      }      
    }

    int numPoints = points.size();

    // Compute the average of the data points.
    Vector<RealType, 2> average = points[0];
    int i0;
    for (i0 = 1; i0 < numPoints; ++i0) {
      average += points[i0];
    }
    RealType invNumPoints = ((RealType)1)/(RealType)numPoints;
    average *= invNumPoints;
    
    DynamicRectMatrix<RealType> mat(4, 4);
    int row, col;
    for (row = 0; row < 4; ++row) {
      for (col = 0; col < 4; ++col){
        mat(row,col) = 0.0;        
      }
    }
    for (int i = 0; i < numPoints; ++i) {
      RealType x = points[i][0];
      RealType y = points[i][1];
      RealType x2 = x*x;
      RealType y2 = y*y;
      RealType xy = x*y;
      RealType r2 = x2+y2;
      RealType xr2 = x*r2;
      RealType yr2 = y*r2;
      RealType r4 = r2*r2;

      mat(0,1) += x;
      mat(0,2) += y;
      mat(0,3) += r2;
      mat(1,1) += x2;
      mat(1,2) += xy;
      mat(1,3) += xr2;
      mat(2,2) += y2;
      mat(2,3) += yr2;
      mat(3,3) += r4;
    }
    mat(0,0) = (RealType)numPoints;

    for (row = 0; row < 4; ++row) {
      for (col = 0; col < row; ++col) {
        mat(row,col) = mat(col,row);
      }
    }

    for (row = 0; row < 4; ++row) {
      for (col = 0; col < 4; ++col) {
        mat(row,col) *= invNumPoints;
      }
    }

    JAMA::Eigenvalue<RealType> eigensystem(mat);
    DynamicRectMatrix<RealType> evects(4, 4);
    DynamicVector<RealType> evals(4);

    eigensystem.getRealEigenvalues(evals);
    eigensystem.getV(evects);

    DynamicVector<RealType> evector = evects.getColumn(0);
    RealType inv = ((RealType)1)/evector[3];  // beware zero divide
    RealType coeff[3];
    for (row = 0; row < 3; ++row) {
      coeff[row] = inv*evector[row];
    }

    Vector<RealType, 2> center;
    
    center[0] = -((RealType)0.5)*coeff[1];
    center[1] = -((RealType)0.5)*coeff[2];
    RealType radius = sqrt(fabs(center[0]*center[0] + center[1]*center[1]
                                - coeff[0]));

    int i1;
    for (i1 = 0; i1 < 100; ++i1) {
      // Update the iterates.
      Vector<RealType, 2> current = center;
      
      // Compute average L, dL/da, dL/db.
      RealType lenAverage = (RealType)0;
      Vector<RealType, 2> derLenAverage = Vector<RealType, 2>(0.0);
      for (i0 = 0; i0 < numPoints; ++i0) {
        Vector<RealType, 2> diff = points[i0] - center;
        RealType length = diff.length();
        if (length > 1e-6) {
          lenAverage += length;
          RealType invLength = ((RealType)1)/length;
          derLenAverage -= invLength*diff;
        }
      }
      lenAverage *= invNumPoints;
      derLenAverage *= invNumPoints;

      center = average + lenAverage*derLenAverage;
      radius = lenAverage;

      Vector<RealType, 2> diff = center - current;
      if (fabs(diff[0]) <= 1e-6 &&  fabs(diff[1]) <= 1e-6) {
        break;
      }
    }

    RealType zCen = center[1];
    RealType rDrop = radius;
    RealType ca;

    if (fabs(zCen) > rDrop) {
      ca = 180.0;
    } else {
      ca = 90.0 + asin(zCen/rDrop)*(180.0/M_PI);
    }

    values_.push_back( ca );    
  }