Beispiel #1
0
void SimplexLP::GetPenaltyEstimates( Real_T &MinM, Real_T &MaxM )
{
	//--------------------------------------------------------------------------
	//	Estimate the minimum penalty.
	//
	MaxM = -INFINITY;	// "Guarantees" that the problem will not be unbounded.
	MinM = +INFINITY;	// Guarantees that the problem will be unbounded.

	Ptr<Real_T> a;
	Ptr<Int_T> row;
	Int_T j, len, nn = GetStructN();

	for( j = 0; j < nn; j++ )
	{
		Real_T x = 0.0;

		for( GetColumn( j, a, row, len ); len; --len, ++a, ++row )
			if( ! ( LambdaVT[ *row ] & VT_FX ) )
				x += Lambda[ *row ] * *a;

		if( IsNonZero( x ) )
		{
			x = GetC( j ) / x;

			if( MaxM < x ) MaxM = x;
			if( MinM > x ) MinM = x;
		}
	}
}
Beispiel #2
0
void SimplexLP::ShiftLowerBoundsToZero( void )
{
	//--------------------------------------------------------------------------
	//	Shift lower bounds to zero (where possible, i.e. where the lower bounds
	//	are finite. Adjust the finite upper bound on variable as well as the
	//	value of the objective function fixed adjustment accordingly.
	//
	Int_T i, nn = GetN(), len;
	Ptr<Real_T> a;
	Ptr<Int_T> row;

	for( i = 0; i < nn; i++ )
	{
		Real_T ll = GetL( i );
		Bool_T up = ( GetVarType( i ) & VT_HAS_LO_BND ) ? True : False;

		if( up && IsNonZero( ll ) )
		{
			for( MPS_LP::GetColumn( i, a, row, len ); len; --len, ++a, ++row )
				b[ *row ] -= *a * ll;

			if( up ) u[i] -= ll;

			f += GetC( i ) * ll;
		}
	}
}
Beispiel #3
0
void SimplexLP::CreateLambda( const Array<Real_T> &v )
{
	Lambda.Resize( m );		Lambda.Fill( 1.0, m );
	LambdaVT.Resize( m );	LambdaVT.Fill( VT_FIXED | VT_ARTIF, m );

	for( Int_T i = 0; i < m; i++ )
		if( IsNonZero( v[i] ) )
		{
			if( v[i] < 0.0 ) Lambda[i] = -1.0;

			LambdaVT[i]	= VT_LO | VT_ARTIF;
		}
}
Beispiel #4
0
void SimplexLP::ProcessSolution( Solution &sol )
{
	Array<Real_T> &x	= sol.x;

	int contents = sol.GetContents();

	assert( !( contents & Solution::Primal ) || sol.GetN() == n );
	assert( !( contents & Solution::Dual ) || sol.GetM() == m );

	if( Standard && ( contents & Solution::Primal ) )
		for( Int_T j = 0; j < n; j++ )
			if( VarType[j] & VT_HAS_LO_BND && IsNonZero( l[j] ) )
				x[j] += l[j];

	SolvableLP::ProcessSolution( sol );
}
Beispiel #5
0
void SimplexLP::UndoStandard( void )
{
	//--------------------------------------------------------------------------
	//	Restore the original positions of the lower bounds.
	//
	Int_T i, len;
	Ptr<Real_T> a;
	Ptr<Int_T> row;

	for( i = 0; i < n; i++ )
	{
		Real_T ll = GetL( i );
		Bool_T up = ( GetVarType( i ) & VT_HAS_LO_BND ) ? True : False;

		if( up && IsNonZero( ll ) )
		{
			for( MPS_LP::GetColumn( i, a, row, len ); len; --len, ++a, ++row )
				b[ *row ] += *a * ll;

			if( up ) u[i] += ll;
		}
	}
}
Beispiel #6
0
void RD_SubproblemSolver::GetFeasibilityCut( Real_T &value, Real_T *grad, // )
	Int_T n, const Scenario &Scen )
{
	assert( grad != NULL );

	//--------------------------------------------------------------------------
	//	Here we generate a feasibility cut. For that purpose we need to know
	//	which row of the constraint matrix was most infeasible and what was the
	//	infeasibility.
	//

	//
	//	Find the most violated constraint corresponding to a non-zero basic
	//	artificial variable. Put the index in 'infrow'.
	//
	Int_T infrow = -1;
	value = 0.0;

	for( Int_T j = Int_T( LP.GetStructN() + LP.GetSlackN() ); j < N; j++ )
		if( VarType[j] & VT_ARTIF && x[j] > FEASIBILITY_TOL )
			if( x[j] > value && A2B[j] >= 0 )
			{
				infrow = A2B[j];
				value = x[j];
			}

	//
	//	It is possible that the problem is infeasible, but all artificial
	//	variables (some of them have non-zero values) are non-basic. In such
	//	case a dual optimal solution to the first stage problem ('y_t') is
	//	used to generate the cut.
	//
	if( infrow < 0 )
	{
#ifndef NDEBUG
		Bool_T found = False;

		for( Int_T i = 0; i < M; i++ )
			if( IsNonZero( y_t[i] ) )
			{
				found = True;
				break;
			}
		if( !found )
			FatalError( "Internal error when generating a feasibility cut." );
#endif
		for( Int_T j = Int_T( LP.GetStructN() + LP.GetSlackN() ); j < N; j++ )
			value += fabs( x[j] );
		CalculateGradient( grad, n, y_t, Scen );
	}
	else
	{
		//----------------------------------------------------------------------
		//	Extract the appropriate row of the basis inverse into "pi" vector.
		//	Use "mark" work vector as a work space for sparsity pattern.
		//
		WorkVector<Real_T> pi( M );
		WorkVector<Int_T> mark( M );

		pi.Fill( 0.0, M );	mark.Fill( 0, M );
		pi[ infrow ] = 1.0;	mark[ infrow ] = 1;
		B->SparseBTRAN( pi, mark );

		CalculateGradient( grad, n, pi, Scen );
	}
}
Beispiel #7
0
void mexFunction(int nlhs,       mxArray *plhs[],
		 int nrhs, const mxArray *prhs[])
{
    /* Declare variables */ 
    size_t elements;
    mwSize j,cmplx;
    mwSize number_of_dims;
    mwSize nnz=0, count=0; 
    double *pr, *pi, *pind;
    const mwSize *dim_array;         
    
    /* Check for proper number of input and output arguments */    
    if (nrhs != 1) {
        mexErrMsgIdAndTxt( "MATLAB:findnz:invalidNumInputs",
                "One input argument required.");
    }
    if (nlhs > 1){
        mexErrMsgIdAndTxt( "MATLAB:findnz:maxlhs",
                "Too many output arguments.");
    }

    /* Check data type of input argument */
    if (!(mxIsDouble(prhs[0]))) {
        mexErrMsgIdAndTxt( "MATLAB:findnz:invalidInputType",
                "Input array must be of type double.");
    }
    
    /* Get the number of elements in the input argument */
    elements=mxGetNumberOfElements(prhs[0]);
   
    /* Get the data */
    pr=(double *)mxGetPr(prhs[0]);
    pi=(double *)mxGetPi(prhs[0]);
    cmplx = ((pi==NULL) ? 0 : 1);

    /* Count the number of non-zero elements to be able to allocate
     * the correct size for output variable */
    for(j=0;j<elements;j++){
        if(IsNonZero(pr[j]) || (cmplx && IsNonZero(pi[j]))) {
            nnz++;
        }
    }
	
    /* Get the number of dimensions in the input argument. Allocate the
       space for the return argument */
    number_of_dims=mxGetNumberOfDimensions(prhs[0]);
    plhs[0]=mxCreateDoubleMatrix(nnz,number_of_dims,mxREAL);
    pind=mxGetPr(plhs[0]);
	
    /* Get the number of dimensions in the input argument. */
    dim_array=mxGetDimensions(prhs[0]);

    /* Fill in the indices to return to MATLAB. This loops through the
     * elements and checks for non-zero values. If it finds a non-zero
     * value, it then calculates the corresponding MATLAB indice and
     * assigns them into the output array.  The 1 is added to the
     * calculated indice because MATLAB is 1 based and C is zero
     * based. */
    for(j=0;j<elements;j++) {
        if(IsNonZero(pr[j]) || (cmplx && IsNonZero(pi[j]))) {
            mwSize temp=j;
            mwSize k;
            for (k=0;k<number_of_dims;k++){
                pind[nnz*k+count]=(double)((temp % (dim_array[k])) +1);
                temp/=dim_array[k];
            }
            count++;
        }
    }
}
Beispiel #8
0
 /**
  * Returns true if the norm of the vector is zero.
  */
 constexpr bool IsZero() const {
   return !IsNonZero();
 }
