1 /****************************************************************
2 Copyright (C) 1997, 2001 Lucent Technologies
3 All Rights Reserved
4 
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name of Lucent or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
13 permission.
14 
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24 
25 #include "asl_pfgh.h"
26 
27  static void
28 #ifdef KR_headers
add_op(H,og0,t)29 add_op(H, og0, t) real *H; ograd *og0; real t;
30 #else
31 add_op(real *H, ograd *og0, real t)
32 #endif
33 {
34 	ograd *og, *og1;
35 	real *Hj, t1;
36 	int j;
37 
38 	for(og = og0; og; og = og->next) {
39 		if ((t1 = t * og->coef)) {
40 			j = og->varno;
41 			Hj = H + ((j*(j+1))>>1);
42 			for(og1 = og0;; og1 = og1->next) {
43 				Hj[og1->varno] += t1*og1->coef;
44 				if (og == og1)
45 					break;
46 				}
47 			}
48 		}
49 	}
50 
51  void
52 #ifdef KR_headers
duthes_ASL(a,H,nobj,ow,y)53 duthes_ASL(a, H, nobj, ow, y) ASL *a; real *H; int nobj; real *ow, *y;
54 #else
55 duthes_ASL(ASL *a, real *H, int nobj, real *ow, real *y)
56 #endif
57 {
58 	/* dense upper triangle of Hessian */
59 	int i, j, n, no, noe;
60 	linarg *la, **lap, **lap1, **lape;
61 	expr_v *v;
62 	range *r, *r0;
63 	real *Hj, *cscale, *owi, *s, *si, t, t1;
64 	ograd *og, *og1;
65 	ps_func *p, *pe;
66 	psg_elem *g, *ge;
67 	ASL_pfgh *asl;
68 
69 	asl = pscheck_ASL(a, "duthes");
70 	xpsg_check_ASL(asl, nobj, ow, y);
71 	if (nobj >= 0 && nobj < n_obj) {
72 		no = nobj;
73 		noe = no + 1;
74 		owi = ow ? ow + no : &edag_one_ASL;
75 		}
76 	else {
77 		nobj = -1;
78 		no = noe = 0;
79 		if ((owi = ow))
80 			noe = n_obj;
81 		}
82 
83 	if (!asl->P.hes_setup_called)
84 		(*asl->p.Hesset)(a, 1, 0, nlo, 0, nlc);
85 	s = asl->P.dOscratch;
86 	n = c_vars >= o_vars ? c_vars : o_vars;
87 	memset(H, 0, (n*(n+1) >> 1) * sizeof(real));
88 
89 	r0 = (range*)&asl->P.rlist;
90 	for(r = asl->P.rlist.next; r != r0; r = r->rlist.next) {
91 		if ((j = r->n) <= 0)
92 			continue;
93 		lap = r->lap;
94 		lape = lap + j;
95 		si = s;
96 		while(lap < lape) {
97 			*si = 1;
98 			pshv_prod_ASL(asl, r, nobj, ow, y);
99 			*si++ = 0;
100 			la = *lap++;
101 			for(og = la->nz; og; og = og->next) {
102 				t = og->coef;
103 				j = og->varno;
104 				Hj = H + ((j*(j+1))>>1);
105 				for(lap1 = r->lap; lap1 < lape; ) {
106 					la = *lap1++;
107 					v = la->v;
108 					if (!(t1 = t * v->aO))
109 						continue;
110 					for(og1 = la->nz;
111 					    og1 && (i = og1->varno) <= j;
112 					    og1 = og1->next)
113 						Hj[i] += t1*og1->coef;
114 					}
115 				}
116 			}
117 		}
118 	if (asl->P.nobjgroups)
119 		for(; no < noe; no++)
120 			if ((t = *owi++)) {
121 				p = asl->P.ops + no;
122 				g = p->g;
123 				for(ge = g + p->ng; g < ge; g++)
124 					if (g->g2)
125 						add_op(H, g->og, t*g->g2);
126 				}
127 	if (asl->P.ncongroups && y) {
128 		cscale = asl->i.lscale;
129 		p = asl->P.cps;
130 		for(pe = p + n_con; p < pe; p++, y++)
131 			if ((t = cscale ? *cscale++ * *y : *y))
132 				for(g = p->g, ge = g + p->ng; g < ge; g++)
133 					if (g->g2)
134 						add_op(H, g->og, t*g->g2);
135 		}
136 	if ((s = asl->i.vscale))
137 		for(i = 0; i < n; i++) {
138 			t = s[i];
139 			for(j = 0; j <= i; j++)
140 				*H++ *= t * s[j];
141 			}
142 	}
143