Esempio n. 1
0
 void
mpec_adjust_ASL(ASL *asl)
{
	MPEC_Adjust *mpa;
	cde *cd;
	cde2 *cd2;
	cgrad **Cgrd, **Cgrd1, **Cgrda, *cg, *cg1, *ncg, **pcg;
	char *hx0;
	int *cc, *ck, *cv, *ind1, *ind2, *map;
	int i, incc, incv, j, k, m, m0, n, n0, n1, n2, nb, ncc, ncc0, nib, nib0;
	int nnv, nz, nz0, nznew, v1, v2, v3, v4;
	real *Lc, *Lc0, *Lc1, *Lv, *Lv0, *Lv1, *Uc, *Uc0, *Uc1, *Uv, *Uv0, *Uv1;
	real a, b, *x;
	extern void f_OPVARVAL_ASL(), f2_VARVAL_ASL();

	n = n0 = n1 = n_var;
	n2 = asl->i.n_var0;
	nib = niv + nbv;
	nib0 = n - nib;	/* offset of first linear integer or binary variable */
	m = m0 = n_con;
	nz = nz0 = nzc;
	cv = cvar;
	Cgrd = Cgrad;
	Cgrd1 = Cgrd + m;
	incc = incv = 1;
	Lc0 = LUrhs;
	if (!(Uc0 = Urhsx)) {
		Uc0 = Lc0 + 1;
		incc = 2;
		}
	Lv0 = LUv;
	if (!(Uv0 = Uvx)) {
		Uv0 = Lv0 + 1;
		incv = 2;
		}
	ncc = ncc0 = n_cc;
	Lc1 = Lc0 + m*incc;
	Uc1 = Uc0 + m*incc;
	Lv1 = Lv0 + n*incv;
	Uv1 = Uv0 + n*incv;

	for(i = k = 0; i < m0; ++i)
		if ((j = cv[i])) {
			++k;
			Lc = Lc0 + incc*i;
			Uc = Uc0 + incc*i;
			nb = (*Lc > negInfinity) + (*Uc < Infinity);
			/* nb == 0 or 1 */
			if (!nb) {
				m += 2;
				n += 4;
				nz += 6;
				++ncc;
				}
			else {
				Lv = Lv0 + incv*(j-1);
				if (*Lv != 0.) {
					++m;
					++n;
					nz += 2;
					}
				/* Even if constraint i has the form v >= 0, */
				/* add a new variable v1 >= 0 and change the */
				/* constraint to v1 = v - rhs, in case v is  */
				/* involved in more than one complementarity */
				++n;
				++nz;
				}
			}
	if (k != ncc0) {
		fprintf(Stderr,
			"\nERROR: mpec_adjust saw %d rather than %d incoming complementarities.\n",
			k, ncc0);
		exit(1);
		}
	n_var = n;
	n_con = m;
	nnv = n - n0;
	if (n_obj)
		adjust_zerograds_ASL(asl, nnv);
	if (n_conjac[1] >= m0)
		n_conjac[1] = m;
	nzc = nz;
	n_cc = ncc;
	nznew = nz - nz0;
	ncg = (cgrad*)M1alloc(2*(ncc + ncc0)*sizeof(int) + nznew*sizeof(cgrad)
			+ ncc0*sizeof(cgrad*) + sizeof(MPEC_Adjust));
	asl->i.mpa = mpa = (MPEC_Adjust*)(ncg + nznew);
	Cgrda = mpa->Cgrda = (cgrad**)(mpa + 1);
	asl->i.ccind1 = ind1 = (int*)(Cgrda + ncc0);
	asl->i.ccind2 = ind2 = ind1 + ncc;
	mpa->cc = cc = ind2 + ncc;
	mpa->ck = ck = mpa->cce = cc + ncc0;
	mpa->m0 = m0;
	mpa->n0 = n0 - nib;
	mpa->rhs1 = Lc1;
	mpa->incc = incc;
	mpa->incv = incv;
	map = get_vcmap_ASL(asl, ASL_Sufkind_var);
	if (n1 < n2) {
		j = n2;
		k = n2 + asl->i.nsufext[ASL_Sufkind_var];
		for(i = n1; i < k; ++i, ++j)
			map[i] = j;
		}
	if (nib) {
		/* Three reverse calls move nib values of map up nnv places. */
		j = n0 - nib;
		reverse(map+j, map + n0 + nnv);
		reverse(map+j, map + j + nnv);
		reverse(map + j + nnv, map + n0 + nnv);
		i = n0 + nnv;
		while(--i >= n0) {
			j = i - nnv;
			Lv0[incv*i] = Lv0[incv*j];
			Uv0[incv*i] = Uv0[incv*j];
			}
		if ((x = X0)) {
			i = n0 + nnv;
			while(--i >= n0)
				x[i] = x[i-nnv];
			for(i = n0 - nnv; i < n0; ++i)
				x[i] = 0.;
			if ((hx0 = havex0)) {
				for(i = n0 + nnv; --i >= n0; )
					hx0[i] = hx0[i-nnv];
				for(i = n0 - nnv;i < n0; ++i)
					hx0[i] = 0;
				}
			}
		Lv1 -= j = incv*nib;
		Uv1 -= j;
		}
	else if ((x = X0)) {
		memset(x + n0, 0, nnv*sizeof(real));
		if ((hx0 = havex0))
			memset(hx0 + n0, 0, nnv);
		}

#define vset(x,y) *x = y; x += incv;
	for(i = 0; i < m0; ++i)
		if ((j = cv[i])) {
			if (j > nib0)
				j += nnv;
			*cc++ = i;
			pcg = &Cgrd[i];
			cg = 0;
			while((cg1 = *pcg))
				pcg = &(cg = cg1)->next;
			*Cgrda++ = cg;
			Lc = Lc0 + incv*i;
			Uc = Uc0 + incc*i;
			Lv = Lv0 + incv*--j;
			Uv = Uv0 + incv*j;
			a = *Lc;
			b = *Uc;
			*ck++ = nb = (a > negInfinity) + (b < Infinity);
			if (nb == 0) {
				/* change L <= v = _svar[j] <= U */
				/* and -Infinity <= body <=  Infinity into */
				/* v1 = v - L >= 0, v2 = U - v >= 0, */
				/* v3 - v4 = body, v3 >= 0, v4 >= 0, */
				/* v1 complements v3, v2 complements v4 */

				*Lc = *Uc = 0.;
				*ind1++ = v1 = n1++;
				*ind1++ = v2 = n1++;
				*ind2++ = v3 = n1++;
				*ind2++ = v4 = n1++;
				for(k = 0; k < 4; ++k) {
					vset(Lv1, 0.);
					vset(Uv1, Infinity);
					}
				ncg[1].varno = n2+3;
				ncg[1].coef = 1.;
				ncg[1].next = 0;
				ncg[0].varno = n2+2;
				ncg[0].coef = -1.;
				ncg[0].next = &ncg[1];
				*pcg = ncg;
				ncg += 2;
				ncg[1].varno = n2;
				ncg[1].coef = -1.;
				ncg[1].next = 0;
				ncg[0].varno = j;
				ncg[0].coef = 1.;
				ncg[0].next = &ncg[1];
				*Lc1 = *Uc1 = *Lv;
				Lc1 += incc;
				Uc1 += incc;
				*Cgrd1++ = ncg;
				ncg += 2;
				ncg[1].varno = n2+1;
				ncg[1].coef = 1.;
				ncg[1].next = 0;
				ncg[0].varno = j;
				ncg[0].coef = 1.;
				ncg[0].next = &ncg[1];
				*Lc1 = *Uc1 = *Uv;
				Lc1 += incc;
				Uc1 += incc;
				*Cgrd1++ = ncg;
				ncg += 2;
				n2 += 4;
				}
			else {
				/*nb == 1*/
				v1 = j;
				if (*Lv != 0.) {
					/* For v = _svar[j], replace */
					/* v >= a with v1 = v - a, v1 >= 0, or */
					/* v <= b with v1 = b - v, v1 >= 0 */
					v1 = n1++;
					vset(Lv1, 0.);
					vset(Uv1, Infinity);
					ncg[1].varno = n2++;
					ncg[1].next = 0;
					ncg[0].varno = j;
					ncg[0].coef = 1.;
					ncg[0].next = &ncg[1];
					if (*Lv > negInfinity) {
						ncg[1].coef = -1.;
						*Lc1 = *Uc1 = *Lv;
						}
					else {
						ncg[1].coef = 1.;
						*Lc1 = *Uc1 = *Uv;
						}
					Lc1 += incc;
					Uc1 += incc;
					*Cgrd1++ = ncg;
					ncg += 2;
					}
				*ind1++ = v1;
				*ind2++ = n1++;
				ncg->varno = n2++;
				ncg->next = 0;
				vset(Lv1, 0.);
				vset(Uv1, Infinity);
				if (*Lv > negInfinity) {
					ncg->coef = -1.;
					*Uc = *Lc;
					}
				else {
					ncg->coef = 1.;
					*Lc = *Uc;
					}
				*pcg = ncg++;
				}
			}
#undef vset
	if ((map = asl->i.cmap)) {
		j = asl->i.n_con0;
		Cgrd1 = asl->i.Cgrad0;
		for(i = m0; i < m; ++i) {
			map[i] = -1;
			Cgrd1[j++] = Cgrd[i];
			}
		}
	i = m0;
	k = m - m0;
	switch(asl->i.ASLtype) {
	  case ASL_read_pfg:
		memset(((ASL_pfg*)asl)->P.cps + m0, 0, k*sizeof(ps_func));
		cd = ((ASL_pfg*)asl)->I.con_de_;
		goto have_cd;
	  case ASL_read_f:
	  case ASL_read_fg:
		cd = ((ASL_fg*)asl)->I.con_de_;
 have_cd:
		while(i < m)
			cd[i++].e = (expr*)&ZeroExpr;
		break;
	  case ASL_read_fgh:
		cd2 = ((ASL_fgh*)asl)->I.con2_de_;
		goto have_cd2;
	  case ASL_read_pfgh:
		memset(((ASL_pfgh*)asl)->P.cps + m0, 0, k*sizeof(ps_func2));
		cd2 = ((ASL_pfgh*)asl)->I.con2_de_;
 have_cd2:
		while(i < m)
			cd2[i++].e = (expr2*)&ZeroExpr;
	  }

	}
