void Loaders::t3DSLoader::ComputeNormals(t3DModel *pModel) { CVector3 vVector1, vVector2, vNormal, vPoly[3]; if (pModel->numOfObjects <= 0) return; for (int index = 0; index < pModel->numOfObjects; index++) { t3DObject *pObject = &(pModel->pObject[index]); CVector3 *pNormals = new CVector3 [pObject->numOfFaces]; CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces]; pObject->pNormals = new CVector3 [pObject->numOfVerts]; for (int i=0; i < pObject->numOfFaces; i++) { vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; vVector1 = Vector(vPoly[0], vPoly[2]); vVector2 = Vector(vPoly[2], vPoly[1]); vNormal = Cross(vVector1, vVector2); pTempNormals[i] = vNormal; vNormal.unitMultiply(1); pNormals[i] = vNormal; } CVector3 vSum(0.0, 0.0, 0.0); CVector3 vZero = vSum; int shared = 0; for (int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) { if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = vSum + pTempNormals[j]; shared++; } } pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared)); pObject->pNormals[i].unitMultiply(1); vSum = vZero; shared = 0; } delete [] pTempNormals; delete [] pNormals; } }
void C3DSLoader::ComputeNormals(t3DModel *pModel) { Vector3 vVector1, vVector2, vNormal, vPoly[3]; if(pModel->numOfObjects <= 0) return; for(int index = 0; index < pModel->numOfObjects; index++) { t3DObject *pObject = &(pModel->pObject[index]); Vector3 *pNormals = new Vector3 [pObject->numOfFaces]; Vector3 *pTempNormals = new Vector3 [pObject->numOfFaces]; pObject->pNormals = new Vector3 [pObject->numOfVerts]; for(int i=0; i < pObject->numOfFaces; i++) { vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]]; vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]]; vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]]; vVector1 = vPoly[0] - vPoly[2]; vVector2 = vPoly[2] - vPoly[1]; vNormal = vVector1.crossProduct(vVector2); pTempNormals[i] = vNormal; vNormal = vNormal.normalize(); pNormals[i] = vNormal; } Vector3 vSum(0.0,0.0,0.0); Vector3 vZero = vSum; int shared=0; for (int i = 0; i < pObject->numOfVerts; i++) { for (int j = 0; j < pObject->numOfFaces; j++) { if (pObject->pFaces[j].vertIndex[0] == i || pObject->pFaces[j].vertIndex[1] == i || pObject->pFaces[j].vertIndex[2] == i) { vSum = vSum + pTempNormals[j]; shared++; } } pObject->pNormals[i] = vSum / float(-shared); pObject->pNormals[i] = pObject->pNormals[i].normalize(); vSum = vZero; shared = 0; } delete [] pTempNormals; delete [] pNormals; } }
/* ------------------------------------- * FindH * IN * func: Function to be minimized. * nRow: Number of rows (length) of x. * N_max: Maximum number of CG iterates. * TOL: Minimum size for gradient of f. * OUT * x: Local minimum of func. * ------------------------------------- */ double * findHSLM(double (*func)(double*, int), double *x, double** s, double** y, int nRow, int m, int k, int N_max){ double *q, *r, *alpha, *rho, *Bd, *r_cg, *d, *z, *r_new; double beta, beta_cg, alpha_cg, epsilon; int i, state, j; // Calculate gradient. r = q = gradCentralDiff(func, x, nRow); // Initialize variables alpha = (double*) malloc(nRow * sizeof(double)); rho = (double*) malloc(nRow * sizeof(double)); state = min(k, m); // Fill in rho for(i = 0; i < state; i++){ rho[i] = 1 / (dotProd(y[i], s[i], nRow)); } // First Loop for(i = (state - 1); i > 0; i--){ alpha[i] = rho[i] * dotProd(s[i], q, nRow); q = vSum(q, vProd(y[i], -alpha[i], nRow), nRow); } /* * ----------------------------------- * ########### CG Iteration ########## * ----------------------------------- * Outputs: r */ // Initialize: epsilon, d, r_cg, z epsilon = min(.5, sqrt(norm(q, nRow))) * norm(q, nRow); d = vProd(q, 1, nRow); r_cg = vProd(q, 1, nRow); z = vProd(q, 0, nRow); for(j = 0; j < N_max; j++){ Bd = hessCentralDiff(func, x, d, nRow); // Check if d'Bd <= 0 i.e. d is a descent direction. if(dotProd(d, Bd, nRow) <= 0){ if(j == 0){ r = d; break; }else{ r = z; break; } } // alpha_j = rj'rj/d_j'Bd_j alpha_cg = dotProd(r_cg, r_cg, nRow) / dotProd(d, Bd, nRow); // z_{j+1} = z_j + alpha_j*d_j z = vSum(z, vProd(d, alpha_cg, nRow), nRow); // r_{j+1} = r_j + alpha_j*B_kd_j r_new = vSum(r_cg, vProd(Bd, alpha_cg, nRow), nRow); if(norm(r_new, nRow) < epsilon){ r = z; break; } // Update beta, d, r_cg. beta_cg = dotProd(r_new, r_new, nRow) / dotProd(r_cg, r_cg, nRow); d = vSum(vProd(r_new, -1, nRow), vProd(d, beta_cg, nRow), nRow); r_cg = r_new; } /* ----------------------------------- * ######### CG Iteration End ######## * ----------------------------------- */ // Second Loop for(i = 0; i < state; i ++){ beta = rho[i] * dotProd(y[i], r, nRow); r = vSum(r, vProd(s[i], (alpha[i] - beta), nRow), nRow); } // Memory release. free(alpha); free(rho); // Return result. return r; }
/* ------------------------------------- * LBFGS * IN * func: Function to be minimized. * nRow: Number of rows (length) of x. * N_max: Maximum number of CG iterates. * TOL: Minimum size for gradient of f. * OUT * x: Local minimum of func. * ------------------------------------- */ double * SLM_LBFGS(double (* func)(double*, int), int nRow, int m, double TOL, int N_max, int verbose){ // Variable declaration. double **s, **y; double *x, *grad, *p, *x_new, *grad_new; double alpha, norm_grad0; int i, k, MAX_ITER, exploredDataPoints; // Space allocation. x = (double *)malloc(nRow * sizeof(double)); s = (double **)malloc((nRow*m) * sizeof(double)); y = (double **)malloc((nRow*m) * sizeof(double)); // Initialize x. for(i = 0; i < nRow; i++){ x[i] = ((double) rand() / INT_MAX) ; } // Stochastic Mode if(stocMode){ exploredDataPoints = 0; //printf("\nRUNNING STOCASTIC MODE\n"); SAMPLE = rand() % (int)(MAX_FILE_ROWS * sampProp); create_sample(0); exploredDataPoints += SAMPLE; } // Until Convergence or MAX_ITER. MAX_ITER = 6e6; grad = gradCentralDiff(func, x, nRow); // Update s, y. k = 0; // Initial norm of gradient. norm_grad0 = norm(grad, nRow); while(norm(grad, nRow) > TOL*(1 + norm_grad0) && ((run_logistic*exploredDataPoints + ((1 - run_logistic)*k)) < MAX_ITER)){ if(stocMode){ printf("\nRUNNING STOCASTIC MODE\n"); SAMPLE = rand() % (int)(MAX_FILE_ROWS * sampProp); create_sample(k); exploredDataPoints += SAMPLE; } // p = -Hgrad(f) if(k > 0){ p = vProd(findHSLM(func, x, s, y, nRow, m, k, N_max), -1, nRow); }else{ p = vProd(grad, -1, nRow); } // Alpha that statifies Wolfe conditions. alpha = backTrack(func, x, p, nRow, verbose); x_new = vSum(x, vProd(p, alpha, nRow), nRow); //imprimeTit("X_NEW"); //imprimeMatriz(x_new, 1, nRow); grad_new = gradCentralDiff(func, x_new, nRow); //imprimeTit("GRAD_NEW"); //imprimeMatriz(grad_new, 1, nRow); // Update s, y. updateSY(s, y, vProd(p, alpha, nRow), vSum(grad_new, vProd(grad, -1, nRow), nRow), m, k); // ---------------- PRINT ------------------- // if(verbose){ if(stocMode){ printf("\n ITER = %d; f(x) = %.10e ; " "||x|| = %.10e ; ||grad|| = %.10e ; " "||p|| = %.10e ; sTy = %.10e ; " "alpha = %.10e; explored data points = %d; precision = %fl ", k, func(x, nRow), norm(x, nRow), norm(grad, nRow), norm(p, nRow), dotProd(s[(int)min(k , (m - 1))], y[(int)min(k , (m - 1))], nRow), alpha, exploredDataPoints, class_precision(x, nRow, 0)); }else{ printf("\n ITER = %d; f(x) = %.10e ; " "||x|| = %.10e ; ||grad|| = %.10e ; " "||p|| = %.10e ; sTy = %.10e ; " "alpha = %.10e", k, func(x, nRow), norm(x, nRow), norm(grad, nRow), norm(p, nRow), dotProd(s[(int)min(k , (m - 1))], y[(int)min(k , (m - 1))], nRow), alpha); } } // ---------------- PRINT ------------------- //y // Update k, x, grad. x = x_new; grad = grad_new; k = k + 1; } free(grad); free(s); free(y); return x; }
int radTApplication::SetUpPolyhedronsFromBaseFacePolygonsTri(double zc, const char* strOrient, TVector2d* arPoints2d, int lenArPoints2d, TVector2d* arTriVertPt, int numTriVertPt, int* arTriVertInd, int numTri, double*** arPtrTrfParInExtrSteps, char** arStrTrfOrderInExtrSteps, int* arNumTrfInExtrSteps, int NumSteps, double avgCur, double* arMagnCompInExtrSteps, char frame, radThg& hgOut) { if((arTriVertPt == 0) || (numTriVertPt <= 0) || (arTriVertInd == 0) || (numTri <= 0)) return 0; if((arPtrTrfParInExtrSteps == 0) || (arStrTrfOrderInExtrSteps == 0) || (arNumTrfInExtrSteps == 0) || (NumSteps <= 0)) return 0; TVector2d *arTriVertPt1=0, *arTriVertPt2=0; int resOK = 0; try { radTGroup* pGroup = new radTGroup(); if(pGroup == 0) { Send.ErrorMessage("Radia::Error900"); throw 0;} radThg hgLoc(pGroup); arTriVertPt1 = new TVector2d[numTriVertPt]; TVector2d *t_arTriVertPt1 = arTriVertPt1, *t_arTriVertPt = arTriVertPt; for(int i=0; i<numTriVertPt; i++) *(t_arTriVertPt1++) = *(t_arTriVertPt++); arTriVertPt2 = new TVector2d[numTriVertPt]; //radTPolygon *pBaseFacePgn1 = new radTPolygon(arPoints2d, lenArPoints2d), *pBaseFacePgn2=0; //pBaseFacePgn1->CoordZ = 0; //radTPolygon genBaseFacePgn1(arPoints2d, lenArPoints2d); //, *pBaseFacePgn2=0; //genBaseFacePgn1.CoordZ = 0; //radTPolygon genBaseFacePgn2(arPoints2d, lenArPoints2d); //, *pBaseFacePgn2=0; //genBaseFacePgn2.CoordZ = 0; TVector3d vCenPointRot1(0,0,0); radTrans trfInitBaseOrient, trfInitBaseTransl; trfInitBaseOrient.SetupRotationToPermutAxes(vCenPointRot1, 'Z', *strOrient); //to find appropriate rotation taking into account direction of polygon normal !!! //trfInitBaseOrient.SetupRotation(vCenPointRot1, vEZ, vBaseNorm); TVector3d vCenPointTransl(0,0,zc); vCenPointTransl = trfInitBaseOrient.TrPoint(vCenPointTransl); trfInitBaseTransl.SetupTranslation(vCenPointTransl); radTrans auxIntermedTrans, auxTotTrans, auxTrans0; auxTrans0.SetupIdent(); if(frame > 0) {//Lab frame auxTrans0.TrMult(trfInitBaseOrient, 'R'); auxTrans0.TrMult(trfInitBaseTransl, 'L'); } //TVector3d vNormFace1(0,0,1), vCenPointBaseFace1(pBaseFacePgn1->CentrPoint.x, pBaseFacePgn1->CentrPoint.y, zc); TVector3d vNormFace1(0,0,1); //, vCenPointBaseFace1(genBaseFacePgn1.CentrPoint.x, genBaseFacePgn1.CentrPoint.y, zc); int NumSteps_mi_1 = NumSteps - 1; for(int j=0; j<NumSteps; j++) { double **arPtrTrfParInCurExtrStep = arPtrTrfParInExtrSteps[j]; char *arStrTrfOrderInCurExtrStep = arStrTrfOrderInExtrSteps[j]; int numTrfInCurExtrStep = arNumTrfInExtrSteps[j]; if((arPtrTrfParInCurExtrStep == 0) || (arStrTrfOrderInCurExtrStep == 0) || (numTrfInCurExtrStep <= 0)) continue; //pBaseFacePgn2 = new radTPolygon(*pBaseFacePgn1); //radTPolygon genBaseFacePgn2(genBaseFacePgn1); TVector2d *t_arTriVertPt1 = arTriVertPt1, *t_arTriVertPt2 = arTriVertPt2; for(int i=0; i<numTriVertPt; i++) *(t_arTriVertPt2++) = *(t_arTriVertPt1++); auxTotTrans.SetupIdent(); for(int k=0; k<numTrfInCurExtrStep; k++) { double *pCurTrfPar = arPtrTrfParInCurExtrStep[k]; if(pCurTrfPar == 0) continue; char cTypeCurTrf = arStrTrfOrderInCurExtrStep[k]; if((cTypeCurTrf == 'r') || (cTypeCurTrf == 'R')) { TVector3d vRotCen(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2)); TVector3d vRotAxis(*(pCurTrfPar+3), *(pCurTrfPar+4), *(pCurTrfPar+5)); auxIntermedTrans.SetupRotation(vRotCen, vRotAxis, *(pCurTrfPar+6)); auxTotTrans.TrMult(auxIntermedTrans, 'L'); } else if((cTypeCurTrf == 't') || (cTypeCurTrf == 'T')) { TVector3d vTransl(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2)); auxIntermedTrans.SetupTranslation(vTransl); auxTotTrans.TrMult(auxIntermedTrans, 'L'); } else if((cTypeCurTrf == 'h') || (cTypeCurTrf == 'H')) { //any homothety is applied to a face before space transformations //to check if this should be improved //pBaseFacePgn2->ApplyHomothety(*pCurTrfPar, *(pCurTrfPar+1), *(pCurTrfPar+2)); //ApplyHomothety(double kxH, double kyH, double phi) double kxH = *pCurTrfPar, kyH = *(pCurTrfPar+1), phi = *(pCurTrfPar+2); //genBaseFacePgn2.ApplyHomothety(kxH, kyH, phi); //ApplyHomothety(double kxH, double kyH, double phi) //TVector2d &CenPointBase2 = genBaseFacePgn2.CentrPoint; TVector2d vSum(0,0); for(int jjj=0; jjj<lenArPoints2d; jjj++) vSum += arPoints2d[jjj]; TVector2d CenPointBase2 = (1./lenArPoints2d)*vSum; if((kxH != 0) && (kyH != 0)) { double cosPhi = cos(phi), sinPhi = sin(phi); TVector2d vHomLocX(cosPhi, sinPhi), vHomLocY(-sinPhi, cosPhi); for(int ip=0; ip<numTriVertPt; ip++) { TVector2d vRelVertex = arTriVertPt2[ip] - CenPointBase2; arTriVertPt2[ip] = CenPointBase2 + ((kxH*(vHomLocX*vRelVertex))*vHomLocX) + ((kyH*(vHomLocY*vRelVertex))*vHomLocY); } } } } radTrans *pBaseFaceTrf1 = new radTrans(auxTrans0); if(frame == 0) auxTrans0.TrMult(auxTotTrans, 'R'); //local frame else auxTrans0.TrMult(auxTotTrans, 'L'); //laboratory frame radTrans *pBaseFaceTrf2 = new radTrans(auxTrans0); //check for memory leak !!! radTHandle<radTrans> hTrf1(pBaseFaceTrf1), hTrf2(pBaseFaceTrf2); double *pMagComp = 0; if(arMagnCompInExtrSteps != 0) pMagComp = arMagnCompInExtrSteps + j*3; TVector2d arTreePt1[3], arTreePt2[3]; int *t_arTriVertInd = arTriVertInd; for(int itr=0; itr<numTri; itr++) { arTreePt1[0] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[0] = arTriVertPt2[*(t_arTriVertInd++)]; arTreePt1[1] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[1] = arTriVertPt2[*(t_arTriVertInd++)]; arTreePt1[2] = arTriVertPt1[*t_arTriVertInd]; arTreePt2[2] = arTriVertPt2[*(t_arTriVertInd++)]; radTPolygon *pBaseFaceTri1 = new radTPolygon(arTreePt1, 3); //pBaseFaceTri1->CoordZ = genBaseFacePgn1.CoordZ; radTPolygon *pBaseFaceTri2 = new radTPolygon(arTreePt2, 3); //pBaseFaceTri2->CoordZ = genBaseFacePgn2.CoordZ; //this doesn't take into account direction of normals and eventual intersection of the faces radTHandle<radTPolygon> hPgn1(pBaseFaceTri1), hPgn2(pBaseFaceTri2); radTHandlePgnAndTrans hPgnTrf1(hPgn1, hTrf1), hPgnTrf2(hPgn2, hTrf2); //create polyhedron here from pBaseFacePgn1, pBaseFaceTrf1, pBaseFacePgn2, pBaseFaceTrf2 radTPolyhedron *pCurStepPlhdr = new radTPolyhedron(hPgnTrf1, hPgnTrf2, avgCur, pMagComp); if(pCurStepPlhdr == 0) { Send.ErrorMessage("Radia::Error900"); throw 0;} if(pCurStepPlhdr->SomethingIsWrong) { delete pCurStepPlhdr; throw 0;} radThg hgCurStepPlhdr(pCurStepPlhdr); pGroup->AddElement(AddElementToContainer(hgCurStepPlhdr), hgCurStepPlhdr); } //if(j < NumSteps_mi_1) //{ // //pBaseFacePgn1 = new radTPolygon(*pBaseFacePgn2); // genBaseFacePgn1 = genBaseFacePgn2; //// //- treat frame (0- local, otherwise "laboratory"); //// //if(frame == 0) pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf1); //leave base trf always the same if Frame->Loc ?? //// //else pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf2); //change base trf if Frame->Lab //// if(frame == 0) pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf2); //change base trf if Frame->Loc //// else pBaseFaceTrf1 = new radTrans(*pBaseFaceTrf1); //leave base trf always the same if Frame->Lab //} } if(frame == 0) { auxTrans0.SetupIdent(); auxTrans0.TrMult(trfInitBaseOrient, 'R'); auxTrans0.TrMult(trfInitBaseTransl, 'L'); double relTol = 1.E-12; //to ensure correct operation on 32-bit OS if(!auxTrans0.IsIdent(relTol)) { radTrans* TransPtr = new radTrans(auxTrans0); if(TransPtr == 0) { Send.ErrorMessage("Radia::Error900"); return 0;} radThg hgTrf(TransPtr); ((radTg3d*)(hgLoc.rep))->AddTransform(1, hgTrf); } } hgOut = hgLoc; resOK = 1; } catch(...) { Initialize(); //return 0; resOK = 0; } if(arTriVertPt1 != 0) delete[] arTriVertPt1; if(arTriVertPt2 != 0) delete[] arTriVertPt2; return resOK; }
// 计算顶点法线量 void C3DSModel::ComputeNormals(void) { Vector3 v1,v2, vNormal,vPoly[3]; // 如果没有3ds对象则直接返回 if (m_3DModel.numOfObjects <= 0) return; t3DObject *obj; int *index; for(int nOfObj=0; nOfObj<m_3DModel.numOfObjects; nOfObj++) { obj = &m_3DModel.pObject[nOfObj]; Vector3 *pNormals = new Vector3 [obj->numOfFaces]; Vector3 *pTempNormals = new Vector3 [obj->numOfFaces]; obj->pNormals = new Vector3 [obj->numOfVerts]; for(int nOfFace=0; nOfFace<obj->numOfFaces; nOfFace++) { index = obj->pFaces[nOfFace].vertIndex; // 三角形的3个顶点 vPoly[0] = obj->pVerts[index[0]]; vPoly[1] = obj->pVerts[index[1]]; vPoly[2] = obj->pVerts[index[2]]; // 计算这个三角形的法线量 v1 = vPoly[0]-vPoly[1]; v2 = vPoly[2]-vPoly[1]; vNormal = Cross(v1, v2); pTempNormals[nOfFace] = vNormal; // 保存未单位化的法向量 vNormal = Normalize(vNormal); // 单位化法向量 pNormals[nOfFace] = vNormal; // 增加到法向量数组列表 } Vector3 vSum(0.0, 0.0, 0.0); Vector3 vZero(0.0, 0.0, 0.0); int shared=0; for (int nOfVert = 0; nOfVert < obj->numOfVerts; nOfVert++) // 遍历所有顶点 { for (int nOfFace = 0; nOfFace < obj->numOfFaces; nOfFace++) // 遍历包含该顶点的面 { if (obj->pFaces[nOfFace].vertIndex[0] == nOfVert || obj->pFaces[nOfFace].vertIndex[1] == nOfVert || obj->pFaces[nOfFace].vertIndex[2] == nOfVert) { vSum = vSum+pTempNormals[nOfFace]; shared++; } } obj->pNormals[nOfVert] = vSum/float(-shared); obj->pNormals[nOfVert] = Normalize(obj->pNormals[nOfVert]); vSum = vZero; shared = 0; } delete [] pTempNormals; delete [] pNormals; } }
// Get bounds according to different distance metrics int getBounds(float* S1r, float* S2r, const short& B, const Rset& R, float& lb, float& ub, const string dist) { // Get |A+| float* Apv = new float[B]; vSub(S1r + B*(R.hi[1]), S1r + B*(R.lo[0]-1), B, &Apv); float Ap = vSum(Apv,B) + EPS; // |A+| // Get |k+| float* Bpv = new float[B]; vSub(S2r + B*(R.hi[3]), S2r + B*(R.lo[2]-1), B, &Bpv); float Bp = vSum(Bpv, B) + EPS; // |B+| // Get |A-| float Am = EPS; // |A-| float* Amv = new float[B]; if (R.lo[1] >= R.hi[0]) { vSub(S1r + B*(R.lo[1]), S1r + B*(R.hi[0]-1), B, &Amv); Am += vSum(Amv, B); } else { memset(Amv, 0, sizeof(float)*B); } // Get |B-| float Bm = EPS; float* Bmv = new float[B]; if (R.lo[3] >= R.hi[2]) { vSub(S2r + B*(R.lo[3]), S2r + B*(R.hi[2]-1), B, &Bmv); Bm += vSum(Bmv, B); } else { memset(Bmv, 0, sizeof(float)*B); } lb = 0.0f; ub = 0.0f; short i; if (dist.compare("l1")==0) { for (i=0; i<B; i++) { lb += max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm); ub += max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp); } } else if (dist.compare("l2")==0) { for (i=0; i<B; i++) { lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f); ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f); } } else if (dist.compare("X2")==0) { for (i=0; i<B; i++) { lb += pow(max(0.0f, max(Amv[i]/Ap, Bmv[i]/Bp) - min(Apv[i]/Am, Bpv[i]/Bm)), 2.0f) \ / (Apv[i]/Am + Bpv[i]/Bm + EPS); ub += pow(max(Apv[i]/Am, Bpv[i]/Bm) - min(Amv[i]/Ap, Bmv[i]/Bp), 2.0f) \ / (Amv[i]/Ap + Bmv[i]/Bp + EPS); } } else if (dist.compare("int")==0) { for (i=0; i<B; i++) { lb -= min(Apv[i]/Am, Bpv[i]/Bm); ub -= min(Amv[i]/Ap, Bmv[i]/Bp); } } delete[] Apv; delete[] Bpv; delete[] Amv; delete[] Bmv; return 0; }