1af0996ceSBarry Smith #include <petsc/private/petscimpl.h>
2ba92ff59SBarry Smith #include <petsctao.h> /*I "petsctao.h" I*/
38370d7cdSHansol Suh #include <petscsys.h>
4a7e14dcfSSatish Balay
Fischer(PetscReal a,PetscReal b)5d71ae5a4SJacob Faibussowitsch static inline PetscReal Fischer(PetscReal a, PetscReal b)
6d71ae5a4SJacob Faibussowitsch {
7a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */
8ad540459SPierre Jolivet if (a + b <= 0) return PetscSqrtReal(a * a + b * b) - (a + b);
946bdf8c8SLisandro Dalcin return -2.0 * a * b / (PetscSqrtReal(a * a + b * b) + (a + b));
10a7e14dcfSSatish Balay }
11a7e14dcfSSatish Balay
12a7e14dcfSSatish Balay /*@
13a7e14dcfSSatish Balay VecFischer - Evaluates the Fischer-Burmeister function for complementarity
14a7e14dcfSSatish Balay problems.
15a7e14dcfSSatish Balay
16c3339decSBarry Smith Logically Collective
17a7e14dcfSSatish Balay
18a7e14dcfSSatish Balay Input Parameters:
19a7e14dcfSSatish Balay + X - current point
20a7e14dcfSSatish Balay . F - function evaluated at x
21a7e14dcfSSatish Balay . L - lower bounds
22a7e14dcfSSatish Balay - U - upper bounds
23a7e14dcfSSatish Balay
24f899ff85SJose E. Roman Output Parameter:
25a7e14dcfSSatish Balay . FB - The Fischer-Burmeister function vector
26a7e14dcfSSatish Balay
272fe279fdSBarry Smith Level: developer
282fe279fdSBarry Smith
29a7e14dcfSSatish Balay Notes:
30a7e14dcfSSatish Balay The Fischer-Burmeister function is defined as
31*b44f4de4SBarry Smith
32*b44f4de4SBarry Smith $$
33*b44f4de4SBarry Smith \phi(a,b) := \sqrt{a^2 + b^2} - a - b
34*b44f4de4SBarry Smith $$
35*b44f4de4SBarry Smith
36a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth
37a7e14dcfSSatish Balay system of equations.
38a7e14dcfSSatish Balay
393b242c63SJacob Faibussowitsch The result of this function is done by cases\:
40a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i]
41a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i])
42a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i])
43a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u]))
44a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
45a7e14dcfSSatish Balay
46a1cb98faSBarry Smith .seealso: `Vec`, `VecSFischer()`, `MatDFischer()`, `MatDSFischer()`
47a7e14dcfSSatish Balay @*/
VecFischer(Vec X,Vec F,Vec L,Vec U,Vec FB)48d71ae5a4SJacob Faibussowitsch PetscErrorCode VecFischer(Vec X, Vec F, Vec L, Vec U, Vec FB)
49d71ae5a4SJacob Faibussowitsch {
5046bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u;
5146bdf8c8SLisandro Dalcin PetscScalar *fb;
52a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval;
53a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i;
54a7e14dcfSSatish Balay
55a7e14dcfSSatish Balay PetscFunctionBegin;
56a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 1);
57a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID, 2);
5876be6f4fSStefano Zampini if (L) PetscValidHeaderSpecific(L, VEC_CLASSID, 3);
5976be6f4fSStefano Zampini if (U) PetscValidHeaderSpecific(U, VEC_CLASSID, 4);
60064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(FB, VEC_CLASSID, 5);
61a7e14dcfSSatish Balay
6276be6f4fSStefano Zampini if (!L && !U) {
6376be6f4fSStefano Zampini PetscCall(VecAXPBY(FB, -1.0, 0.0, F));
643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
6576be6f4fSStefano Zampini }
6676be6f4fSStefano Zampini
679566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high));
689566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1));
699566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2));
709566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3));
719566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4));
72a7e14dcfSSatish Balay
73ad540459SPierre Jolivet for (i = 1; i < 4; ++i) PetscCheck(low[0] == low[i] && high[0] == high[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Vectors must be identically loaded over processors");
74a7e14dcfSSatish Balay
759566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x));
769566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f));
779566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l));
789566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u));
799566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb));
80a7e14dcfSSatish Balay
819566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n));
82a7e14dcfSSatish Balay
83a7e14dcfSSatish Balay for (i = 0; i < n; ++i) {
8476be6f4fSStefano Zampini xval = PetscRealPart(x[i]);
8576be6f4fSStefano Zampini fval = PetscRealPart(f[i]);
8676be6f4fSStefano Zampini lval = PetscRealPart(l[i]);
8776be6f4fSStefano Zampini uval = PetscRealPart(u[i]);
88a7e14dcfSSatish Balay
8976be6f4fSStefano Zampini if (lval <= -PETSC_INFINITY && uval >= PETSC_INFINITY) {
90a7e14dcfSSatish Balay fb[i] = -fval;
91e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) {
92a7e14dcfSSatish Balay fb[i] = -Fischer(uval - xval, -fval);
93e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) {
94a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval);
952d0e5244SBarry Smith } else if (lval == uval) {
96a7e14dcfSSatish Balay fb[i] = lval - xval;
972d0e5244SBarry Smith } else {
98a7e14dcfSSatish Balay fval = Fischer(uval - xval, -fval);
99a7e14dcfSSatish Balay fb[i] = Fischer(xval - lval, fval);
100a7e14dcfSSatish Balay }
101a7e14dcfSSatish Balay }
102a7e14dcfSSatish Balay
1039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x));
1049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f));
1059566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l));
1069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u));
1079566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb));
1083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
109a7e14dcfSSatish Balay }
110a7e14dcfSSatish Balay
SFischer(PetscReal a,PetscReal b,PetscReal c)111d71ae5a4SJacob Faibussowitsch static inline PetscReal SFischer(PetscReal a, PetscReal b, PetscReal c)
112d71ae5a4SJacob Faibussowitsch {
113a7e14dcfSSatish Balay /* Method suggested by Bob Vanderbei */
114ad540459SPierre Jolivet if (a + b <= 0) return PetscSqrtReal(a * a + b * b + 2.0 * c * c) - (a + b);
1153f6ba705SLisandro Dalcin return 2.0 * (c * c - a * b) / (PetscSqrtReal(a * a + b * b + 2.0 * c * c) + (a + b));
116a7e14dcfSSatish Balay }
117a7e14dcfSSatish Balay
118a7e14dcfSSatish Balay /*@
119a7e14dcfSSatish Balay VecSFischer - Evaluates the Smoothed Fischer-Burmeister function for
120a7e14dcfSSatish Balay complementarity problems.
121a7e14dcfSSatish Balay
122c3339decSBarry Smith Logically Collective
123a7e14dcfSSatish Balay
124a7e14dcfSSatish Balay Input Parameters:
125a7e14dcfSSatish Balay + X - current point
126a7e14dcfSSatish Balay . F - function evaluated at x
127a7e14dcfSSatish Balay . L - lower bounds
128a7e14dcfSSatish Balay . U - upper bounds
129a7e14dcfSSatish Balay - mu - smoothing parameter
130a7e14dcfSSatish Balay
131f899ff85SJose E. Roman Output Parameter:
132a7e14dcfSSatish Balay . FB - The Smoothed Fischer-Burmeister function vector
133a7e14dcfSSatish Balay
134a7e14dcfSSatish Balay Notes:
135a7e14dcfSSatish Balay The Smoothed Fischer-Burmeister function is defined as
136a7e14dcfSSatish Balay $ phi(a,b) := sqrt(a*a + b*b + 2*mu*mu) - a - b
137a7e14dcfSSatish Balay and is used reformulate a complementarity problem as a semismooth
138a7e14dcfSSatish Balay system of equations.
139a7e14dcfSSatish Balay
1403b242c63SJacob Faibussowitsch The result of this function is done by cases\:
141a7e14dcfSSatish Balay + l[i] == -infinity, u[i] == infinity -- fb[i] = -f[i] - 2*mu*x[i]
142a7e14dcfSSatish Balay . l[i] == -infinity, u[i] finite -- fb[i] = phi(u[i]-x[i], -f[i], mu)
143a7e14dcfSSatish Balay . l[i] finite, u[i] == infinity -- fb[i] = phi(x[i]-l[i], f[i], mu)
144a7e14dcfSSatish Balay . l[i] finite < u[i] finite -- fb[i] = phi(x[i]-l[i], phi(u[i]-x[i], -f[u], mu), mu)
145a7e14dcfSSatish Balay - otherwise l[i] == u[i] -- fb[i] = l[i] - x[i]
146a7e14dcfSSatish Balay
147a7e14dcfSSatish Balay Level: developer
148a7e14dcfSSatish Balay
149a1cb98faSBarry Smith .seealso: `Vec`, `VecFischer()`, `MatDFischer()`, `MatDSFischer()`
150a7e14dcfSSatish Balay @*/
VecSFischer(Vec X,Vec F,Vec L,Vec U,PetscReal mu,Vec FB)151d71ae5a4SJacob Faibussowitsch PetscErrorCode VecSFischer(Vec X, Vec F, Vec L, Vec U, PetscReal mu, Vec FB)
152d71ae5a4SJacob Faibussowitsch {
15346bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u;
15446bdf8c8SLisandro Dalcin PetscScalar *fb;
155a7e14dcfSSatish Balay PetscReal xval, fval, lval, uval;
156a7e14dcfSSatish Balay PetscInt low[5], high[5], n, i;
157a7e14dcfSSatish Balay
158a7e14dcfSSatish Balay PetscFunctionBegin;
159a7e14dcfSSatish Balay PetscValidHeaderSpecific(X, VEC_CLASSID, 1);
160a7e14dcfSSatish Balay PetscValidHeaderSpecific(F, VEC_CLASSID, 2);
161a7e14dcfSSatish Balay PetscValidHeaderSpecific(L, VEC_CLASSID, 3);
162a7e14dcfSSatish Balay PetscValidHeaderSpecific(U, VEC_CLASSID, 4);
163a7e14dcfSSatish Balay PetscValidHeaderSpecific(FB, VEC_CLASSID, 6);
164a7e14dcfSSatish Balay
1659566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(X, low, high));
1669566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(F, low + 1, high + 1));
1679566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(L, low + 2, high + 2));
1689566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(U, low + 3, high + 3));
1699566063dSJacob Faibussowitsch PetscCall(VecGetOwnershipRange(FB, low + 4, high + 4));
170a7e14dcfSSatish Balay
171ad540459SPierre Jolivet for (i = 1; i < 4; ++i) PetscCheck(low[0] == low[i] && high[0] == high[i], PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Vectors must be identically loaded over processors");
172a7e14dcfSSatish Balay
1739566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x));
1749566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(F, &f));
1759566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(L, &l));
1769566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(U, &u));
1779566063dSJacob Faibussowitsch PetscCall(VecGetArray(FB, &fb));
178a7e14dcfSSatish Balay
1799566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &n));
180a7e14dcfSSatish Balay
181a7e14dcfSSatish Balay for (i = 0; i < n; ++i) {
1829371c9d4SSatish Balay xval = PetscRealPart(*x++);
1839371c9d4SSatish Balay fval = PetscRealPart(*f++);
1849371c9d4SSatish Balay lval = PetscRealPart(*l++);
1859371c9d4SSatish Balay uval = PetscRealPart(*u++);
186a7e14dcfSSatish Balay
187e270355aSBarry Smith if ((lval <= -PETSC_INFINITY) && (uval >= PETSC_INFINITY)) {
188a7e14dcfSSatish Balay (*fb++) = -fval - mu * xval;
189e270355aSBarry Smith } else if (lval <= -PETSC_INFINITY) {
190a7e14dcfSSatish Balay (*fb++) = -SFischer(uval - xval, -fval, mu);
191e270355aSBarry Smith } else if (uval >= PETSC_INFINITY) {
192a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu);
1932d0e5244SBarry Smith } else if (lval == uval) {
194a7e14dcfSSatish Balay (*fb++) = lval - xval;
1952d0e5244SBarry Smith } else {
196a7e14dcfSSatish Balay fval = SFischer(uval - xval, -fval, mu);
197a7e14dcfSSatish Balay (*fb++) = SFischer(xval - lval, fval, mu);
198a7e14dcfSSatish Balay }
199a7e14dcfSSatish Balay }
2009371c9d4SSatish Balay x -= n;
2019371c9d4SSatish Balay f -= n;
2029371c9d4SSatish Balay l -= n;
2039371c9d4SSatish Balay u -= n;
2049371c9d4SSatish Balay fb -= n;
205a7e14dcfSSatish Balay
2069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x));
2079566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(F, &f));
2089566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(L, &l));
2099566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(U, &u));
2109566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(FB, &fb));
2113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
212a7e14dcfSSatish Balay }
213a7e14dcfSSatish Balay
fischnorm(PetscReal a,PetscReal b)214d71ae5a4SJacob Faibussowitsch static inline PetscReal fischnorm(PetscReal a, PetscReal b)
215d71ae5a4SJacob Faibussowitsch {
216658c1fc4SLisandro Dalcin return PetscSqrtReal(a * a + b * b);
217a7e14dcfSSatish Balay }
218a7e14dcfSSatish Balay
fischsnorm(PetscReal a,PetscReal b,PetscReal c)219d71ae5a4SJacob Faibussowitsch static inline PetscReal fischsnorm(PetscReal a, PetscReal b, PetscReal c)
220d71ae5a4SJacob Faibussowitsch {
221658c1fc4SLisandro Dalcin return PetscSqrtReal(a * a + b * b + 2.0 * c * c);
222a7e14dcfSSatish Balay }
223a7e14dcfSSatish Balay
224a7e14dcfSSatish Balay /*@
225235fd6e6SBarry Smith MatDFischer - Calculates an element of the B-subdifferential of the
226a7e14dcfSSatish Balay Fischer-Burmeister function for complementarity problems.
227a7e14dcfSSatish Balay
228c3339decSBarry Smith Collective
229a7e14dcfSSatish Balay
230a7e14dcfSSatish Balay Input Parameters:
2313b242c63SJacob Faibussowitsch + jac - the jacobian of `f` at `X`
232a7e14dcfSSatish Balay . X - current point
2333b242c63SJacob Faibussowitsch . Con - constraints function evaluated at `X`
234a7e14dcfSSatish Balay . XL - lower bounds
235a7e14dcfSSatish Balay . XU - upper bounds
2363b242c63SJacob Faibussowitsch . T1 - work vector
2373b242c63SJacob Faibussowitsch - T2 - work vector
238a7e14dcfSSatish Balay
239a7e14dcfSSatish Balay Output Parameters:
240a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result
241a7e14dcfSSatish Balay - Db - row scaling component of the result
242a7e14dcfSSatish Balay
243a7e14dcfSSatish Balay Level: developer
244a7e14dcfSSatish Balay
245a1cb98faSBarry Smith .seealso: `Mat`, `VecFischer()`, `VecSFischer()`, `MatDSFischer()`
246a7e14dcfSSatish Balay @*/
MatDFischer(Mat jac,Vec X,Vec Con,Vec XL,Vec XU,Vec T1,Vec T2,Vec Da,Vec Db)247d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, Vec T1, Vec T2, Vec Da, Vec Db)
248d71ae5a4SJacob Faibussowitsch {
249a7e14dcfSSatish Balay PetscInt i, nn;
25046bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u, *t2;
25146bdf8c8SLisandro Dalcin PetscScalar *da, *db, *t1;
252a7e14dcfSSatish Balay PetscReal ai, bi, ci, di, ei;
253a7e14dcfSSatish Balay
254a7e14dcfSSatish Balay PetscFunctionBegin;
2559566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &nn));
2569566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x));
2579566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con, &f));
2589566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL, &l));
2599566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU, &u));
2609566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da, &da));
2619566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db, &db));
2629566063dSJacob Faibussowitsch PetscCall(VecGetArray(T1, &t1));
2639566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2, &t2));
264a7e14dcfSSatish Balay
265a7e14dcfSSatish Balay for (i = 0; i < nn; i++) {
26646bdf8c8SLisandro Dalcin da[i] = 0.0;
26746bdf8c8SLisandro Dalcin db[i] = 0.0;
26846bdf8c8SLisandro Dalcin t1[i] = 0.0;
269a7e14dcfSSatish Balay
27046bdf8c8SLisandro Dalcin if (PetscAbsScalar(f[i]) <= PETSC_MACHINE_EPSILON) {
27146bdf8c8SLisandro Dalcin if (PetscRealPart(l[i]) > PETSC_NINFINITY && PetscAbsScalar(x[i] - l[i]) <= PETSC_MACHINE_EPSILON) {
27246bdf8c8SLisandro Dalcin t1[i] = 1.0;
27346bdf8c8SLisandro Dalcin da[i] = 1.0;
274a7e14dcfSSatish Balay }
275a7e14dcfSSatish Balay
27646bdf8c8SLisandro Dalcin if (PetscRealPart(u[i]) < PETSC_INFINITY && PetscAbsScalar(u[i] - x[i]) <= PETSC_MACHINE_EPSILON) {
27746bdf8c8SLisandro Dalcin t1[i] = 1.0;
27846bdf8c8SLisandro Dalcin db[i] = 1.0;
279a7e14dcfSSatish Balay }
280a7e14dcfSSatish Balay }
281a7e14dcfSSatish Balay }
282a7e14dcfSSatish Balay
2839566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(T1, &t1));
2849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2, &t2));
2859566063dSJacob Faibussowitsch PetscCall(MatMult(jac, T1, T2));
2869566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(T2, &t2));
287a7e14dcfSSatish Balay
288a7e14dcfSSatish Balay for (i = 0; i < nn; i++) {
28946bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) {
29046bdf8c8SLisandro Dalcin da[i] = 0.0;
29146bdf8c8SLisandro Dalcin db[i] = -1.0;
29246bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) {
29346bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) {
294658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i]));
295a7e14dcfSSatish Balay
29646bdf8c8SLisandro Dalcin da[i] = -1.0 / ai - 1.0;
29746bdf8c8SLisandro Dalcin db[i] = -t2[i] / ai - 1.0;
2982d0e5244SBarry Smith } else {
299658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]);
300658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i]));
301a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
302a7e14dcfSSatish Balay
30346bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0;
30446bdf8c8SLisandro Dalcin db[i] = -f[i] / ai - 1.0;
305a7e14dcfSSatish Balay }
30646bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) {
30746bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) {
308658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i]));
309a7e14dcfSSatish Balay
31046bdf8c8SLisandro Dalcin da[i] = 1.0 / ai - 1.0;
31146bdf8c8SLisandro Dalcin db[i] = t2[i] / ai - 1.0;
3122d0e5244SBarry Smith } else {
313658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]);
314658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i]));
315a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
316a7e14dcfSSatish Balay
31746bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0;
31846bdf8c8SLisandro Dalcin db[i] = f[i] / ai - 1.0;
319a7e14dcfSSatish Balay }
320658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) {
32146bdf8c8SLisandro Dalcin da[i] = -1.0;
32246bdf8c8SLisandro Dalcin db[i] = 0.0;
3232d0e5244SBarry Smith } else {
32446bdf8c8SLisandro Dalcin if (PetscRealPart(db[i]) >= 1) {
325658c1fc4SLisandro Dalcin ai = fischnorm(1.0, PetscRealPart(t2[i]));
326a7e14dcfSSatish Balay
32746bdf8c8SLisandro Dalcin ci = 1.0 / ai + 1.0;
328658c1fc4SLisandro Dalcin di = PetscRealPart(t2[i]) / ai + 1.0;
3292d0e5244SBarry Smith } else {
330658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]);
331658c1fc4SLisandro Dalcin ai = fischnorm(bi, PetscRealPart(f[i]));
332a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
333a7e14dcfSSatish Balay
33446bdf8c8SLisandro Dalcin ci = bi / ai + 1.0;
335658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0;
336a7e14dcfSSatish Balay }
337a7e14dcfSSatish Balay
33846bdf8c8SLisandro Dalcin if (PetscRealPart(da[i]) >= 1) {
339658c1fc4SLisandro Dalcin bi = ci + di * PetscRealPart(t2[i]);
340658c1fc4SLisandro Dalcin ai = fischnorm(1.0, bi);
341a7e14dcfSSatish Balay
34246bdf8c8SLisandro Dalcin bi = bi / ai - 1.0;
34346bdf8c8SLisandro Dalcin ai = 1.0 / ai - 1.0;
3442d0e5244SBarry Smith } else {
345658c1fc4SLisandro Dalcin ei = Fischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i]));
346658c1fc4SLisandro Dalcin ai = fischnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei);
347a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
348a7e14dcfSSatish Balay
34946bdf8c8SLisandro Dalcin bi = ei / ai - 1.0;
350658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0;
351a7e14dcfSSatish Balay }
352a7e14dcfSSatish Balay
353a7e14dcfSSatish Balay da[i] = ai + bi * ci;
354a7e14dcfSSatish Balay db[i] = bi * di;
355a7e14dcfSSatish Balay }
356a7e14dcfSSatish Balay }
357a7e14dcfSSatish Balay
3589566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da, &da));
3599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db, &db));
3609566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x));
3619566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con, &f));
3629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL, &l));
3639566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU, &u));
3649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(T2, &t2));
3653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3668e3154b5SSatish Balay }
367a7e14dcfSSatish Balay
368a7e14dcfSSatish Balay /*@
369235fd6e6SBarry Smith MatDSFischer - Calculates an element of the B-subdifferential of the
370a7e14dcfSSatish Balay smoothed Fischer-Burmeister function for complementarity problems.
371a7e14dcfSSatish Balay
372c3339decSBarry Smith Collective
373a7e14dcfSSatish Balay
374a7e14dcfSSatish Balay Input Parameters:
375a7e14dcfSSatish Balay + jac - the jacobian of f at X
376a7e14dcfSSatish Balay . X - current point
377e056e8ceSJacob Faibussowitsch . Con - constraint function evaluated at X
378a7e14dcfSSatish Balay . XL - lower bounds
379a7e14dcfSSatish Balay . XU - upper bounds
380a7e14dcfSSatish Balay . mu - smoothing parameter
381a7e14dcfSSatish Balay . T1 - work vector
382a7e14dcfSSatish Balay - T2 - work vector
383a7e14dcfSSatish Balay
384d8d19677SJose E. Roman Output Parameters:
385a7e14dcfSSatish Balay + Da - diagonal perturbation component of the result
386a7e14dcfSSatish Balay . Db - row scaling component of the result
387a7e14dcfSSatish Balay - Dm - derivative with respect to scaling parameter
388a7e14dcfSSatish Balay
389a7e14dcfSSatish Balay Level: developer
390a7e14dcfSSatish Balay
391a1cb98faSBarry Smith .seealso: `Mat`, `VecFischer()`, `VecDFischer()`, `MatDFischer()`
392a7e14dcfSSatish Balay @*/
MatDSFischer(Mat jac,Vec X,Vec Con,Vec XL,Vec XU,PetscReal mu,Vec T1,Vec T2,Vec Da,Vec Db,Vec Dm)393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDSFischer(Mat jac, Vec X, Vec Con, Vec XL, Vec XU, PetscReal mu, Vec T1, Vec T2, Vec Da, Vec Db, Vec Dm)
394d71ae5a4SJacob Faibussowitsch {
395a7e14dcfSSatish Balay PetscInt i, nn;
39646bdf8c8SLisandro Dalcin const PetscScalar *x, *f, *l, *u;
39746bdf8c8SLisandro Dalcin PetscScalar *da, *db, *dm;
398a7e14dcfSSatish Balay PetscReal ai, bi, ci, di, ei, fi;
399a7e14dcfSSatish Balay
400a7e14dcfSSatish Balay PetscFunctionBegin;
401a7e14dcfSSatish Balay if (PetscAbsReal(mu) <= PETSC_MACHINE_EPSILON) {
4029566063dSJacob Faibussowitsch PetscCall(VecZeroEntries(Dm));
4039566063dSJacob Faibussowitsch PetscCall(MatDFischer(jac, X, Con, XL, XU, T1, T2, Da, Db));
4042d0e5244SBarry Smith } else {
4059566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(X, &nn));
4069566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(X, &x));
4079566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(Con, &f));
4089566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XL, &l));
4099566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(XU, &u));
4109566063dSJacob Faibussowitsch PetscCall(VecGetArray(Da, &da));
4119566063dSJacob Faibussowitsch PetscCall(VecGetArray(Db, &db));
4129566063dSJacob Faibussowitsch PetscCall(VecGetArray(Dm, &dm));
413a7e14dcfSSatish Balay
414a7e14dcfSSatish Balay for (i = 0; i < nn; ++i) {
41546bdf8c8SLisandro Dalcin if ((PetscRealPart(l[i]) <= PETSC_NINFINITY) && (PetscRealPart(u[i]) >= PETSC_INFINITY)) {
416a7e14dcfSSatish Balay da[i] = -mu;
41746bdf8c8SLisandro Dalcin db[i] = -1.0;
418a7e14dcfSSatish Balay dm[i] = -x[i];
41946bdf8c8SLisandro Dalcin } else if (PetscRealPart(l[i]) <= PETSC_NINFINITY) {
420658c1fc4SLisandro Dalcin bi = PetscRealPart(u[i]) - PetscRealPart(x[i]);
421658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu);
422a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
423a7e14dcfSSatish Balay
42446bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0;
425658c1fc4SLisandro Dalcin db[i] = -PetscRealPart(f[i]) / ai - 1.0;
426a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai;
42746bdf8c8SLisandro Dalcin } else if (PetscRealPart(u[i]) >= PETSC_INFINITY) {
428658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(l[i]);
429658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu);
430a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
431a7e14dcfSSatish Balay
43246bdf8c8SLisandro Dalcin da[i] = bi / ai - 1.0;
433658c1fc4SLisandro Dalcin db[i] = PetscRealPart(f[i]) / ai - 1.0;
434a7e14dcfSSatish Balay dm[i] = 2.0 * mu / ai;
435658c1fc4SLisandro Dalcin } else if (PetscRealPart(l[i]) == PetscRealPart(u[i])) {
43646bdf8c8SLisandro Dalcin da[i] = -1.0;
43746bdf8c8SLisandro Dalcin db[i] = 0.0;
43846bdf8c8SLisandro Dalcin dm[i] = 0.0;
4392d0e5244SBarry Smith } else {
440658c1fc4SLisandro Dalcin bi = PetscRealPart(x[i]) - PetscRealPart(u[i]);
441658c1fc4SLisandro Dalcin ai = fischsnorm(bi, PetscRealPart(f[i]), mu);
442a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
443a7e14dcfSSatish Balay
44446bdf8c8SLisandro Dalcin ci = bi / ai + 1.0;
445658c1fc4SLisandro Dalcin di = PetscRealPart(f[i]) / ai + 1.0;
446a7e14dcfSSatish Balay fi = 2.0 * mu / ai;
447a7e14dcfSSatish Balay
448658c1fc4SLisandro Dalcin ei = SFischer(PetscRealPart(u[i]) - PetscRealPart(x[i]), -PetscRealPart(f[i]), mu);
449658c1fc4SLisandro Dalcin ai = fischsnorm(PetscRealPart(x[i]) - PetscRealPart(l[i]), ei, mu);
450a7e14dcfSSatish Balay ai = PetscMax(PETSC_MACHINE_EPSILON, ai);
451a7e14dcfSSatish Balay
45246bdf8c8SLisandro Dalcin bi = ei / ai - 1.0;
453a7e14dcfSSatish Balay ei = 2.0 * mu / ei;
454658c1fc4SLisandro Dalcin ai = (PetscRealPart(x[i]) - PetscRealPart(l[i])) / ai - 1.0;
455a7e14dcfSSatish Balay
456a7e14dcfSSatish Balay da[i] = ai + bi * ci;
457a7e14dcfSSatish Balay db[i] = bi * di;
458a7e14dcfSSatish Balay dm[i] = ei + bi * fi;
459a7e14dcfSSatish Balay }
460a7e14dcfSSatish Balay }
461a7e14dcfSSatish Balay
4629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(X, &x));
4639566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(Con, &f));
4649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XL, &l));
4659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(XU, &u));
4669566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Da, &da));
4679566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Db, &db));
4689566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(Dm, &dm));
469a7e14dcfSSatish Balay }
4703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
471a7e14dcfSSatish Balay }
472a7e14dcfSSatish Balay
ST_InternalPN(PetscScalar in,PetscReal lb,PetscReal ub)473d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalPN(PetscScalar in, PetscReal lb, PetscReal ub)
474d71ae5a4SJacob Faibussowitsch {
475835f2295SStefano Zampini return PetscMax(0, PetscRealPart(in) - ub) - PetscMax(0, -PetscRealPart(in) - PetscAbsReal(lb));
4768370d7cdSHansol Suh }
4778370d7cdSHansol Suh
ST_InternalNN(PetscScalar in,PetscReal lb,PetscReal ub)478d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalNN(PetscScalar in, PetscReal lb, PetscReal ub)
479d71ae5a4SJacob Faibussowitsch {
480835f2295SStefano Zampini return PetscMax(0, PetscRealPart(in) + PetscAbsReal(ub)) - PetscMax(0, -PetscRealPart(in) - PetscAbsReal(lb));
4818370d7cdSHansol Suh }
4828370d7cdSHansol Suh
ST_InternalPP(PetscScalar in,PetscReal lb,PetscReal ub)483d71ae5a4SJacob Faibussowitsch static inline PetscReal ST_InternalPP(PetscScalar in, PetscReal lb, PetscReal ub)
484d71ae5a4SJacob Faibussowitsch {
485835f2295SStefano Zampini return PetscMax(0, PetscRealPart(in) - ub) + PetscMin(0, PetscRealPart(in) - lb);
4868370d7cdSHansol Suh }
4878370d7cdSHansol Suh
4888370d7cdSHansol Suh /*@
4898370d7cdSHansol Suh TaoSoftThreshold - Calculates soft thresholding routine with input vector
4908370d7cdSHansol Suh and given lower and upper bound and returns it to output vector.
4918370d7cdSHansol Suh
4928370d7cdSHansol Suh Input Parameters:
4938370d7cdSHansol Suh + in - input vector to be thresholded
4948370d7cdSHansol Suh . lb - lower bound
495f0fc11ceSJed Brown - ub - upper bound
4968370d7cdSHansol Suh
49797bb3fdcSJose E. Roman Output Parameter:
4988370d7cdSHansol Suh . out - Soft thresholded output vector
4998370d7cdSHansol Suh
5008370d7cdSHansol Suh Notes:
5018370d7cdSHansol Suh Soft thresholding is defined as
5028370d7cdSHansol Suh \[ S(input,lb,ub) =
5038370d7cdSHansol Suh \begin{cases}
5048370d7cdSHansol Suh input - ub \text{input > ub} \\
5058370d7cdSHansol Suh 0 \text{lb =< input <= ub} \\
5068370d7cdSHansol Suh input + lb \text{input < lb} \\
5078370d7cdSHansol Suh \]
5088370d7cdSHansol Suh
5098370d7cdSHansol Suh Level: developer
5108370d7cdSHansol Suh
511a1cb98faSBarry Smith .seealso: `Tao`, `Vec`
5128370d7cdSHansol Suh @*/
TaoSoftThreshold(Vec in,PetscReal lb,PetscReal ub,Vec out)513d71ae5a4SJacob Faibussowitsch PetscErrorCode TaoSoftThreshold(Vec in, PetscReal lb, PetscReal ub, Vec out)
514d71ae5a4SJacob Faibussowitsch {
5158370d7cdSHansol Suh PetscInt i, nlocal, mlocal;
5168370d7cdSHansol Suh PetscScalar *inarray, *outarray;
5178370d7cdSHansol Suh
5188370d7cdSHansol Suh PetscFunctionBegin;
5199566063dSJacob Faibussowitsch PetscCall(VecGetArrayPair(in, out, &inarray, &outarray));
5209566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(in, &nlocal));
52184430a0dSHansol Suh PetscCall(VecGetLocalSize(out, &mlocal));
5228370d7cdSHansol Suh
5233c859ba3SBarry Smith PetscCheck(nlocal == mlocal, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Input and output vectors need to be of same size.");
52484430a0dSHansol Suh if (lb == ub) {
52584430a0dSHansol Suh PetscCall(VecRestoreArrayPair(in, out, &inarray, &outarray));
52684430a0dSHansol Suh PetscFunctionReturn(PETSC_SUCCESS);
52784430a0dSHansol Suh }
5283c859ba3SBarry Smith PetscCheck(lb < ub, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Lower bound needs to be lower than upper bound.");
5298370d7cdSHansol Suh
5308370d7cdSHansol Suh if (ub >= 0 && lb < 0) {
5318370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalPN(inarray[i], lb, ub);
5328370d7cdSHansol Suh } else if (ub < 0 && lb < 0) {
5338370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalNN(inarray[i], lb, ub);
5348370d7cdSHansol Suh } else {
5358370d7cdSHansol Suh for (i = 0; i < nlocal; i++) outarray[i] = ST_InternalPP(inarray[i], lb, ub);
5368370d7cdSHansol Suh }
5378370d7cdSHansol Suh
5389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayPair(in, out, &inarray, &outarray));
5393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
5408370d7cdSHansol Suh }
541