Beispiel #9
0
void Presolver::Presolve( const int Mode, VerbLevel Verbosity )
{
	if( !Mode ) return;

	if( Verbosity >= V_HIGH )
	{
		Print( "\nPRESOLVER INVOKED:\n" );
		if( Mode & LPR_ALL )
		{
			Print( "\tThe following presolve techniques activated:\n" );
			if( Mode & LPR_EMPTY_ROWS )
				Print( "\t\tempty column removal\n" );
			if( Mode & LPR_EMPTY_COLS )
				Print( "\t\tempty row removal\n" );
			if( Mode & LPR_ORIG_FIXED )
				Print( "\t\tfixed variable removal\n" );
			if( Mode & LPR_NUM_ELIM )
				Print( "\t\tnumerical eliminations\n" );
			if( Mode & LPR_SINGL_ROWS )
				Print( "\t\tsingleton row reduction\n" );
			if( Mode & LPR_SINGL_COLS )
				Print( "\t\tfree singleton column reduction\n" );
			if( Mode & LPR_FORC_DOM_CONSTR )
				Print( "\t\tforcing and dominated row detection\n" );
			if( Mode & LPR_DOM_COLS )
				Print( "\t\tdominated and weakly dominated column removal\n" );
			if( Mode & LPR_EXPLICIT_SLACKS )
				Print( "\t\texplicit slack removal\n" );
		}
		else
		{
			Print( "\tNo presolve techniques activated. Exiting." );
			return;
		}
	}

	InitializePresolverData();

	Bool_T Elim;
	Int_T ElNum = 0;

	if( Mode & LPR_ORIG_FIXED )
		if( ( OrigFixedVars = EliminateFixedVariables() ) != 0 )
			if( Verbosity >= V_HIGH )
				Print( "\tFound %d fixed variables in original problem.\n",
					(int) OrigFixedVars );

	do
	{
		Elim = False;

		if( Mode & LPR_SINGL_ROWS )
		{
			if( ( ElNum = EliminateSingletonRows() ) != 0 )
			{
				if( Verbosity >= V_HIGH )
					Print( "\tFound %d singleton rows.\n", (int) ElNum );
				Elim = True;
			}
			if( Status != LPS_UNKNOWN ) break;
		}

		if( Mode & ( LPR_SINGL_COLS | LPR_EXPLICIT_SLACKS ) )
		{
			if( ( ElNum = DealWithSigletonColumns( Mode ) ) != 0 )
			{
				if( Verbosity >= V_HIGH )
					Print( "\tConverted %d singleton columns.\n",
						(int) ElNum );
				Elim = True;
			}
			if( Status != LPS_UNKNOWN ) break;
		}

		if( Mode & LPR_FORC_DOM_CONSTR )
		{
			if( ( ElNum = ForcingAndDominatedRows() ) != 0 )
			{
				if( Verbosity >= V_HIGH )
					Print( "\tFound %d rows forcing or dominated.\n",
						(int) ElNum );
				Elim = True;
			}
			if( Status != LPS_UNKNOWN ) break;
		}

		if( !Elim && ( Mode & LPR_NUM_ELIM ) )
		{
			if( ( ElNum = NumericalEliminations( 100.0 ) ) != 0 )
			{
				if( Verbosity >= V_HIGH )
					Print( "\tEliminated %d non-zeros.\n", (int) ElNum );
				Elim = True;
			}
			if( Status != LPS_UNKNOWN ) break;
		}

	} while( Elim );

	if( Mode & LPR_EMPTY_ROWS && ( ElNum = EliminateEmptyRows() ) != 0 &&
		Verbosity >= V_HIGH )
		Print( "\tFound %d empty rows.\n", (int) ElNum );

	if( Mode & LPR_EMPTY_COLS && ( ElNum = EliminateEmptyColumns() ) != 0 &&
		Verbosity >= V_HIGH )
		Print( "\tFound %d empty columns.\n", (int) ElNum );

	if( PostSolve && IsNonZero( f ) )
		PostSolve->FixedAdjustment( f );

	//--------------------------------------------------------------------------
	{
		Int_T nzc = 0;
		for( Int_T j = 0; j < n; j++ )
			if( !ExcludeCols[j] )
				nzc += ColLen[j];

#ifndef NDEBUG
		Int_T nzr = 0;
		for( Int_T i = 0; i < m; i++ )
			if( !ExcludeRows[i] )
				nzr += RowLen[i];
		assert( nzc == nzr );
#endif

		EliminatedNonZeros = Int_T( LP.GetNZ() - nzc );
	}

	//--------------------------------------------------------------------------
	//	Restore the right-hand-side and range vector from "bl" and "bu" vector
	//	pair.
	//
	BLU2RHS();
	UpdateLP_AfterReductions();

	//--------------------------------------------------------------------------
	//	Set problem status to solved if the dimensions have been reduced to
	//	zero.
	//
	EliminatedRows += ForcingRows;
	if( EliminatedRows == m && EliminatedCols == n &&
		EliminatedNonZeros == LP.GetNZ() )
		Status = LPS_SOLVED;

	//--------------------------------------------------------------------------
	//	Report on the presolver activity. Special (short) note if no reductions
	//	were obtained.
	//
	if( Verbosity >= V_LOW )
	{
		if( EliminatedRows || EliminatedCols || EliminatedNonZeros )
			Print(
				//----------------------------------------------------------
				//	Format string.
				//
				"\nElimination statistics:\n"
				"\tTotals:\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%20.12E\n"

				"\tSingleton column analysis:\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"

				"\tRow analysis:\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"
				"\t\t%-25s%10d\n"

				"\tInfeasibility\n"
				"\t\t%-25s%10G\n"
				"\t\t%-25s%10G\n",

				//----------------------------------------------------------
				//	Data.
				//
				"Original fixed variables",	(int) OrigFixedVars,
				"Eliminated rows:",			(int) EliminatedRows,
				"Eliminated columns:",		(int) EliminatedCols,
				"Eliminated non-zeros:",	(int) EliminatedNonZeros,
				"Fixed adjustment:",		(double) f,

				"Original free singletons:",(int) OrigFreeSingletonCols,
				"Implied free variables:",	(int) ImpliedFreeSingletonCols,
				"Relaxed constraints:",		(int) RelaxedConstraints,

				"Forcing rows:",			(int) ForcingRows,
				"Dominated rows:",			(int) DominatedRows,
				"Tightened bounds:",		(int) VariableBoundsTightened,
				"Primal:",					(double) PrimalInf,
				"Dual:",					(double) DualInf
			);
		else
			Print( "The problem was not reduced.\n" );
	}
	else if( Verbosity >= V_LINE )
	{
		Print(
			//----------------------------------------------------------
			//	Format string.
			//
			" %10d | %10d | %10d | %10d | %10d | %10d | %10d | %10d |",

			//----------------------------------------------------------
			//	Data.
			//
			(int) EliminatedRows,
			(int) EliminatedCols,
			(int) EliminatedNonZeros,

			(int) OrigFreeSingletonCols,
			(int) ImpliedFreeSingletonCols,
			(int) RelaxedConstraints,

			(int) ForcingRows,
			(int) DominatedRows
		);
	}

	//--------------------------------------------------------------------------
	//	If the problem's status changed, display information.
	//
	switch( Status )
	{
	case LPS_UNKNOWN:
		break;

	case LPS_INFEASIBLE:
		if( Verbosity >= V_LOW )
			Print( "Problem is infeasible.\n" );
		break;

	case LPS_UNBOUNDED:
		if( Verbosity >= V_LOW )
			Print( "Problem is unbounded.\n" );
		break;

	case LPS_SOLVED:
		if( Verbosity >= V_LOW )
			Print( "Problem is solved.\n" );
		break;
	}
}
Beispiel #10
0
void mexFunction(
		 int nlhs,       mxArray *plhs[],
		 int nrhs, const mxArray *prhs[]
		 )
{
    /* Declare variable */
    mwSize m,n;
    mwSize nzmax;
    mwIndex *irs,*jcs,j,k;
    int cmplx,isfull;
    double *pr,*pi,*si,*sr;
    double percent_sparse;
    
    /* Check for proper number of input and output arguments */
    if (nrhs != 1) {
        mexErrMsgIdAndTxt( "MATLAB:fulltosparse:invalidNumInputs",
                "One input argument required.");
    }
    if(nlhs > 1){
        mexErrMsgIdAndTxt( "MATLAB:fulltosparse:maxlhs",
                "Too many output arguments.");
    }
    
    /* Check data type of input argument  */
    if (!(mxIsDouble(prhs[0]))){
        mexErrMsgIdAndTxt( "MATLAB:fulltosparse:inputNotDouble",
                "Input argument must be of type double.");
    }
    
    if (mxGetNumberOfDimensions(prhs[0]) != 2){
        mexErrMsgIdAndTxt( "MATLAB:fulltosparse:inputNot2D",
                "Input argument must be two dimensional\n");
    }
    
    /* Get the size and pointers to input data */
    m  = mxGetM(prhs[0]);
    n  = mxGetN(prhs[0]);
    pr = mxGetPr(prhs[0]);
    pi = mxGetPi(prhs[0]);
    cmplx = (pi==NULL ? 0 : 1);
    
    /* Allocate space for sparse matrix
     * NOTE:  Assume at most 20% of the data is sparse.  Use ceil
     * to cause it to round up.
     */
    
    percent_sparse = 0.2;
    nzmax=(mwSize)ceil((double)m*(double)n*percent_sparse);
    
    plhs[0] = mxCreateSparse(m,n,nzmax,cmplx);
    sr  = mxGetPr(plhs[0]);
    si  = mxGetPi(plhs[0]);
    irs = mxGetIr(plhs[0]);
    jcs = mxGetJc(plhs[0]);
    
    /* Copy nonzeros */
    k = 0;
    isfull=0;
    for (j=0; (j<n); j++) {
        mwSize i;
        jcs[j] = k;
        for (i=0; (i<m ); i++) {
            if (IsNonZero(pr[i]) || (cmplx && IsNonZero(pi[i]))) {
                
                /* Check to see if non-zero element will fit in
                 * allocated output array.  If not, increase percent_sparse
                 * by 10%, recalculate nzmax, and augment the sparse array
                 */
                if (k>=nzmax){
                    mwSize oldnzmax = nzmax;
                    percent_sparse += 0.1;
                    nzmax = (mwSize)ceil((double)m*(double)n*percent_sparse);
                    
                    /* make sure nzmax increases atleast by 1 */
                    if (oldnzmax == nzmax)
                        nzmax++;
                    
                    mxSetNzmax(plhs[0], nzmax);
                    mxSetPr(plhs[0], mxRealloc(sr, nzmax*sizeof(double)));
                    if(si != NULL)
                        mxSetPi(plhs[0], mxRealloc(si, nzmax*sizeof(double)));
                    mxSetIr(plhs[0], mxRealloc(irs, nzmax*sizeof(mwIndex)));
                    
                    sr  = mxGetPr(plhs[0]);
                    si  = mxGetPi(plhs[0]);
                    irs = mxGetIr(plhs[0]);
                }
                sr[k] = pr[i];
                if (cmplx){
                    si[k]=pi[i];
                }
                irs[k] = i;
                k++;
            }
        }
        pr += m;
        pi += m;
    }
    jcs[n] = k;
}
int TestLinearSolver(void){

  int test=1,test1=1,test2=1,test3=1;

  LinearSolver sky;


#define _NN 5

  // preliminary work on the skyline struct
  // _NN is the size of the linear system to be solved
  InitLinearSolver(&sky,_NN,NULL,NULL);

  sky.solver_type = LU;
  sky.pc_type=NONE;

  real A[_NN][_NN];
  real vf[_NN],sol[_NN];

  A[0][0] = 0.2e1;
  A[0][1] = -0.1e1;
  A[0][2] = 0;
  A[0][3] = 0;
  A[0][4] = 0;
  A[1][0] = -0.1e1;
  A[1][1] = 0.2e1;
  A[1][2] = -0.1e1;
  A[1][3] = 0;
  A[1][4] = 0;
  A[2][0] = 0;
  A[2][1] = -0.1e1;
  A[2][2] = 0.2e1;
  A[2][3] = -0.1e1;
  A[2][4] = 0;
  A[3][0] = 0;
  A[3][1] = 0;
  A[3][2] = -0.1e1;
  A[3][3] = 0.2e1;
  A[3][4] = -0.1e1;
  A[4][0] = 0;
  A[4][1] = 0;
  A[4][2] = 0;
  A[4][3] = -0.1e1;
  A[4][4] = 0.2e1;
  vf[0] = 0;
  vf[1] = 0;
  vf[2] = 0;
  vf[3] = 0;
  vf[4] = 0.6e1;

  sol[0] = 0;
  sol[1] = 0;
  sol[2] = 0;
  sol[3] = 0;
  sol[4] = 0;



  // first mark the nonzero values in A
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0) IsNonZero(&sky,i,j);
      //if (i==j) SwitchOn(&sky,i,j);
    }
  }

  // once the nonzero positions are known allocate memory
  AllocateLinearSolver(&sky);

  // now set the nonzero terms
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0){
      	AddLinearSolver(&sky,i,j,A[i][j]);
      }
      /* if (i==j){ */
      /* 	SetLinearSolver(&sky,i,j,2); */
      /* } */
    }
  }


  // printf for checking...
  DisplayLinearSolver(&sky);


  // solve from a decomposed matrix
  // vf: rhs
  // sol: solution

  sky.rhs=vf;
  sky.sol=sol;
  SolveLinearSolver(&sky);


  // checking
  real verr=0;
  printf("sol of LU=");
  for(int i=0;i<_NN;i++){
    printf("%f ",sol[i]);
    verr+=fabs(sol[i]-i-1);
  }
  printf("\n");
  printf("\n");
  // deallocate memory
  FreeLinearSolver(&sky);
  

  test1= (verr<1e-10);


