vector<Point> Find_refer_point(vector<Point> contour_point) { int size = contour_point.size(); Point temp; int i=0,j=0,k=0; float x_sum=0,y_sum=0; float x_mean,y_mean; float xx=0,xy=0,yx=0,yy=0; float xd,yd; float A[2][2]; float maj1,maj2,min1,min2; for(i=0;i<size;i++) { temp = contour_point[i]; x_sum = temp.x + x_sum; y_sum = temp.y + x_sum; } x_mean = x_sum/(float)size; y_mean = y_sum/(float)size; for(i=0;i<size;i++) { temp = contour_point[i]; xd = (float)temp.y - x_mean; yd = (float)temp.x - y_mean; xx = xx + (xd*xd)/(float)size; xy = xy + (xd*yd)/(float)size; yx = yx + (yd*xd)/(float)size; yy = yy + (yd*yd)/(float)size; } A[0][0] = xx; A[0][1] = xy; A[1][0] = yx; A[1][1] = yy; Mat CM(2,2,CV_32FC1,A); Mat eival(2,1,CV_32FC1); Mat eivec(2,2,CV_32FC1); eigen(CM,eival,eivec); maj1 = eivec.at<float>(0,0); maj2 = eivec.at<float>(0,1); min1 = eivec.at<float>(1,0); min2 = eivec.at<float>(1,1); float Head[2]={0,0}, Lfoot[2]={0,0}, Rfoot[2]={0,0}; float dummy_x, dummy_y; float Rmin[2], Rmaj[2], Gmin[2], Gmaj[2]; Rmin[0] = (-1)*maj1; Rmin[1] = (-1)*maj2; Rmaj[0] = maj1; Rmaj[1] = maj2; Gmin[0] = (-1)*min1; Gmin[1] = (-1)*min2; Gmaj[0] = min1; Gmaj[1] = min2; Mat Ra(1,2,CV_32FC1,Rmin); Mat Rb(1,2,CV_32FC1,Rmaj); Mat Ga(1,2,CV_32FC1,Gmin); Mat Gb(1,2,CV_32FC1,Gmaj); Mat dumvec(1,2,CV_32FC1); float Hmax=0,Lmax=0,Rmax=0,d_dum=0; float dum1,dum2,dum3; for (k = 0; k < size; k++) { temp = contour_point[k]; i = temp.y; j = temp.x; dummy_x = (float)temp.y - x_mean; dummy_y = (float)temp.x - y_mean; dumvec.at<float>(0, 0) = dummy_x; dumvec.at<float>(0, 1) = dummy_y; dum1 = Ra.dot(dumvec); if (Hmax < dum1) { Hmax = dum1; Head[0] = j; Head[1] = i; } dum2 = Ga.dot(dumvec); if (dum2 > 0) { d_dum = Rb.dot(dumvec); if (d_dum > 0) { if (Lmax < (d_dum + dum2)) { Lmax = d_dum + dum2; Lfoot[0] = j, Lfoot[1] = i; } } } dum3 = Gb.dot(dumvec); if (dum3 > 0) { d_dum = Rb.dot(dumvec); if (d_dum > 0) { if (Rmax < (d_dum + dum3)) { Rmax = d_dum + dum3; Rfoot[0] = j, Rfoot[1] = i; } } } } vector<Point> Result(3); Result[0].x = Head[0]; Result[0].y = Head[1]; Result[1].x = Lfoot[0]; Result[1].y = Lfoot[1]; Result[2].x = Rfoot[0]; Result[2].y = Rfoot[1]; return Result; }
void omxComputeNumericDeriv::computeImpl(FitContext *fc) { if (fc->fitUnits == FIT_UNITS_SQUARED_RESIDUAL || fc->fitUnits == FIT_UNITS_SQUARED_RESIDUAL_CHISQ) { // refactor TODO numParams = 0; if (verbose >= 1) mxLog("%s: derivatives %s units are meaningless", name, fitUnitsToName(fc->fitUnits)); return; //Possible TODO: calculate Hessian anyway? } int newWanted = fc->wanted | FF_COMPUTE_GRADIENT; if (wantHessian) newWanted |= FF_COMPUTE_HESSIAN; int nf = fc->calcNumFree(); if (numParams != 0 && numParams != nf) { mxThrow("%s: number of parameters changed from %d to %d", name, numParams, nf); } numParams = nf; if (numParams <= 0) { complainNoFreeParam(); return; } optima.resize(numParams); fc->copyEstToOptimizer(optima); paramMap.resize(numParams); for (int px=0,ex=0; px < numParams; ++ex) { if (fc->profiledOut[ex]) continue; paramMap[px++] = ex; } omxAlgebraPreeval(fitMat, fc); fc->createChildren(fitMat); // allow FIML rowwiseParallel even when parallel=false fc->state->countNonlinearConstraints(fc->state->numEqC, fc->state->numIneqC, false); int c_n = fc->state->numEqC + fc->state->numIneqC; fc->constraintFunVals.resize(c_n); fc->constraintJacobian.resize(c_n, numParams); if(c_n){ omxCalcFinalConstraintJacobian(fc, numParams); } // TODO: Allow more than one hessian value for calculation int numChildren = 1; if (parallel && !fc->openmpUser && fc->childList.size()) numChildren = fc->childList.size(); if (!fc->haveReferenceFit(fitMat)) return; minimum = fc->fit; hessWorkVector = new hess_struct[numChildren]; if (numChildren == 1) { omxPopulateHessianWork(hessWorkVector, fc); } else { for(int i = 0; i < numChildren; i++) { omxPopulateHessianWork(hessWorkVector + i, fc->childList[i]); } } if(verbose >= 1) mxLog("Numerical Hessian approximation (%d children, ref fit %.2f)", numChildren, minimum); hessian = NULL; if (wantHessian) { hessian = fc->getDenseHessUninitialized(); Eigen::Map< Eigen::MatrixXd > eH(hessian, numParams, numParams); eH.setConstant(NA_REAL); if (knownHessian) { int khSize = int(khMap.size()); Eigen::Map< Eigen::MatrixXd > kh(knownHessian, khSize, khMap.size()); for (int rx=0; rx < khSize; ++rx) { for (int cx=0; cx < khSize; ++cx) { if (khMap[rx] < 0 || khMap[cx] < 0) continue; eH(khMap[rx], khMap[cx]) = kh(rx, cx); } } } } if (detail) { recordDetail = false; // already done it once } else { Rf_protect(detail = Rf_allocVector(VECSXP, 4)); SET_VECTOR_ELT(detail, 0, Rf_allocVector(LGLSXP, numParams)); for (int gx=0; gx < 3; ++gx) { SET_VECTOR_ELT(detail, 1+gx, Rf_allocVector(REALSXP, numParams)); } SEXP detailCols; Rf_protect(detailCols = Rf_allocVector(STRSXP, 4)); Rf_setAttrib(detail, R_NamesSymbol, detailCols); SET_STRING_ELT(detailCols, 0, Rf_mkChar("symmetric")); SET_STRING_ELT(detailCols, 1, Rf_mkChar("forward")); SET_STRING_ELT(detailCols, 2, Rf_mkChar("central")); SET_STRING_ELT(detailCols, 3, Rf_mkChar("backward")); SEXP detailRowNames; Rf_protect(detailRowNames = Rf_allocVector(STRSXP, numParams)); Rf_setAttrib(detail, R_RowNamesSymbol, detailRowNames); for (int nx=0; nx < int(numParams); ++nx) { SET_STRING_ELT(detailRowNames, nx, Rf_mkChar(fc->varGroup->vars[nx]->name)); } markAsDataFrame(detail); } gforward = REAL(VECTOR_ELT(detail, 1)); gcentral = REAL(VECTOR_ELT(detail, 2)); gbackward = REAL(VECTOR_ELT(detail, 3)); Eigen::Map< Eigen::ArrayXd > Gf(gforward, numParams); Eigen::Map< Eigen::ArrayXd > Gc(gcentral, numParams); Eigen::Map< Eigen::ArrayXd > Gb(gbackward, numParams); Gf.setConstant(NA_REAL); Gc.setConstant(NA_REAL); Gb.setConstant(NA_REAL); calcHessianEntry che(this); CovEntrywiseParallel(numChildren, che); for(int i = 0; i < numChildren; i++) { struct hess_struct *hw = hessWorkVector + i; totalProbeCount += hw->probeCount; } delete [] hessWorkVector; if (isErrorRaised()) return; Eigen::Map< Eigen::ArrayXi > Gsymmetric(LOGICAL(VECTOR_ELT(detail, 0)), numParams); double gradNorm = 0.0; double feasibilityTolerance = Global->feasibilityTolerance; for (int px=0; px < numParams; ++px) { // factor out simliar code in ComputeNR omxFreeVar &fv = *fc->varGroup->vars[ paramMap[px] ]; if ((fabs(optima[px] - fv.lbound) < feasibilityTolerance && Gc[px] > 0) || (fabs(optima[px] - fv.ubound) < feasibilityTolerance && Gc[px] < 0)) { Gsymmetric[px] = false; continue; } gradNorm += Gc[px] * Gc[px]; double relsym = 2 * fabs(Gf[px] + Gb[px]) / (Gb[px] - Gf[px]); Gsymmetric[px] = (Gf[px] < 0 && 0 < Gb[px] && relsym < 1.5); if (checkGradient && verbose >= 2 && !Gsymmetric[px]) { mxLog("%s: param[%d] %d %f", name, px, Gsymmetric[px], relsym); } } fc->grad.resize(fc->numParam); fc->grad.setZero(); fc->copyGradFromOptimizer(Gc); if(c_n){ fc->inequality.resize(fc->state->numIneqC); fc->analyticIneqJacTmp.resize(fc->state->numIneqC, numParams); fc->myineqFun(true, verbose, omxConstraint::LESS_THAN, false); } gradNorm = sqrt(gradNorm); double gradThresh = Global->getGradientThreshold(minimum); //The gradient will generally not be near zero at a local minimum if there are equality constraints //or active inequality constraints: if ( checkGradient && gradNorm > gradThresh && !(fc->state->numEqC || fc->inequality.array().sum()) ) { if (verbose >= 1) { mxLog("Some gradient entries are too large, norm %f", gradNorm); } if (fc->getInform() < INFORM_NOT_AT_OPTIMUM) fc->setInform(INFORM_NOT_AT_OPTIMUM); } fc->setEstFromOptimizer(optima); // auxillary information like per-row likelihoods need a refresh ComputeFit(name, fitMat, FF_COMPUTE_FIT, fc); fc->wanted = newWanted; }
int PFEMElement2D::update() { // get nodal coordinates double x[3], y[3]; for(int a=0; a<3; a++) { const Vector& coord = nodes[2*a]->getCrds(); const Vector& disp = nodes[2*a]->getTrialDisp(); x[a] = coord(0) + disp(0); y[a] = coord(1) + disp(1); } // get c and d double cc[3], dd[3]; cc[0] = y[1]-y[2]; dd[0] = x[2]-x[1]; cc[1] = y[2]-y[0]; dd[1] = x[0]-x[2]; cc[2] = y[0]-y[1]; dd[2] = x[1]-x[0]; // get Jacobi double J = cc[0]*dd[1]-dd[0]*cc[1]; if(fabs(J)<1e-15) { opserr<<"WARNING: element area is nearly zero"; opserr<<" -- PFEMElement2D::update\n"; for (int i=0; i<3; i++) { opserr<<"node "<<ntags[2*i]<<"\n"; opserr<<"x = "<<x[i]<<" , y = "<<y[i]<<"\n"; } return -1; } // get M M = rho*J*thickness/6.0; Mp = (kappa<=0? 0.0 : J*thickness/kappa/24.0); double Mb = 9.*rho*J*thickness/40.0; // get Km Km.Zero(); double fact = mu*thickness/(6.*J); for (int a=0; a<3; a++) { for (int b=0; b<3; b++) { Km(2*a,2*b) = fact*(4*cc[a]*cc[b]+3*dd[a]*dd[b]); // Kxx Km(2*a,2*b+1) = fact*(3*dd[a]*cc[b]-2*cc[a]*dd[b]); // Kxy Km(2*a+1,2*b) = fact*(3*cc[a]*dd[b]-2*dd[a]*cc[b]); // Kyx Km(2*a+1,2*b+1) = fact*(3*cc[a]*cc[b]+4*dd[a]*dd[b]); // Kyy } } // get Kb Matrix Kb(2,2); fact = 27.*mu*thickness/(40.*J); double cc2 = 0., dd2 = 0., cd2 = 0.; for(int a=0; a<3; a++) { cc2 += cc[a]*cc[a]; dd2 += dd[a]*dd[a]; cd2 += cc[a]*dd[a]; } Kb(0,0) = fact*(4*cc2+3*dd2); // Kxx Kb(0,1) = fact*cd2; // Kxy Kb(1,0) = fact*cd2; // Kyx Kb(1,1) = fact*(3*cc2+4*dd2); // Kyy // get Gx and Gy Gx.Zero(); Gy.Zero(); fact = thickness/6.0; for (int a=0; a<3; a++) { Gx(a) = cc[a]*fact; Gy(a) = dd[a]*fact; } // get Gb Matrix Gb(2,3); fact = -9.*thickness/40.0; for (int a=0; a<3; a++) { Gb(0,a) = cc[a]*fact; Gb(1,a) = dd[a]*fact; } // get S S.Zero(); if (ops_Dt > 0) { Kb(0,0) += Mb/ops_Dt; Kb(1,1) += Mb/ops_Dt; } if (Kb(0,0)!=0 && Kb(1,1)!=0) { this->inverse(Kb); } S.addMatrixTripleProduct(0.0, Gb, Kb, 1); // get F F.Zero(); fact = rho*J*thickness/6.0; F(0) = fact*b1; F(1) = fact*b2; // get Fb Vector Fb(2); fact = 9.*rho*J*thickness/40.; Fb(0) = fact*b1; Fb(1) = fact*b2; // get Fp Fp.Zero(); Fp.addMatrixTransposeVector(0.0, Gb, Kb*Fb, -1); return 0; }