Пример #1
0
void mexFunction( int nlhs, mxArray *plhs[],
		  int nrhs, const mxArray *prhs[] )
{
	int mrows, ncols;
	int        i, j, k;
	double 	*volume;
	double	*matrix;
    extern rational *pivotrow;
    extern T_LassInt *All_index;
    extern T_LassInt *Pivot;
    extern int **p2c;
    extern rational *A;
    extern rational  * planescopy;
    extern T_Tree  *tree_volumes;
    extern T_Key key;

	/* Check for proper number of arguments. */
	if (nrhs != 1)
	{
		mexErrMsgTxt("One input required.");
	} else if (nlhs > 1)
	{
		mexErrMsgTxt("Too many output arguments");
	}

	/* the input must be a non complex m by 4 matrix */
	mrows = mxGetM(prhs[0]);
	ncols = mxGetN(prhs[0]);
	if (ncols != 4 || !mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]))
	{
		mexErrMsgTxt("Input must be a noncomplex m by 4 double matrix");
	}

	/* Set up the return argument matrix */
	plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);

	/* The output goes in *volume */
	volume = mxGetPr(plhs[0]);

	/* Get pointer to the right hand side */
	matrix = mxGetPr(prhs[0]);

	/* Set global variables */
	G_m = mrows;
	G_d = ncols - 1;
	create_hyperplanes (); /* allocates space for hyperplanes */

	/* needs to be changed to read data from the array, or use the array(better) */
	k=0;
	for (i = 0; i < G_m; i++)
    {
		G_Hyperplanes [i] [G_d] = matrix[k++];
	}
	for (i=0; i < G_m; i++)
	{
		G_Hyperplanes [i] [0] = -matrix[k++];
	}
	for (i=0; i < G_m; i++)
	{
		G_Hyperplanes [i] [1] = -matrix[k++];
	}
	for (i=0; i < G_m; i++)
	{
		G_Hyperplanes [i] [2] = -matrix[k++];
	}

	if (G_Storage > G_d - 3)
	  G_Storage = G_d - 3;
	  /* necessary to prevent memory waste because in the tree arrays of length */
	  /* G_Storage + 2 are allocated                                          */

	pivotrow = (rational *) my_malloc ((G_d + 1) * sizeof (rational));
	All_index = (T_LassInt *) my_malloc ((G_m + 1) * sizeof (T_LassInt));
	Pivot = (T_LassInt *) my_malloc ((G_d + 1) * sizeof (T_LassInt));
	p2c = (int **) my_malloc (G_d * sizeof (int *));
	for (i=0; i<G_d; i++){
	   p2c[i] = (int *) my_malloc (2 * sizeof (int));
	}
	A=compact();
	planescopy=compact();
	tree_volumes = NULL;
	create_key (&key, KEY_PLANES_VAR);
	key.hypervar.hyperplanes [0] = G_m + 1;
	key.hypervar.variables [0] = G_d + 1;
	All_index[0]=G_m+2;  /* initialization (end mark) */
	Pivot[0]=G_m+2;	/* initialization (end mark) */
	*volume = lass (A, G_m-1, G_d);

	/* Deallocate memory (didn't work?)*/
	free_key (key, KEY_PLANES_VAR);
	my_free(planescopy, G_m*(G_d+1)*sizeof(rational));
	my_free(A, G_m*(G_d+1)*sizeof(rational));
	for (i=0; i<G_d; i++){
		my_free(p2c[i], 2 * sizeof (int));
	}
	my_free(p2c, G_d * sizeof (int *));
	my_free(Pivot, (G_d + 1) * sizeof (T_LassInt));
	my_free(All_index,(G_m + 1) * sizeof (T_LassInt));
	my_free(pivotrow, (G_d + 1) * sizeof (rational));
	free_hyperplanes ();
}
Пример #2
0
static rational lass(rational *A, int LastPlane_, int d)
/* A has exact dimension (LastPlane_+1)*(d+1). The function returns
   the volume; an underscore is appended to LastPlane_ and d */

