// Copyright (C) 2005-2008, Pierre Bonami and others.  All Rights Reserved.
// Author:   Pierre Bonami
//           LIF
//           CNRS, Aix-Marseille Universites
// Date:     02/23/08
//---------------------------------------------------------------------------


#ifndef CglLandPUtils_H
#define CglLandPUtils_H
#include "CglLandPTabRow.hpp"

class OsiRowCut;
class OsiCuts;
#include <vector>

namespace LAP {
/** Compute \$ \frac{\sum\limits_{j=1}^n | \overline a_{ij} |}{1 - \overline a_{i0}} \$ for row passed as argument.*/
double normCoef(TabRow &row, int ncols, const int * nonBasics);
/** scale the cut passed as argument*/
void scale(OsiRowCut &cut);
/** scale the cut passed as argument using provided normalization factor*/
void scale(OsiRowCut &cut, double norma);
/** Modularize row.*/
void modularizeRow(TabRow & row, const bool * integerVar);


/** return the coefficients of the intersection cut */
inline double intersectionCutCoef(double alpha_i, double beta)
{
    if (alpha_i>0) return alpha_i* (1 - beta);
    else return -alpha_i * beta;// (1 - beta);
}

/** compute the modularized row coefficient for an integer variable*/
inline double modularizedCoef(double alpha, double beta)
{
    double f_i = alpha - floor(alpha);
    if (f_i <= beta)
        return f_i;
    else
        return f_i - 1;
}

/** Says is value is integer*/
inline bool int_val(double value, double tol)
{
    return fabs( floor( value + 0.5 ) - value ) < tol;
}


/** To store extra cuts generated by columns from which they origin.*/
struct Cuts {
    Cuts():  numberCuts_(0), cuts_(0){
    }
    /** Puts all the cuts into an OsiCuts */
    int insertAll(OsiCuts & cs, CoinRelFltEq eq);
    /** Destructor.*/
    ~Cuts() {}
    /** Access to row cut indexed by i*/
    OsiRowCut * rowCut(unsigned int i) {
        return cuts_[i];
    }
    /** const access to row cut indexed by i*/
    const OsiRowCut * rowCut(unsigned int i) const {
        return cuts_[i];
    }
    /** insert a cut for variable i and count number of cuts.*/
    void insert(int i, OsiRowCut * cut);
    /** Access to number of cuts.*/
    int numberCuts() {
        return numberCuts_;
    }
    /** resize vector.*/
    void resize(unsigned int i) {
        cuts_.resize(i, (OsiRowCut *) NULL);
    }
private:
    /** Stores the number of cuts.*/
    int numberCuts_;
    /** Store the cuts by index of the generating simple disjunction.*/
    std::vector<OsiRowCut *> cuts_;
};

}
#endif

