/*
 * traverser_resultantfanspecialization.h
 *
 *  Created on: Jul 1, 2011
 *      Author: anders
 */

#ifndef TRAVERSER_RESULTANTFANSPECIALIZATION_H_INCLUDED
#define TRAVERSER_RESULTANTFANSPECIALIZATION_H_INCLUDED

#include "traverser_resultantfan.h"
#include "triangulation2.h"

/*
 * Specializing at a set of variables coresponds to stably intersecting with the subspace
 * where these coordinates are zero.
 */
class ResultantFanSpecializationTraverser : public ConeTraverser
{
  Triangulation2 theTriangulation;
  PolyhedralCone theCone;
//  PolynomialSet g;
  IntegerVectorListList tuple;
  IntegerMatrix theConfiguration;
  IntegerVector isSpecial;
  vector<pair<int, int> > intervals;
  PolyhedralCone subspace;
  int D1;
  int n,d;
public:
  ResultantFanSpecializationTraverser(/*PolynomialSet const &g, */IntegerVectorListList const &tuple_,int D_, IntegerMatrix const &cayley, vector<pair<int,int> > intervals_, IntegerVector const &isSpecial_, IntegerVector omega, int dim);
  virtual void changeCone(IntegerVector const &ridgeVector, IntegerVector const &rayVector);
  virtual IntegerVectorList link(IntegerVector const &ridgeVector);
  PolyhedralCone &refToPolyhedralCone();
};

IntegerVector nonTrivialVectorInSpecializedResultant(IntegerMatrix const &exponents, vector<pair<int,int> > const &intervals, IntegerVector const &subset, IntegerVector const &isSpecial);

/**
 * This function takes a matrix whose columns are grouped according to intervals, and computes perturbed vector in the
 * relative interior of a maximal cone in the corresponding specialized resultant. The specialization variables are given
 * by the 0-1 vector isSpecial.
 * An additional argument is the 0-1 subset vector, which tells which columns of the matrix (and entries of isSpecial) to
 * take into the consideration. Usually this will be the all 1 vector, but since this function is recursive other inputs are
 * allowed.
 * The return value v, is to be interpreted as v[0]+epsilon*v[1]+epsilon^2*v[2]....
 */
IntegerVectorList perturbationSequenceRek(IntegerMatrix const &exponents, vector<pair<int,int> > const &intervals, IntegerVector const &subset, IntegerVector const &isSpecial, PolyhedralCone const &toBeAvoided);


bool isSpecializedResultantEmpty(IntegerMatrix const &exponents, vector<pair<int,int> > const &intervals, IntegerVector const &isSpecial);

/**
 * Computes the secondary cone containing the perturbed vector l[0]+epsilon*l[1]+....
 * The configuration is....
 */
PolyhedralCone perturbationSequenceToVectorInSecondaryCone(IntegerVectorList const &l, IntegerMatrix const &configuration);

/**
 * Takes the list of boolean values and returns the subspace, generated by those standard vectors whose corresponding
 * entry boolean value is zero. The return value is a PolyhedralCone.
 */
PolyhedralCone specializedToSubspace(IntegerVector const &isSpecial);

/**
 * This class takes a list of intervals and iterates through all vectors of possible two element subsets
 * where the ith two element subset is a subset of the ith interval.
 */
class SelectionIterator
{
  vector<vector<int> > choices;
public:
  SelectionIterator(vector<pair<int,int> > const &intervals):
    choices(intervals.size())
    {
      for(int i=0;i<intervals.size();i++)for(int j=intervals[i].first;j!=intervals[i].second;j++)choices[i].push_back(j>=intervals[i].second-2);
    }
  bool operator++()
    {
      int i;
      for(i=0;i<choices.size();i++)
        {
          if(next_permutation(choices[i].begin(),choices[i].end()))break;
        }
      return i!=choices.size();
    }
  int size()const
  {
    return choices.size();
  }
  int sizeOfIth(int i)const
  {
    assert(i<choices.size());
    return choices[i].size();
  }
  bool chosen(int  i, int j)const
  {
    assert(i<choices.size());
    assert(j<choices[i].size());
    return choices[i][j];
  }
};

#endif