Esempio n. 2
0
File: misc.c Progetto: ampl/mp
 int
prob_adj_ASL(ASL *asl)
{
#undef cde
	cde *d, *de;
	cde2 *d2, *d2e;
	cgrad *cg, **pcg, **pcge;
	int flags, k;
#ifndef NO_BOUNDSFILE_OPTION /*{*/
	FILE *f;
	char *bf, buf[4096], *s, *s1, *se;
	int a, i, n1, nr, nv, swap;
	real *L, *U, *x;
	size_t inc, m, n;
#endif /*}*/

	if (n_obj)
		adjust_zerograds_ASL(asl, 0);
	flags = asl->i.rflags;
	asl->i.Cgrad0 = asl->i.Cgrad_;
	if ((k = asl->i.nsufext[ASL_Sufkind_con])) {
		switch(asl->i.ASLtype) {
		  case ASL_read_f:
		  case ASL_read_fg:
			d = ((ASL_fg*)asl)->I.con_de_;
			goto have_d;
		  case ASL_read_fgh:
			d2 = ((ASL_fgh*)asl)->I.con2_de_;
			goto have_d2;
		  case ASL_read_pfg:
			d = ((ASL_pfg*)asl)->I.con_de_;
 have_d:
			d += n_con;
			for(de = d + k; d < de; ++d)
				d->e = (expr*)&Zero;
			break;
		  case ASL_read_pfgh:
			d2 = ((ASL_pfgh*)asl)->I.con2_de_;
 have_d2:
			d2 += n_con;
			for(d2e = d2 + k; d2 < d2e; ++d2)
				d2->e = (expr2*)&Zero;
		  }
		}
	if (flags & (ASL_obj_replace_eq | ASL_obj_replace_ineq))
		obj_adj_ASL(asl);
	if (!A_vals) {
		if (flags & ASL_cc_simplify && n_cc)
			mpec_adjust_ASL(asl);
		if (flags & ASL_rowwise_jac) {
			pcg = Cgrad;
			pcge = pcg + n_con;
			k = 0;
			while(pcg < pcge)
				for(cg = *pcg++; cg; cg = cg->next)
					cg->goff = k++;
			}
		}
	if (n_obj)
		zerograd_chk(asl);
#ifndef NO_BOUNDSFILE_OPTION /*{*/
	if ((bf = asl->i.boundsfile)) {
		if (!(f = fopen(bf, "rb")))
			bad_bounds(asl, "Cannot open boundsfile \"%s\".", bf);
		m = sizeof(buf);
		if ((n = fread(buf, 1, m, f)) < 24
		 || strncmp(buf, "Bounds, x; arith ", 17)) {
 badmagic:
			bad_bounds(asl, "Bad magic in boundsfile \"%s\".", bf);
			}
		a = (int)strtol(s = buf+17, &se, 10);
		if (se <= s || a < 0 || a > 2 || *se >= ' ')
			goto badmagic;
		if (a == 0 && *se == '\r')
			++se;
		if (*se++ != '\n')
			goto badmagic;
		nv = n_var;
		L = LUv;
		if ((U = Uvx))
			inc = 1;
		else {
			U = L + 1;
			inc = 2;
			}
		if (!(x = X0))
			X0 = x = (real*)M1alloc(nv*sizeof(real));
		swap = 0;
		if (a) {
			if (a != Arith_Kind_ASL)
				swap = 1;
			s = buf + 20;
			n1 = *(int*)s;
			if (swap)
				bswap_ASL(&n1, sizeof(n1));
			if (n1 != nv) {
 bad_n1:
				bad_bounds(asl, "Expected %d bounds triples in boundsfile"
					" \"%s\"; got %d.", nv, bf, n1);
				}
			s += sizeof(int);
			se = buf + n;
			for(i = 1; i <= nv; ++i) {
				if (se-s < 3*sizeof(real)) {
					for(s1 = buf; s < se; ++s, ++s1)
						*s1 = *s;
					m = s1 - buf;
					m  += n = fread(s1, 1, sizeof(buf) - m, f);
					se = buf + m;
					if (m < 3*sizeof(real)) {
 too_few:
						bad_bounds(asl, "%d too few bound triples "
							"in boundsfile \"%s\".",
							nv - i + 1, bf);
						}
					s = buf;
					}
				*L = *(real*)s;
				s += sizeof(real);
				*x = *(real*)s;
				s += sizeof(real);
				*U = *(real*)s;
				s += sizeof(real);
				if (swap) {
					bswap_ASL(L, sizeof(real));
					bswap_ASL(x, sizeof(real));
					bswap_ASL(U, sizeof(real));
					}
				if (*L > *U || *x < *L || *x > *U) {
 bad_triple:
					bad_bounds(asl, "bad bound triple %d in bounds file "
						"\"%s\":\n\tL = %.g\n\tx = %.g\n\tU = %.g",
						i, bf, *L, *x, *U);
					}
				L += inc;
				U += inc;
				++x;
				}
			}
		else {
			n1 = (int)strtol(se, &s, 10);
			if (n1 != nv)
				goto bad_n1;
			se = buf + n;
			for(i = 1; i <= nv; ++i) {
				nr = 0;
 tryagain:
				while(s < se && *s <= ' ')
					++s;
				s1 = s;
				for(k = 0; k < 3 && s1 < se; ++k) {
					while(s1 < se && *s1 > ' ')
						++s1;
					while(s1 < se && *s1 <= ' ')
						++s1;
					}
				if (k < 3) {
					if (nr)
						goto too_few;
					for(s1 = buf; s < se; ++s, ++s1)
						*s1 = *s;
					m = sizeof(buf) - (s1 - buf);
					n = fread(s1, 1, m, f);
					se = s1 + n;
					s = buf;
					nr = 1;
					goto tryagain;
					}
				*L = strtod(s, &s1);
				if (s1 <= s || *s1 > ' ') {
 badnumber:
					while(s1 < se && *s1 > ' ')
						++s1;
					bad_bounds(asl, "Bound triple %d: bad number \"%.*s\""
						" in boundsfile \"%s\".", i,
						(int)(s1-s), s, bf);
					}
				*x = strtod(s = s1, &s1);
				if (s1 <= s || *s1 > ' ')
					goto badnumber;
				*U = strtod(s = s1, &s1);
				if (s1 <= s || *s1 > ' ')
					goto badnumber;
				if (*L > *U || *x < *L || *x > *U)
					goto bad_triple;
				L += inc;
				U += inc;
				++x;
				s = s1;
				}
			}
		fclose(f);
		}
#endif /*}*/
	asl->i.err_jmp_ = 0;
	asl->i.rd_M1z_bytes = asl->i.tot_M1z_bytes;
	return 0;
	}