Beispiel #1
0
/* The main function: pivot */
ptrdiff_t  Basis_Pivot(PT_Basis pB, PT_Matrix pA, ptrdiff_t enter, ptrdiff_t leave)
{
	ptrdiff_t m, nW, Wl, c, r;
	PT_Index pW, pZ, pWc;
	PT_Matrix pG, pX, pF;
	ptrdiff_t left;

	/* abbreviations */
	pW  = pB->pW;
	pWc = pB->pWc;
	pZ  = pB->pZ;
	pG  = pB->pG;
	pX = pB->pX;
	pF = pB->pF;

	/* get dimensions */
	m   = Matrix_Rows(pA);
	nW  = Index_Length(pW);

	/* determine the leaving variable */
	if(leave < Index_Length(pW))
	{
		left = Index_Get(pW,leave);
	}
	else
	{
		left = Index_Get(pZ,leave-Index_Length(pW))+m;
	}
  
/*   printf("\n ---------------------------------------\n"); */
/*   printf("enter = %ld, leave = %ld\n", enter, leave); */
  
	/* Four cases */
	if(enter < m)
	{
		/* r = find(B.Wc == enter) */
		r = Index_FindElement(pWc, enter);

		if(leave < nW)
		{
			/* printf("case 1:\n"); */
			Wl = Index_Get(pW,leave);

			/* G_l,* = M_e,Z */
			/* Basis_Print(pB); */
			/* Update matrix G with the row corresponding to the entering variable */
			Matrix_GetRow(pA, pB->y, enter, pZ);
			Matrix_ReplaceRow(pG, leave, pB->y);

			/* X_r,* = M_Wl,Z */
			/* Update matrix X with the row corresponing to the leaving variable 
			   from index set pW. Similarly, we must update matrix F as its gets overwritten
			   by dgesv routine.   */
			Matrix_GetRow(pA, pB->y, Wl, pZ);
			Matrix_ReplaceRow(pF, r, pB->y);      
			Matrix_ReplaceRow(pX, r, pB->y);
			/* smart update with LUmod */
			LU_Replace_Row(pB->pLX, pB->pUX, r, pB->y, pB->z, pB->w);

			/* Wc_r = Wl, W_l = e */
			/* update index sets */
			Index_Replace(pWc, r, Wl);
			Index_Replace(pW,  leave, enter);

		}
		else /* leave >= nW */
		{
			/* printf("case 2:\n"); */
			Index_Add(pW,enter);
			c = leave-nW;

			/* Replace row r and column c with the last row and column of X
			   and remove last row/column. */
			Matrix_RemoveRow(pX,r);
			Matrix_RemoveCol(pX,c);
			/* We must update matrix F as well */
			Matrix_RemoveRow(pF,r);
			Matrix_RemoveCol(pF,c);
			/* smart update with LUmod */
			LU_Shrink(pB->pLX, pB->pUX, r, c, pB->y, pB->z, pB->w);

			/* Update indices */
			Index_Remove(pWc, r);
			Index_Remove(pZ,  c);

			/* Update G matrix */
			Matrix_RemoveCol(pG, c);
			Matrix_GetRow(pA, pB->y, enter, pZ);
			Matrix_AddRow(pG, pB->y);
		}
	}
	else /* enter >= m */
	{
		if(leave < nW)
		{
			/* printf("case 3:\n"); */
			Wl = Index_Get(pW,leave);

			/* Add row Wl and column e-m to X */
			if(Index_Length(pZ) > 0)
			{
				Matrix_GetRow(pA, pB->y, Wl, pZ);
				Matrix_GetCol(pA, pB->z, pWc, enter-m);
			}
			pB->y[Index_Length(pZ)] = C_SEL(pA,Wl,enter-m);

			/* updating F */
			Matrix_AddCol(pF, pB->z);
			Matrix_AddRow(pF, pB->y);

			/* updating X */
			Matrix_AddCol(pX, pB->z);
			Matrix_AddRow(pX, pB->y);
			/* update with LUmod */
			LU_Expand(pB->pLX, pB->pUX, pB->y, pB->z, pB->w);

			/* printf("pX col=\n"); */
			/* Matrix_Print_col(pX); */
     
			/* Remove row Wl from G */
			/* and add column e-m */
			Matrix_RemoveRow(pG, leave);
			Index_Remove(pW, leave);

			Matrix_GetCol(pA, pB->z, pW, enter-m);
			Matrix_AddCol(pG, pB->z);

			/* Extend Wc and Z */
			Index_Add(pWc, Wl);
			Index_Add(pZ, enter-m);

		}
		else /* leave >= nW */
		{
			/* printf("case 4:\n"); */
			/* Replace column */
			c = leave - nW;

			/* G_*,c = M_w,(e-m) */
			Matrix_GetCol(pA, pB->y, pW, enter-m);
			Matrix_ReplaceCol(pG, c, pB->y);

			/* X_*,c = M_Wc,(e-m) */
			Matrix_GetCol(pA, pB->z, pWc, enter-m);

			/* Vector_Print_raw(pB->z,m); */
			/* Basis_Print(pB); */

			/* update matrices X, F by replacing column */
			Matrix_ReplaceCol(pX, c, pB->z);
			Matrix_ReplaceCol(pF, c, pB->z);
			/* update for LUmod */
			LU_Replace_Col(pB->pLX, pB->pUX, c, pB->y, pB->z, pB->w);

			/* Update Z */
			Index_Replace(pZ, c, enter-m);
		}
	}

	/* create column-wise upper triangular matrix Ut from U*/
	Matrix_Triu(pB->pUt, pB->pUX, pB->r);

	return left;
}
Beispiel #2
0
/* If something goes wrong, returned value contains LCP_flag (negative values). */
ptrdiff_t LexMinRatio(PT_Basis pB, PT_Matrix pA, double *v, T_Options options)
{
	ptrdiff_t m, i, j, k, incx, info;
	PT_Index pP;
	double *rat, *q;
	double minrat=0.0, alpha;

	m   = Matrix_Rows(pA);
	pP  = pB->pP;
	rat = pB->y;
	q   = pB->w;

	/* used to obtain an identity matrix in lex-pivot operation */
	alpha = 0.0;
	/* increment of each vectors is 1 */
	incx = 1;
  
	/* Compute the index set of positive v s */
	Index_Length(pP) = 0;
	for (j=0, i=0;i<m;i++)
	{
		if ( v[i] > options.zerotol )
		{
			Index_Add(pP, i);
			/* The positive elements of 1/v are now the first |pP| elements */ 
			v[j++] = v[i];
		}
	}

	if(Index_Length(pP) == 0) /* Problem infeasible */
		return LCP_INFEASIBLE;

	/* q = A(:,m+1) */
	memcpy(q,&(C_SEL(pA, 0, m+1)),m*sizeof(double));
	
        for (i=0; i<m+1; i++)
	 {	
		/* Basis_Print(pB); */
		/* Index_Print(pP); */

		/* rat = iB*q */
		info = Basis_Solve(pB, q, rat, options);
		if (info!=0)  {
#ifdef MATLAB_MEX_FILE
		  if (options.verbose) {
		    printf("Numerical problems with Basis_Solve in LexRatio.\n");
		  }
#endif
			return LCP_CODEERROR;
		}	

		/* printf("q after Basis_Solve in LexRatio=\n"); */
		/* Vector_Print_raw(q,m); */

		/* rat = rat(pP) / v(pP) */
		/* find minimum ratio */
		minrat = rat[Index_Get(pP,0)]/v[0];
		for (j=0; j<Index_Length(pP); j++) {
			rat[j] = rat[Index_Get(pP,j)]/v[j];
			if (rat[j] < minrat) {
				minrat = rat[j];
			}
		}
		/* printf("minrat=%lf\n",minrat); */
		/* printf("Ratio vector after=\n"); */
		/* Vector_Print_raw(rat,m); */

		/* printf("positive index set:\n"); */
                /* Index_Print(pP); */
    
		/* remove all indices that are greater than the minumum ratio with some tolerance */
		/* Move all elements equal to minrat to the start of the list */
		for (k=0, j=0;j<Index_Length(pP);j++)
		{
			/* printf("j=%ld, fabs(minrat - rat[lndex_Get(pP,j)]) = %f\n", j, fabs(minrat - rat[Index_Get(pP,j)])); */
			if (fabs(minrat - rat[j]) < options.lextol) {
				Index_Set(pP,k,Index_Get(pP,j));
				/*pP is now a set of indices with equal ratio */
				v[k++] = v[j];
			} 
		}
		pP->len = k;
		/* printf("new index set:\n"); */
                /* Index_Print(pP); */

		if(Index_Length(pP) <= 0) {
			/* Vector_Print_raw(v,m); */
			/* Vector_Print_raw(rat,m); */
			/* mexPrintf("minrat = %lf, length(pP)  = %ld\n",minrat,Index_Length(pP)); */
			/* Index_Print(pP); */
            #ifdef MATLAB_MEX_FILE
		  if (options.verbose) {
			printf("Numerical problems with finding lexicographic minimum. You can refine this using the 'lextol' feature in options.\n");
		  }
            #endif
			return LCP_CODEERROR;
		}

		if(Index_Length(pP) > 1)
		{
			/* printf("Taking lex-pivot\n"); */
			/* Need to make a lex-comparison */
			/* q = 0*q */
			dscal(&m, &alpha, q, &incx);
			q[i] = 1.0;
		}
		else
		{
			return Index_Get(pP,0);
		}
	 }

	/* if the lex-pivot failed, pick the largest element from v_i vector i=0, ..., k */
	return Index_Get(pP, idamax(&k, v, &incx)-1);

	/* mexErrMsgTxt("Did not find a lex-min. This should be impossible."); */
	/* return LCP_INFEASIBLE; */
}