{   rational * redA;            /* A reduced by one dimension and constraint */
    int i, j;
    T_LassInt baserow = 0, basecol = 0, col;
    int dimdiff, row;         /* dimension difference */
    boolean store_volume;
    boolean i_balance = FALSE;
    rational ma, mi, *volume, *realp1, *realp2;
    int Index_needed;         /* Boolean, if index operations are needed */
    T_LassInt * Del_index = NULL; /* contains the indices of the deleted planes */

    /* test if volume is already known and return it if so */

    dimdiff = G_d-d;
    if ((G_Storage > (dimdiff-2)) && (dimdiff >= 2)) {
        tree_out (&tree_volumes, &i_balance, key, &volume, &keyfound, KEY_PLANES_VAR);
        if ((*volume)>=0)  {  /* this volume has already been computed */
	    #ifdef STATISTICS
		Stat_CountRetrieved [d] ++;
	    #endif
	    return (*volume)*scale(dimdiff, 
	                           keyfound->hypervar.variables,
				   key.hypervar.variables);
	}
        (*volume)=0;      /* initialize */
        store_volume=TRUE;
        #ifdef STATISTICS
           Stat_CountStored [d] ++;
        #endif
    }
    else store_volume=FALSE;

    /* if d==1 compute the volume and give it back */

    if (d == 1) {
	ma=-MAXIMUM;
	mi= MAXIMUM;
	for (i=0; i<=LastPlane_; i++,A+=2) { 
	    if (*A>EPSILON_LASS) { if ((*(A+1)/ *A)<mi) mi=(*(A+1)/ *A); }
	    else if (*A<-EPSILON_LASS) { if ((*(A+1)/ *A)>ma) ma=*(A+1)/ *A; } 
            else if ((*(A+1))<-(100000*EPSILON_LASS)) return 0; 
	}
	if ((ma<-.5*MAXIMUM)||(mi>.5*MAXIMUM)) {
	    printf("\nVolume is unbounded!\n");
	    exit(0);
	}
	if ((mi-ma)>EPSILON_LASS) {
	    if (store_volume) (*volume)=mi-ma;
	    return mi-ma;
	}
	return 0;
    }

    /* if d>1 apply the recursive scheme by fixing constraints. */

    Index_needed = (G_Storage>(G_d-d-1));
    if (Index_needed){
	if (!(Del_index = (T_LassInt *) my_malloc ((LastPlane_ + 2) * sizeof (T_LassInt)))){
	    fprintf (stderr, "\n***** ERROR/WARNING: Out of memory in 'lass'\n");
	    exit(0);
	};
        Del_index[0]=G_m+2;   /* initialize: mark end */
    }
    ma=0;                                         /* used to sum up the summands */
    if (norm_and_clean_constraints(A, &LastPlane_, d, Del_index, Index_needed)!=0)
        goto label2;

    /* if appropriate shift polytope */

    if (d>=LaShiftLevel) {
	realp1=A+d;
	realp2=realp1+LastPlane_*(d+1);
	j=0;
	while (realp1<=realp2) {
	    if (fabs(*realp1)<EPSILON_LASS) j++;
	    realp1+=d+1;
	}
	if (d-j>=LaShift) shift_P(A, LastPlane_, d);
    }


    redA = (rational *) my_malloc (LastPlane_* d*sizeof(rational));
    if (redA == NULL) {
	fprintf (stderr, "\n***** ERROR/WARNING: Out of memory in 'lass.*redA'\n");
	exit(0);
    }
#ifdef ReverseLass
    for (row=LastPlane_; row>=0; row--) {
#else
    for (row=0; row<=LastPlane_; row++) {
#endif
	if (fabs(*(A+row*(d+1)+d))<EPSILON_LASS) 
            continue;                        /* skip this constraint if b_row == 0 */
	if (Index_needed)
	{  baserow=add_reduced_index(row, NULL, All_index);
           p2c[G_d-d][1] = baserow;
	   add_hypervar (baserow, G_d+1, &key);
	}	
	memcpy(&pivotrow[0], A+row*(d+1), sizeof(rational)*(d+1));
	col=0;                               /* search for pivot column */
	for (i=0; i<d; i++) {        
#if PIVOTING_LASS == 0
	    if (fabs(pivotrow[i])>=MIN_PIVOT_LASS) {col=i; break;};
#endif
	    if (fabs(pivotrow[i])>fabs(pivotrow[col])) col=i;
	};
	if (G_Storage>(G_d-d-1))
	{  basecol=add_reduced_index(col, NULL, Pivot);
           p2c[G_d-d][0] = basecol;
	   add_hypervar (G_m+1, basecol, &key);
	}

        /* copy A onto redA and at the same time perform pivoting */
	 
	mi=1.0/pivotrow[col];
	for (i=0; i<=d; i++) pivotrow[i]*=mi;
	realp1=A;
	realp2=redA;
	for (i=0; i<=LastPlane_; i++) {
	    if (i==row) {
		realp1+=d+1;
		continue;
	    };
	    mi=*(A+(i*(d+1))+col);
	    for (j=0; j<=d; j++) {
		if (j==col) {
		    realp1++;
		    continue;
		};
		*realp2=(*realp1)-pivotrow[j]*mi;
		realp1++;
		realp2++;
	    };
	};
	ma+= *(A+row*(d+1)+d)/(d*fabs(*(A+row*(d+1)+col)))
	     *lass(redA, LastPlane_-1, d-1);
        if (Index_needed)
        {  rm_original_inElAll_index(baserow);
           delete_hypervar (baserow, G_d+1, &key);
        }
	if (G_Storage>(G_d-d-1))
	{  del_original(basecol, Pivot);
	   delete_hypervar (G_m+1, basecol, &key);
	}
        #ifdef verboseFirstLevel
            if (d==G_d) 
	        printf("\nVolume accumulated to iteration %i is %20.12f",row,ma );
        #endif
    };
    my_free (redA, LastPlane_* d * sizeof (rational));
    label2: 
    if (Index_needed) {
	del_original_indices(Del_index, All_index);
        my_free (Del_index, (LastPlane_ + 2) * sizeof (T_LassInt));
    };
    if (store_volume)(*volume)=ma;
    return ma;
}

/****************************************************************************************/

void volume_lasserre_file (rational *volume, char *planesfile)

{  int i;

   read_hyperplanes (planesfile);
   if (G_m > 254)
   {  fprintf (stderr, "\n***** ERROR: Trying to use 'rlass' with more than 254 hyperplanes.");
      fprintf (stderr, "\nThis restriction can be changed, though. Please contact the authors.\n");
      exit (0);
   }
   if (G_Storage > G_d - 3)
      G_Storage = G_d - 3;
      /* necessary to prevent memory waste because in the tree arrays of length         */
      /* G_Storage + 2 are allocated                                                    */

   pivotrow = (rational *) my_malloc ((G_d + 1) * sizeof (rational));
   All_index = (T_LassInt *) my_malloc ((G_m + 1) * sizeof (T_LassInt));
   Pivot = (T_LassInt *) my_malloc ((G_d + 1) * sizeof (T_LassInt));
   p2c = (int **) my_malloc (G_d * sizeof (int *));
   for (i=0; i<G_d; i++){
       p2c[i] = (int *) my_malloc (2 * sizeof (int));
   }
   A=compact();
   planescopy=compact();
   tree_volumes = NULL;
   create_key (&key, KEY_PLANES_VAR);
   key.hypervar.hyperplanes [0] = G_m + 1;
   key.hypervar.variables [0] = G_d + 1;
   All_index[0]=G_m+2;  /* initialization (end mark) */
   Pivot[0]=G_m+2;	/* initialization (end mark) */
#ifdef STATISTICS
   init_statistics ();
#endif
   *volume = lass (A, G_m-1, G_d);

/*
   free_key (key, KEY_PLANES_VAR);
*/
}