#ifdef PARALUTION
  // preliminary work on the skyline struct
  // _NN is the size of the linear system to be solved
  InitLinearSolver(&sky,_NN,NULL,NULL);

  sky.solver_type = PAR_GMRES;
  sky.pc_type=PAR_JACOBI;

  A[0][0] = 0.2e1;
  A[0][1] = -0.1e1;
  A[0][2] = 0;
  A[0][3] = 0;
  A[0][4] = 0;
  A[1][0] = -0.1e1;
  A[1][1] = 0.2e1;
  A[1][2] = -0.1e1;
  A[1][3] = 0;
  A[1][4] = 0;
  A[2][0] = 0;
  A[2][1] = -0.1e1;
  A[2][2] = 0.2e1;
  A[2][3] = -0.1e1;
  A[2][4] = 0;
  A[3][0] = 0;
  A[3][1] = 0;
  A[3][2] = -0.1e1;
  A[3][3] = 0.2e1;
  A[3][4] = -0.1e1;
  A[4][0] = 0;
  A[4][1] = 0;
  A[4][2] = 0;
  A[4][3] = -0.1e1;
  A[4][4] = 0.2e1;
  vf[0] = 0;
  vf[1] = 0;
  vf[2] = 0;
  vf[3] = 0;
  vf[4] = 0.6e1;

  sol[0] = 0;
  sol[1] = 0;
  sol[2] = 0;
  sol[3] = 0;
  sol[4] = 0;



  // first mark the nonzero values in A
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0) IsNonZero(&sky,i,j);
      //if (i==j) SwitchOn(&sky,i,j);
    }
  }

  // once the nonzero positions are known allocate memory
  AllocateLinearSolver(&sky);

  // now set the nonzero terms
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0){
      	AddLinearSolver(&sky,i,j,A[i][j]);
      }
      /* if (i==j){ */
      /* 	SetLinearSolver(&sky,i,j,2); */
      /* } */
    }
  }

  sky.rhs=vf;
  sky.sol=sol;
  SolveLinearSolver(&sky);


  // checking
  verr=0;
  printf("sol of paralution=");
  for(int i=0;i<_NN;i++){
    printf("%f ",sol[i]);
    verr+=fabs(sol[i]-i-1);
  }
  printf("\n");
  printf("\n");

  // deallocate memory
  FreeLinearSolver(&sky);
  

  test2= (verr<1e-6);
