/** Perform curve fitting via Levenberg-Marquardt with no bounds/weights. */ int CurveFit::LevenbergMarquardt(FitFunctionType fxnIn, Darray const& Xvals_, Darray const& Yvals_, Darray& ParamVec, double tolerance, int maxIterations) { return LevenbergMarquardt(fxnIn, Xvals_, Yvals_, ParamVec, std::vector<bool>(), Darray(), Darray(), Darray(), tolerance, maxIterations); }
// Action_Matrix::Setup() Action::RetType Action_Matrix::Setup(ActionSetup& setup) { size_t mask1tot = 0; // Will be # of columns size_t mask2tot = 0; // Will be # of rows if not symmetric matrix // Set up masks. if (Mat_->Meta().ScalarType() == MetaData::IREDMAT) { // IRED - matrix # cols = # of IRED vectors mask1tot = IredVectors_.size(); } else if (Mat_->Meta().ScalarType() == MetaData::DIHCOVAR) { // Dihedral covariance - matrix # cols = # data sets mask1tot = DihedralSets_.size(); } else { if (setup.Top().SetupIntegerMask(mask1_)) return Action::ERR; mask1_.MaskInfo(); if (mask1_.None()) { mprintf("Warning: No atoms selected for mask1.\n"); return Action::SKIP; } if (useMask2_) { if (setup.Top().SetupIntegerMask(mask2_)) return Action::ERR; mask2_.MaskInfo(); if (mask2_.None()) { mprintf("Warning: No atoms selected for mask2.\n"); return Action::SKIP; } } mask1tot = (size_t)mask1_.Nselected(); mask2tot = (size_t)mask2_.Nselected(); } if (mask1tot < mask2tot) { mprinterr("Error: # of atoms in mask1 < # of atoms in mask2\n"); return Action::ERR; } // Store mass info for MWCOVAR matrix or when output BYRESIDUE or BYMASK. if ( Mat_->Meta().ScalarType() == MetaData::MWCOVAR || (outtype_ != BYATOM && useMass_) ) { mass1_ = FillMassArray(setup.Top(), mask1_); mass2_ = FillMassArray(setup.Top(), mask2_); if (outtype_ != BYATOM && !useMass_) mprintf("Warning: Using mass-weighted covar matrix, byres/bymask output will be" "weighted by mass.\n"); } else if (outtype_ != BYATOM && !useMass_) { mass1_ = Darray(mask1_.Nselected(), 1.0); if (useMask2_) mass2_ = Darray(mask2_.Nselected(), 1.0); } // If output is BYRESIDUE, determine which mask elements correspond to // which residues, as well as how many residues are selected in mask1 (cols) // and mask2 (rows) to determine output matrix dimensions. if (outtype_ == BYRESIDUE) { residues1_ = MaskToMatResArray( setup.Top(), mask1_ ); residues2_ = MaskToMatResArray( setup.Top(), mask2_ ); } // Determine matrix/vector dimensions. size_t vectsize = 0; size_t ncols = 0; size_t nrows = 0; switch( Mat_->Meta().ScalarType() ) { case MetaData::CORREL : // Like DIST but vectors required. vectsize = (mask1tot + mask2tot) * 3; case MetaData::DIST : // No vectors required. ncols = mask1tot; nrows = mask2tot; break; case MetaData::DISTCOVAR: // No Full matrix possible. vectsize = mask1tot * (mask1tot - 1) / 2; ncols = vectsize; if (mask2tot > 0) return PrintMask2Error(); break; case MetaData::MWCOVAR : // Store mass info matrix DataSet for mass-weighting eigenvectors. Mat_->StoreMass( mass1_ ); case MetaData::COVAR : vectsize = (mask1tot + mask2tot) * 3; ncols = mask1tot * 3; nrows = mask2tot * 3; break; case MetaData::DIHCOVAR: // Dihedral covariance vectsize = (mask1tot + mask2tot) * 2; ncols = mask1tot * 2; nrows = mask2tot * 2; break; case MetaData::IDEA : case MetaData::IREDMAT : // No Full matrix possible. vectsize = mask1tot + mask2tot; ncols = mask1tot; if (mask2tot > 0) return PrintMask2Error(); break; default: return Action::ERR; // Sanity check } // Allocate vector memory. Mat_->AllocateVector( vectsize ); vect2_.resize( vectsize, 0.0 ); // Allocate matrix memory. If already allocated, do not allow sizes to change. if (Mat_->Size() == 0) { if (nrows > 0) // Full matrix - no DISTCOVAR, IDEA, or IRED possible Mat_->Allocate2D( ncols, nrows ); else // "Upper right half" matrix, including main diagonal. Mat_->AllocateHalf( ncols ); } else { bool dimensionsHaveChanged = false; if (nrows > 0) dimensionsHaveChanged = (nrows != Mat_->Nrows() || ncols != Mat_->Ncols()); else dimensionsHaveChanged = (ncols != Mat_->Ncols()); if (dimensionsHaveChanged) { mprinterr("Error: Attempting to reallocate matrix with different size.\n" "Error: Original # cols = %zu, new # cols = %zu.\n", Mat_->Ncols(), ncols); if (nrows > 0) mprinterr("Error: Original # rows = %zu, new # rows = %zu.\n", Mat_->Nrows(), nrows); mprinterr("Error: This can occur when different #s of atoms are selected in\n" "Error: different topology files.\n"); return Action::ERR; } } # ifdef _OPENMP if ( ( Mat_->Meta().ScalarType() == MetaData::COVAR || Mat_->Meta().ScalarType() == MetaData::MWCOVAR )) { # ifdef NEW_MATRIX_PARA // Store coordinate XYZ indices of mask 1. crd_indices_.clear(); for (AtomMask::const_iterator m1 = mask1_.begin(); m1 != mask1_.end(); ++m1) { int crdidx = *m1 * 3; crd_indices_.push_back( crdidx ); crd_indices_.push_back( crdidx+1 ); crd_indices_.push_back( crdidx+2 ); } # else if (Mat_->MatrixKind() == DataSet_2D::FULL) { // Store combined mask1 and mask2 for diagonal. crd_indices_.clear(); crd_indices_.reserve( mask1_.Nselected() + mask2_.Nselected() ); for (AtomMask::const_iterator at = mask1_.begin(); at != mask1_.end(); ++at) crd_indices_.push_back( *at * 3 ); for (AtomMask::const_iterator at = mask2_.begin(); at != mask2_.end(); ++at) crd_indices_.push_back( *at * 3 ); } if (debug_ > 1) { mprintf("DEBUG: Combined mask1+mask2 coordinate indices:\n"); for (unsigned int i = 0; i < crd_indices_.size(); i += 2) mprintf("%u:\t%i %i\n", i/2, crd_indices_[i], crd_indices_[i+1]); } # endif } # endif return Action::OK; }