/*@ VecFischer - Evaluates the Fischer-Burmeister function for complementarity problems. Logically Collective on vectors Input Parameters: + X - current point . F - function evaluated at x . L - lower bounds - U - upper bounds Output Parameters: . FB - The Fischer-Burmeister function vector Notes: The Fischer-Burmeister function is defined as $ phi(a,b) := sqrt(a*a + b*b) - a - b and is used reformulate a complementarity problem as a semismooth system of equations. The result of this function is done by cases: + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i]) . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i]) . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u])) - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] Level: developer @*/ PetscErrorCode VecFischer(Vec X, Vec F, Vec L, Vec U, Vec FB) { const PetscScalar *x, *f, *l, *u; PetscScalar *fb; PetscReal xval, fval, lval, uval; PetscErrorCode ierr; PetscInt low[5], high[5], n, i; PetscFunctionBegin; PetscValidHeaderSpecific(X, VEC_CLASSID,1); PetscValidHeaderSpecific(F, VEC_CLASSID,2); PetscValidHeaderSpecific(L, VEC_CLASSID,3); PetscValidHeaderSpecific(U, VEC_CLASSID,4); PetscValidHeaderSpecific(FB, VEC_CLASSID,4); ierr = VecGetOwnershipRange(X, low, high);CHKERRQ(ierr); ierr = VecGetOwnershipRange(F, low + 1, high + 1);CHKERRQ(ierr); ierr = VecGetOwnershipRange(L, low + 2, high + 2);CHKERRQ(ierr); ierr = VecGetOwnershipRange(U, low + 3, high + 3);CHKERRQ(ierr); ierr = VecGetOwnershipRange(FB, low + 4, high + 4);CHKERRQ(ierr); for (i = 1; i < 4; ++i) { if (low[0] != low[i] || high[0] != high[i]) SETERRQ(PETSC_COMM_SELF,1,"Vectors must be identically loaded over processors"); } ierr = VecGetArrayRead(X, &x);CHKERRQ(ierr); ierr = VecGetArrayRead(F, &f);CHKERRQ(ierr); ierr = VecGetArrayRead(L, &l);CHKERRQ(ierr); ierr = VecGetArrayRead(U, &u);CHKERRQ(ierr); ierr = VecGetArray(FB, &fb);CHKERRQ(ierr); ierr = VecGetLocalSize(X, &n);CHKERRQ(ierr); for (i = 0; i < n; ++i) { xval = PetscRealPart(x[i]); fval = PetscRealPart(f[i]); lval = PetscRealPart(l[i]); uval = PetscRealPart(u[i]); if ((lval <= -PETSC_INFINITY) && (uval >= PETSC_INFINITY)) { fb[i] = -fval; } else if (lval <= -PETSC_INFINITY) { fb[i] = -Fischer(uval - xval, -fval); } else if (uval >= PETSC_INFINITY) { fb[i] = Fischer(xval - lval, fval); } else if (lval == uval) { fb[i] = lval - xval; } else { fval = Fischer(uval - xval, -fval); fb[i] = Fischer(xval - lval, fval); } } ierr = VecRestoreArrayRead(X, &x);CHKERRQ(ierr); ierr = VecRestoreArrayRead(F, &f);CHKERRQ(ierr); ierr = VecRestoreArrayRead(L, &l);CHKERRQ(ierr); ierr = VecRestoreArrayRead(U, &u);CHKERRQ(ierr); ierr = VecRestoreArray(FB, &fb);CHKERRQ(ierr); PetscFunctionReturn(0); }
/*@C SFischer - Evaluates the Smoothed Fischer-Burmeister function for complementarity problems. Input Parameters: + xx - current point . ff - function evaluated at x . ll - lower bounds . uu - upper bounds - mu - smoothing parameter Notes: The Smoothed Fischer-Burmeister function is defined as $ phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b and is used reformulate a complementarity problem as a semismooth system of equations. The result of this function is done by cases: + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] - 2*mu*x[i] . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i], mu) . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i], mu) . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu) - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i] Level: advanced .seealso TaoMat::SD_Fischer() @*/ int TaoVec::SFischer(TaoVec* xx, TaoVec* ff, TaoVec* ll, TaoVec* uu, double mu) { int info; TaoInt nn1, nn2, nn3, nn4, nn5,i; TaoScalar *v, *x, *f, *l, *u; TaoFunctionBegin; if ((mu >= -TAO_EPSILON) && (mu <= TAO_EPSILON)) { Fischer(xx, ff, ll, uu); } else { info = this->GetArray(&v, &nn1); CHKERRQ(info); info = xx->GetArray(&x, &nn2); CHKERRQ(info); info = ff->GetArray(&f, &nn3); CHKERRQ(info); info = ll->GetArray(&l, &nn4); CHKERRQ(info); info = uu->GetArray(&u, &nn5); CHKERRQ(info); if (nn1!=nn2 || nn2!=nn3 || nn3!=nn4 || nn4!=nn5) { TaoFunctionReturn(1); } for (i = 0; i < nn1; ++i) { if ((l[i] <= -TAO_INFINITY) && (u[i] >= TAO_INFINITY)) { v[i] = -f[i] - mu*x[i]; } else if (l[i] <= -TAO_INFINITY) { v[i] = -sfischer(u[i] - x[i], -f[i], mu); } else if (u[i] >= TAO_INFINITY) { v[i] = sfischer(x[i] - l[i], f[i], mu); } else if (l[i] == u[i]) { v[i] = l[i] - x[i]; } else { v[i] = sfischer(u[i] - x[i], -f[i], mu); v[i] = sfischer(x[i] - l[i], v[i], mu); } } info = this->RestoreArray(&v, &nn1); CHKERRQ(info); info = xx->RestoreArray(&x, &nn2); CHKERRQ(info); info = ff->RestoreArray(&f, &nn3); CHKERRQ(info); info = ll->RestoreArray(&l, &nn4); CHKERRQ(info); info = uu->RestoreArray(&u, &nn5); CHKERRQ(info); } TaoFunctionReturn(0); }
/*@ MatDFischer - Calculates an element of the B-subdifferential of the Fischer-Burmeister function for complementarity problems. Collective on jac Input Parameters: + jac - the jacobian of f at X . X - current point . Con - constraints function evaluated at X . XL - lower bounds . XU - upper bounds . t1 - work vector - t2 - work vector Output Parameters: + Da - diagonal perturbation component of the result - Db - row scaling component of the result Level: developer .seealso: VecFischer() @*/ PetscErrorCode MatDFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, Vec T1, Vec T2, Vec Da, Vec Db) { PetscErrorCode ierr; PetscInt i,nn; const PetscScalar *x,*f,*l,*u,*t2; PetscScalar *da,*db,*t1; PetscReal ai,bi,ci,di,ei; PetscFunctionBegin; ierr = VecGetLocalSize(X,&nn);CHKERRQ(ierr); ierr = VecGetArrayRead(X,&x);CHKERRQ(ierr); ierr = VecGetArrayRead(Con,&f);CHKERRQ(ierr); ierr = VecGetArrayRead(XL,&l);CHKERRQ(ierr); ierr = VecGetArrayRead(XU,&u);CHKERRQ(ierr); ierr = VecGetArray(Da,&da);CHKERRQ(ierr); ierr = VecGetArray(Db,&db);CHKERRQ(ierr); ierr = VecGetArray(T1,&t1);CHKERRQ(ierr); ierr = VecGetArrayRead(T2,&t2);CHKERRQ(ierr); for (i = 0; i < nn; i++) { da[i] = 0.0; db[i] = 0.0; t1[i] = 0.0; if (PetscAbsScalar(f[i]) <= PETSC_MACHINE_EPSILON) { if (PetscRealPart(l[i]) > PETSC_NINFINITY && PetscAbsScalar(x[i] - l[i]) <= PETSC_MACHINE_EPSILON) { t1[i] = 1.0; da[i] = 1.0; } if (PetscRealPart(u[i]) < PETSC_INFINITY && PetscAbsScalar(u[i] - x[i]) <= PETSC_MACHINE_EPSILON) { t1[i] = 1.0; db[i] = 1.0; } } } ierr = VecRestoreArray(T1,&t1);CHKERRQ(ierr); ierr = VecRestoreArrayRead(T2,&t2);CHKERRQ(ierr); ierr = MatMult(jac,T1,T2);CHKERRQ(ierr); ierr = VecGetArrayRead(T2,&t2);CHKERRQ(ierr); for (i = 0; i < nn; i++) { if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) { da[i] = 0.0; db[i] = -1.0; } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) { if (PetscRealPart(db[i]) >= 1) { ai = fischnorm(1.0, PetscRealPart(t2[i])); da[i] = -1.0 / ai - 1.0; db[i] = -t2[i] / ai - 1.0; } else { bi = PetscRealPart(u[i]) - PetscRealPart(x[i]); ai = fischnorm(bi, PetscRealPart(f[i])); ai = PetscMax(PETSC_MACHINE_EPSILON, ai); da[i] = bi / ai - 1.0; db[i] = -f[i] / ai - 1.0; } } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) { if (PetscRealPart(da[i]) >= 1) { ai = fischnorm(1.0, PetscRealPart(t2[i])); da[i] = 1.0 / ai - 1.0; db[i] = t2[i] / ai - 1.0; } else { bi = PetscRealPart(x[i]) - PetscRealPart(l[i]); ai = fischnorm(bi, PetscRealPart(f[i])); ai = PetscMax(PETSC_MACHINE_EPSILON, ai); da[i] = bi / ai - 1.0; db[i] = f[i] / ai - 1.0; } } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) { da[i] = -1.0; db[i] = 0.0; } else { if (PetscRealPart(db[i]) >= 1) { ai = fischnorm(1.0, PetscRealPart(t2[i])); ci = 1.0 / ai + 1.0; di = PetscRealPart(t2[i]) / ai + 1.0; } else { bi = PetscRealPart(x[i]) - PetscRealPart(u[i]); ai = fischnorm(bi, PetscRealPart(f[i])); ai = PetscMax(PETSC_MACHINE_EPSILON, ai); ci = bi / ai + 1.0; di = PetscRealPart(f[i]) / ai + 1.0; } if (PetscRealPart(da[i]) >= 1) { bi = ci + di*PetscRealPart(t2[i]); ai = fischnorm(1.0, bi); bi = bi / ai - 1.0; ai = 1.0 / ai - 1.0; } else { ei = Fischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i])); ai = fischnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei); ai = PetscMax(PETSC_MACHINE_EPSILON, ai); bi = ei / ai - 1.0; ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0; } da[i] = ai + bi*ci; db[i] = bi*di; } } ierr = VecRestoreArray(Da,&da);CHKERRQ(ierr); ierr = VecRestoreArray(Db,&db);CHKERRQ(ierr); ierr = VecRestoreArrayRead(X,&x);CHKERRQ(ierr); ierr = VecRestoreArrayRead(Con,&f);CHKERRQ(ierr); ierr = VecRestoreArrayRead(XL,&l);CHKERRQ(ierr); ierr = VecRestoreArrayRead(XU,&u);CHKERRQ(ierr); ierr = VecRestoreArrayRead(T2,&t2);CHKERRQ(ierr); PetscFunctionReturn(0); }