#endif

  InitLinearSolver(&sky,_NN,NULL,NULL);

  sky.solver_type = GMRES;
  sky.pc_type=NONE;
  
  // now test a symmetric matrix
  A[0][0] = 0.3e1;
  A[0][1] = -0.1e1;
  A[0][2] = 0;
  A[0][3] = 0;
  A[0][4] = -0.1e1;
  A[1][0] = -0.1e1;
  A[1][1] = 0.2e1;
  A[1][2] = -0.1e1;
  A[1][3] = 0;
  A[1][4] = 0;
  A[2][0] = 0;
  A[2][1] = -0.1e1;
  A[2][2] = 0.2e1;
  A[2][3] = -0.1e1;
  A[2][4] = 0;
  A[3][0] = 0;
  A[3][1] = 0;
  A[3][2] = -0.1e1;
  A[3][3] = 0.2e1;
  A[3][4] = -0.1e1;
  A[4][0] = -0.1e1;
  A[4][1] = 0;
  A[4][2] = 0;
  A[4][3] = -0.1e1;
  A[4][4] = 0.3e1;
  vf[0] = -0.4e1;
  vf[1] = 0;
  vf[2] = 0;
  vf[3] = 0;
  vf[4] = 0.10e2;

  sol[0] = 0;
  sol[1] = 0;
  sol[2] = 0;
  sol[3] = 0;
  sol[4] = 0;

  sky.is_sym=false;

  // first mark the nonzero values in A
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0) IsNonZero(&sky,i,j);
    }
  }

  // once the nonzero positions are known allocate memory
  AllocateLinearSolver(&sky);

  // now set the nonzero terms
  for(int i=0;i<_NN;i++){
    for(int j=0;j<_NN;j++){
      if (A[i][j] != 0){
      	AddLinearSolver(&sky,i,j,A[i][j]);
      }
    }
  }

  sky.rhs=vf;
  sky.sol=sol;
  SolveLinearSolver(&sky);


  // checking
  verr=0;
  printf("sol of gmres=");
  for(int i=0;i<_NN;i++){
    printf("%f ",sol[i]);
    verr+=fabs(sol[i]-i-1);
  }
  printf("\n");
  printf("\n");

  // deallocate memory
  FreeLinearSolver(&sky);

  test3 =  (verr<1e-6);

  if(test1==1 &&  test2==1 && test3==1) test=1;

  return test;

}
void mexFunction(
        int nlhs,       mxArray *plhs[],
        int nrhs, const mxArray *prhs[]
        )
{
  /* Declare variables. */
  int j,k,m,n,nzmax,*irs,*jcs, *irs2, *jcs2;
  double *overlap, *overlap2, tmp, areaA, areaB;
  double percent_sparse;
  double *leftA, *rightA, *topA, *bottomA;
  double *leftB, *rightB, *topB, *bottomB;
  double *verbose;

  /* Get the size and pointers to input data. */
  m = MAX(mxGetM(prhs[0]), mxGetN(prhs[0]));
  n = MAX(mxGetM(prhs[4]), mxGetN(prhs[4]));
  /* printf("A=%d, B=%d\n", m, n); */

  leftA = mxGetPr(prhs[0]);
  rightA = mxGetPr(prhs[1]);
  topA = mxGetPr(prhs[2]);
  bottomA = mxGetPr(prhs[3]);

  leftB = mxGetPr(prhs[4]);
  rightB = mxGetPr(prhs[5]);
  topB = mxGetPr(prhs[6]);
  bottomB = mxGetPr(prhs[7]);

  verbose = mxGetPr(prhs[8]);

    /* Allocate space for sparse matrix. 
     * NOTE:  Assume at most 20% of the data is sparse.  Use ceil
     * to cause it to round up. 
     */

  percent_sparse = 0.01;
  nzmax = (int)ceil((double)m*(double)n*percent_sparse);

  plhs[0] = mxCreateSparse(m,n,nzmax,0);
  overlap  = mxGetPr(plhs[0]);
  irs = mxGetIr(plhs[0]);
  jcs = mxGetJc(plhs[0]);

  plhs[1] = mxCreateSparse(m,n,nzmax,0);
  overlap2  = mxGetPr(plhs[1]);
  irs2 = mxGetIr(plhs[1]);
  jcs2 = mxGetJc(plhs[1]);

    
  /* Assign nonzeros. */
  k = 0; 
  for (j = 0; (j < n); j++) {
    int i;
    jcs[j] = k; 
    jcs2[j] = k; 
    for (i = 0; (i < m); i++) {
      tmp = (MAX(0, MIN(rightA[i], rightB[j]) - MAX(leftA[i], leftB[j]) )) * 
	(MAX(0, MIN(topA[i], topB[j]) - MAX(bottomA[i], bottomB[j]) ));
      
      if (*verbose) {
	printf("j=%d,i=%d,tmp=%5.3f\n", j,i,tmp);
      }

      if (IsNonZero(tmp)) {

        /* Check to see if non-zero element will fit in 
         * allocated output array.  If not, increase
         * percent_sparse by 20%, recalculate nzmax, and augment
         * the sparse array.
         */
        if (k >= nzmax) {
          int oldnzmax = nzmax;
          percent_sparse += 0.2;
          nzmax = (int)ceil((double)m*(double)n*percent_sparse);

          /* Make sure nzmax increases atleast by 1. */
          if (oldnzmax == nzmax) 
            nzmax++;
	  printf("reallocating from %d to %d\n", oldnzmax, nzmax);

          mxSetNzmax(plhs[0], nzmax); 
          mxSetPr(plhs[0], mxRealloc(overlap, nzmax*sizeof(double)));
          mxSetIr(plhs[0], mxRealloc(irs, nzmax*sizeof(int)));
          overlap  = mxGetPr(plhs[0]);
          irs = mxGetIr(plhs[0]);

          mxSetNzmax(plhs[1], nzmax); 
          mxSetPr(plhs[1], mxRealloc(overlap2, nzmax*sizeof(double)));
          mxSetIr(plhs[1], mxRealloc(irs2, nzmax*sizeof(int)));
          overlap2  = mxGetPr(plhs[1]);
          irs2 = mxGetIr(plhs[1]);
        }

        overlap[k] = tmp;
        irs[k] = i;
	
	areaA = (rightA[i]-leftA[i])*(topA[i]-bottomA[i]);
	areaB = (rightB[j]-leftB[j])*(topB[j]-bottomB[j]);
	overlap2[k] = MIN(tmp/areaA, tmp/areaB);
	irs2[k] = i;

        k++;
      } /* IsNonZero */
    } /* for i */
  }
  jcs[n] = k;
  jcs2[n] = k;
  
}