Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 10198)
@@ -104,4 +104,5 @@
     <Compile Include="ConvexHullTest.cs" />
     <Compile Include="RealVectorSolutionCacheTest.cs" />
+    <Compile Include="TestVolumeCalculation.cs" />
   </ItemGroup>
   <ItemGroup>
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs	(revision 10198)
@@ -74,9 +74,9 @@
       for (int i = 0; i < data.Count(); i++) {
         double[] d = data[i];
-        for (int j = 0; j < d.Length; j++) {
-          DefaultVertex vertex = new DefaultVertex();
-          vertex.Position = d.Select(x => x).ToArray();
-          result.Add(vertex);
-        }
+
+        DefaultVertex vertex = new DefaultVertex();
+        vertex.Position = d;
+        result.Add(vertex);
+
       }
       return result;
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/LPConvexHullTest.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/LPConvexHullTest.cs	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/LPConvexHullTest.cs	(revision 10198)
@@ -145,9 +145,7 @@
       for (int i = 0; i < data.Count(); i++) {
         double[] d = data[i];
-        for (int j = 0; j < d.Length; j++) {
-          DefaultVertex vertex = new DefaultVertex();
-          vertex.Position = d.Select(x => x).ToArray();
-          result.Add(vertex);
-        }
+        DefaultVertex vertex = new DefaultVertex();
+        vertex.Position = d;
+        result.Add(vertex);
       }
       return result;
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/TestVolumeCalculation.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/TestVolumeCalculation.cs	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/TestVolumeCalculation.cs	(revision 10198)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Analysis.AlgorithmBehavior.Analyzers;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace AlgorithmBehaviorUnitTests {
+  [TestClass]
+  public class TestVolumeCalculation {
+    [TestMethod]
+    public void TestVolCalc() {
+      int dim = 4;
+      int size = 20;
+      var data = CreateRandomData(size, dim);
+      var dataList = data.ToList();
+      Stopwatch watch = new Stopwatch();
+
+
+      //calculate convex hull
+      watch.Start();
+      var convexHull = LPHull.Calculate(data);
+      watch.Stop();
+      Console.WriteLine("Convex hull calculation took : " + watch.Elapsed.TotalSeconds + " seconds.");
+
+
+      //calculate volume of convex hull
+      watch.Start();
+      double volume = ConvexHullMeasures.CalculateVolumeNew(convexHull);
+      watch.Stop();
+      Console.WriteLine("Volume calculation of convex hull took : " + watch.Elapsed.TotalSeconds + " seconds.");
+      Console.WriteLine("Volume of convex hull is: " + volume);
+
+
+      //do volume calculation from the whole data set
+      watch.Start();
+      volume = ConvexHullMeasures.CalculateVolumeNew(dataList);
+      watch.Stop();
+      Console.WriteLine("Volume calculation of whole data set took : " + watch.Elapsed.TotalSeconds + " seconds.");
+      Console.WriteLine("Volume of whole data is: " + volume);
+    }
+
+
+    private double[][] CreateRandomData(int n, int m) {
+      double[][] result = new double[n][];
+      Random rand = new Random();
+
+      for (int i = 0; i < n; i++) {
+        result[i] = new double[m];
+        for (int j = 0; j < m; j++) {
+          result[i][j] = (double)rand.Next(1, 60);
+        }
+      }
+      return result;
+    }
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ConvexHullMeasures.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ConvexHullMeasures.cs	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ConvexHullMeasures.cs	(revision 10198)
@@ -20,6 +20,8 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using MIConvexHull;
 
 namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
@@ -67,4 +69,41 @@
       return volume;
     }
+
+    public static double CalculateVolumeNew(List<double[]> convexHull) {
+      double volume = 0.0;
+
+      int dim = convexHull.First().Length;
+      if (dim > convexHull.Count)
+        throw new ArgumentException("Nr. of points for volume calculation must be greater than dimension", "convexHull");
+
+      var triangulation = Triangulation.CreateDelaunay(ConvertToVertex(convexHull));
+      var simplices = ConvertFromTriangulation(triangulation);
+      foreach (var simplex in simplices) {
+        volume += CalculateSimplexVolume(simplex.ToList());
+      }
+
+      return volume;
+    }
+
+    private static List<double[][]> ConvertFromTriangulation(ITriangulation<DefaultVertex, DefaultTriangulationCell<DefaultVertex>> triangulation) {
+      List<double[][]> results = new List<double[][]>();
+
+      foreach (var cell in triangulation.Cells) {
+        results.Add(cell.Vertices.Select(x => x.Position).ToArray());
+      }
+
+      return results;
+    }
+
+    private static List<DefaultVertex> ConvertToVertex(List<double[]> data) {
+      List<DefaultVertex> result = new List<DefaultVertex>();
+      for (int i = 0; i < data.Count(); i++) {
+        double[] d = data[i];
+        DefaultVertex vertex = new DefaultVertex();
+        vertex.Position = d;
+        result.Add(vertex);
+      }
+      return result;
+    }
   }
 }
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 10198)
@@ -159,4 +159,8 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\MIConvexHull\MIConvexHull.csproj">
+      <Project>{2337776d-7d0c-40aa-a439-c26c3ce24fab}</Project>
+      <Name>MIConvexHull</Name>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs	(revision 10197)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs	(revision 10198)
@@ -85,9 +85,8 @@
       for (int i = 0; i < data.Count(); i++) {
         double[] d = data[i];
-        for (int j = 0; j < d.Length; j++) {
-          DefaultVertex vertex = new DefaultVertex();
-          vertex.Position = d.Select(x => x).ToArray();
-          result.Add(vertex);
-        }
+        DefaultVertex vertex = new DefaultVertex();
+        vertex.Position = d;
+        result.Add(vertex);
+
       }
       return result;
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/FractionClass.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/FractionClass.cs	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/FractionClass.cs	(revision 10198)
@@ -0,0 +1,1345 @@
+	/*
+	* Author: Syed Mehroz Alam
+	* Email: smehrozalam@yahoo.com
+	* URL: Programming Home "http://www.geocities.com/smehrozalam/" 
+	*
+	*/
+
+	using System;
+	using System.Runtime.InteropServices;
+	using System.Globalization;
+
+	namespace Mehroz
+	{
+		/// <summary>
+		/// Classes Contained:
+		///     Fraction
+		///     FractionException
+		/// </summary>
+	    
+		/// Class name: Fraction
+		/// Developed by: Syed Mehroz Alam
+		/// Email: mailto:smehrozalam@yahoo.com
+		/// URL: http://www.geocities.com/smehrozalam/
+		/// Changes: Marc C. Brooks  mailto:IDisposable@gmail.com
+		///          Jeffery Sax    http://www.extremeoptimization.com
+		/// Version: 2.2
+		/// 
+		/// What's new in version 2.0:
+		///     *   Changed Numerator and Denominator from Int32(integer) to Int64(long) for increased range
+		///     *   renamed ConvertToString() to (overloaded) ToString()
+		///     *   added the capability of detecting/raising overflow exceptions
+		///     *   Fixed the bug that very small numbers e.g. 0.00000001 could not be converted to fraction
+		///     *   Other minor bugs fixed
+		/// 
+		/// What's new in version 2.1
+		///     *   overloaded user-defined conversions to/from Fractions
+		///
+		/// What's new in version 2.2 - Marc C. Brooks   mailto:IDisposable@gmail.com
+		///     *   less overflows by finding the GCD for Add [Jeffery Sax] and Multiply [Marc C. Brooks]
+		///     *   understands and handles NaN, PositiveInfinity, NegativeInfinity just like double [Marc C. Brooks]
+		///     *   fixed several uses of int where long was correct [Marc C. Brooks]
+		///     *   made value-type (struct) [Jeffery Sax]
+		///     *   added ToInt32(), ToInt64() which throw for invalid (NaN, PositiveInfinity, NegativeInfinity) [Marc C. Brooks]
+		///     *   removed redundant Value property [Jeffery Sax]
+		///     *   added explicit conversion to Int32 and Int64 [Marc C. Brooks]
+		///     *   better handling of exceptions [Marc C. Brooks]
+		///     *   reorganize code, add XML doc and regions [Marc C. Brooks]
+		///     *   proper implementations of Equals [Marc C. Brooks, Jeffery Sax]
+		///     *   uses Math.Log(xx,2) and Math.Pow(xx,2) to get the best accuracy possible when converting doubles [Marc C. Brooks, Jeffery Sax]
+		///
+		/// What's new in version 2.3 - Marc C. Brooks   mailto:IDisposable@gmail.com   01/10/2005
+		///     *   fixed double-to-fraction logic to use continued fraction rules to get best possible precistion [bug fix for Syed Mehroz Alam, idea from  Jeffery Sax]
+		///     *	added static readonly values for NaN, PositiveInfinity, NegativeInfinity [idea from Jeffery Sax]
+		///     *	moved comparisons into an implementation of IComparer [idea from Jeffery Sax]
+		///     *	no longer throws for NaN(s) involved in Add, Subtract, Multiply, Divide operations [idea from Jeffery Sax]
+		///     *   added static readonly values for Zero, MinValue, MaxValue, Epsilon to better mirror double
+		///     *   added IsInfinity to better mirror double.
+		///     *   added Modulus and % operators
+		///
+		/// Properties:
+		///     Numerator: Set/Get value for Numerator
+		///     Denominator:  Set/Get value for Numerator
+		///     [Note: If you Set either Property, the Fraction should be passed to ReduceFraction at some point.]
+		/// 
+		/// Constructors:
+		///     no arguments:   initializes fraction as 0/0 = NaN, so don't do that!
+		///     (Numerator, Denominator): initializes fraction with the given numerator and denominator 
+		///                               values and reduces
+		///     (long): initializes fraction with the given long value
+		///     (double):   initializes fraction with the given double value
+		///     (string):   initializes fraction with the given string value
+		///                 the string can be an in the form of and integer, double or fraction.
+		///                 e.g it can be like "123" or "123.321" or "123/456"
+		/// 
+		/// Public Methods (Description is given with respective methods' definitions)
+		///     Fraction ToFraction(long)
+		///     Fraction ToFraction(double)
+		///     Fraction ToFraction(string)
+		///     Int32 ToInt32()
+		///     Int64 ToInt64()
+		///     double ToDouble()
+		///     (override) string ToString()
+		///     Fraction Inverse()
+		///     Fraction Inverted(long)
+		///     Fraction Inverted(double)
+		///     ReduceFraction(ref Fraction)
+		///     CrossReducePair(ref Fraction, ref Fraction)
+		///     (override) Equals(object)
+		///     (override) GetHashCode()
+		/// 
+		/// Overloaded Operators (overloaded for Fractions, long and double)
+		///     Unary: -
+		///     Binary: +,-,*,/
+		///     Relational and Logical Operators: ==,!=,<,>,<=,>= (only == and != for long and doubles)
+		/// 
+		/// Overloaded user-defined conversions
+		///     Implicit:   From long/double/string to Fraction
+		///     Explicit:   From Fraction to long/double/string
+		/// </summary>
+		[Serializable, StructLayout(LayoutKind.Sequential)]
+		public struct Fraction : IComparable, IFormattable
+		{
+			#region Constructors
+			/// <summary>
+			/// Construct a Fraction from an integral value
+			/// </summary>
+			/// <param name="wholeNumber">The value (eventual numerator)</param>
+			/// <remarks>The denominator will be 1</remarks>
+			public Fraction(long wholeNumber)
+			{
+				if (wholeNumber == long.MinValue)
+					wholeNumber++;	// prevent serious issues later..
+
+				m_Numerator = wholeNumber;
+				m_Denominator = 1;
+				// no reducing required, we're a whole number
+			}
+	    
+			/// <summary>
+			/// Construct a Fraction from a floating-point value
+			/// </summary>
+			/// <param name="floatingPointNumber">The value</param>
+			public Fraction(double floatingPointNumber)
+			{
+				this = ToFraction(floatingPointNumber);
+			}
+	        
+			/// <summary>
+			/// Construct a Fraction from a string in any legal format
+			/// </summary>
+			/// <param name="inValue">A string with a legal fraction input format</param>
+			/// <remarks>Will reduce the fraction to smallest possible denominator</remarks>
+			/// <see>ToFraction(string strValue)</see>
+			public Fraction(string inValue)
+			{
+				this = ToFraction(inValue);
+			}
+	        
+			/// <summary>
+			/// Construct a Fraction from a numerator, denominator pair
+			/// </summary>
+			/// <param name="numerator">The numerator (top number)</param>
+			/// <param name="denominator">The denominator (bottom number)</param>
+			/// <remarks>Will reduce the fraction to smallest possible denominator</remarks>
+			public Fraction(long numerator, long denominator)
+			{
+				if (numerator == long.MinValue)
+					numerator++;	// prevent serious issues later..
+
+				if (denominator == long.MinValue)
+					denominator++;	// prevent serious issues later..
+
+				m_Numerator = numerator;
+				m_Denominator = denominator;
+				ReduceFraction(ref this);
+			}
+
+			/// <summary>
+			/// Private constructor to synthesize a Fraction for indeterminates (NaN and infinites)
+			/// </summary>
+			/// <param name="type">Kind of inderterminate</param>
+			private Fraction(Indeterminates type)
+			{
+				m_Numerator = (long)type;
+				m_Denominator = 0;
+				// do NOT reduce, we're clean as can be!
+			}
+			#endregion
+
+			#region Properties
+			/// <summary>
+			/// The 'top' part of the fraction
+			/// </summary>
+			/// <example>For 3/4ths, this is the 3</example>
+			public long Numerator
+			{
+				get 
+				{
+					return m_Numerator;
+				}
+				set
+				{
+					m_Numerator = value;
+				}
+			}
+
+			/// <summary>
+			/// The 'bottom' part of the fraction
+			/// </summary>
+			/// <example>For 3/4ths, this is the 4</example>
+			public long Denominator
+			{
+				get
+				{
+					return m_Denominator;
+				}
+				set
+				{
+					m_Denominator = value;
+				}
+			}
+			#endregion
+
+			#region Expose constants
+			public static readonly Fraction NaN = new Fraction(Indeterminates.NaN);
+			public static readonly Fraction PositiveInfinity = new Fraction(Indeterminates.PositiveInfinity);
+			public static readonly Fraction NegativeInfinity = new Fraction(Indeterminates.NegativeInfinity);
+			public static readonly Fraction Zero = new Fraction(0,1);
+			public static readonly Fraction Epsilon = new Fraction(1, Int64.MaxValue);
+			private static readonly double EpsilonDouble = 1.0 / Int64.MaxValue;
+			public static readonly Fraction MaxValue = new Fraction(Int64.MaxValue, 1);
+			public static readonly Fraction MinValue = new Fraction(Int64.MinValue, 1);
+			#endregion
+
+			#region Explicit conversions
+			#region To primitives
+			/// <summary>
+			/// Get the integral value of the Fraction object as int/Int32
+			/// </summary>
+			/// <returns>The (approximate) integer value</returns>
+			/// <remarks>If the value is not a true integer, the fractional part is discarded
+			/// (truncated toward zero). If the valid exceeds the range of an Int32 and exception is thrown.</remarks>
+			/// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity
+			/// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception>
+			/// <exception cref="OverflowException" Will throw a System.OverflowException if the value is too
+			/// large or small to be represented as an Int32.</exception>
+			public Int32 ToInt32()
+			{
+				if (this.m_Denominator == 0)
+				{
+					throw new FractionException(string.Format("Cannot convert {0} to Int32", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException());
+				}
+
+				long bestGuess = this.m_Numerator / this.m_Denominator;
+
+				if (bestGuess > Int32.MaxValue || bestGuess < Int32.MinValue)
+				{
+					throw new FractionException("Cannot convert to Int32", new System.OverflowException());
+				}
+
+				return (Int32)bestGuess;
+			}
+
+			/// <summary>
+			/// Get the integral value of the Fraction object as long/Int64
+			/// </summary>
+			/// <returns>The (approximate) integer value</returns>
+			/// <remarks>If the value is not a true integer, the fractional part is discarded
+			/// (truncated toward zero). If the valid exceeds the range of an Int32, no special
+			/// handling is guaranteed.</remarks>
+			/// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity
+			/// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception>
+			public Int64 ToInt64()
+			{
+				if (this.m_Denominator == 0)
+				{
+					throw new FractionException(string.Format("Cannot convert {0} to Int64", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException());
+				}
+
+				return this.m_Numerator / this.m_Denominator;
+			}
+
+			/// <summary>
+			/// Get the value of the Fraction object as double with full support for NaNs and infinities
+			/// </summary>
+			/// <returns>The decimal representation of the Fraction, or double.NaN, double.NegativeInfinity
+			/// or double.PositiveInfinity</returns>
+			public double ToDouble()
+			{
+				if (this.m_Denominator == 1)
+					return this.m_Numerator;
+				else if (this.m_Denominator == 0)
+				{
+					switch (NormalizeIndeterminate(this.m_Numerator))
+					{
+						case Indeterminates.NegativeInfinity:
+							return double.NegativeInfinity;
+
+						case Indeterminates.PositiveInfinity:
+							return double.PositiveInfinity;
+
+						case Indeterminates.NaN:
+						default:    // this can't happen
+							return double.NaN;
+					}
+				}
+				else
+				{
+					return (double)this.m_Numerator / (double)this.m_Denominator;
+				}
+			}
+
+			/// <summary>
+			/// Get the value of the Fraction as a string, with proper representation for NaNs and infinites
+			/// </summary>
+			/// <returns>The string representation of the Fraction, or the culture-specific representations of
+			/// NaN, PositiveInfinity or NegativeInfinity.</returns>
+			/// <remarks>The current culture determines the textual representation the Indeterminates</remarks>
+			public override string ToString()
+			{
+				if (this.m_Denominator == 1)
+				{
+					return this.m_Numerator.ToString();
+				}
+				else if (this.m_Denominator == 0)
+				{
+					return IndeterminateTypeName(this.m_Numerator);
+				}
+				else
+				{
+					return this.m_Numerator.ToString() + "/" + this.m_Denominator.ToString();
+				}
+			}
+			#endregion
+
+			#region From primitives
+			/// <summary>
+			/// Converts a long value to the exact Fraction
+			/// </summary>
+			/// <param name="inValue">The long to convert</param>
+			/// <returns>An exact representation of the value</returns>
+			public static Fraction ToFraction(long inValue)
+			{
+				return new Fraction(inValue);
+			}
+
+			/// <summary>
+			/// Converts a double value to the approximate Fraction
+			/// </summary>
+			/// <param name="inValue">The double to convert</param>
+			/// <returns>A best-fit representation of the value</returns>
+			/// <remarks>Supports double.NaN, double.PositiveInfinity and double.NegativeInfinity</remarks>
+			public static Fraction ToFraction(double inValue)
+			{
+				// it's one of the indeterminates... which?
+				if (double.IsNaN(inValue))
+					return NaN;
+				else if (double.IsNegativeInfinity(inValue))
+					return NegativeInfinity;
+				else if (double.IsPositiveInfinity(inValue))
+					return PositiveInfinity;
+				else if (inValue == 0.0d)
+					return Zero;
+
+				if (inValue > Int64.MaxValue)
+					throw new OverflowException(string.Format("Double {0} too large", inValue));
+
+				if (inValue < -Int64.MaxValue)
+					throw new OverflowException(string.Format("Double {0} too small", inValue));
+
+				if (-EpsilonDouble < inValue && inValue < EpsilonDouble)
+					throw new ArithmeticException(string.Format("Double {0} cannot be represented", inValue));
+
+				int sign = Math.Sign(inValue);
+				inValue = Math.Abs(inValue);
+
+				return ConvertPositiveDouble(sign, inValue);
+			}
+
+			/// <summary>
+			/// Converts a string to the corresponding reduced fraction
+			/// </summary>
+			/// <param name="inValue">The string representation of a fractional value</param>
+			/// <returns>The Fraction that represents the string</returns>
+			/// <remarks>Four forms are supported, as a plain integer, as a double, or as Numerator/Denominator
+			/// and the representations for NaN and the infinites</remarks>
+			/// <example>"123" = 123/1 and "1.25" = 5/4 and "10/36" = 5/13 and NaN = 0/0 and
+			/// PositiveInfinity = 1/0 and NegativeInfinity = -1/0</example>
+			public static Fraction ToFraction(string inValue)
+			{
+				if (inValue == null || inValue == string.Empty)
+					throw new ArgumentNullException("inValue");
+
+				// could also be NumberFormatInfo.InvariantInfo
+				NumberFormatInfo info = NumberFormatInfo.CurrentInfo;
+
+				// Is it one of the special symbols for NaN and such...
+				string trimmedValue = inValue.Trim();
+
+				if (trimmedValue == info.NaNSymbol)
+					return NaN;
+				else if (trimmedValue == info.PositiveInfinitySymbol)
+					return PositiveInfinity;
+				else if (trimmedValue == info.NegativeInfinitySymbol)
+					return NegativeInfinity;
+				else
+				{
+					// Not special, is it a Fraction?
+					int slashPos = inValue.IndexOf('/');
+
+					if (slashPos > -1)
+					{
+						// string is in the form of Numerator/Denominator
+						long numerator = Convert.ToInt64(inValue.Substring(0, slashPos));
+						long denominator = Convert.ToInt64(inValue.Substring(slashPos + 1));
+
+						return new Fraction(numerator, denominator);
+					}
+					else
+					{
+						// the string is not in the form of a fraction
+						// hopefully it is double or integer, do we see a decimal point?
+						int decimalPos = inValue.IndexOf(info.CurrencyDecimalSeparator);
+
+						if (decimalPos > -1)
+							return new Fraction(Convert.ToDouble(inValue));
+						else
+							return new Fraction(Convert.ToInt64(inValue));
+					}
+				}
+			}
+			#endregion
+			#endregion
+
+			#region Indeterminate classifications
+			/// <summary>
+			/// Determines if a Fraction represents a Not-a-Number
+			/// </summary>
+			/// <returns>True if the Fraction is a NaN</returns>
+			public bool IsNaN()
+			{
+				if (this.m_Denominator == 0 
+					&& NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NaN)
+					return true;
+				else
+					return false;
+			}
+
+			/// <summary>
+			/// Determines if a Fraction represents Any Infinity
+			/// </summary>
+			/// <returns>True if the Fraction is Positive Infinity or Negative Infinity</returns>
+			public bool IsInfinity()
+			{
+				if (this.m_Denominator == 0
+					&& NormalizeIndeterminate(this.m_Numerator) != Indeterminates.NaN)
+					return true;
+				else
+					return false;
+			}
+
+			/// <summary>
+			/// Determines if a Fraction represents Positive Infinity
+			/// </summary>
+			/// <returns>True if the Fraction is Positive Infinity</returns>
+			public bool IsPositiveInfinity()
+			{
+				if (this.m_Denominator == 0
+					&& NormalizeIndeterminate(this.m_Numerator) == Indeterminates.PositiveInfinity)
+					return true;
+				else
+					return false;
+			}
+
+			/// <summary>
+			/// Determines if a Fraction represents Negative Infinity
+			/// </summary>
+			/// <returns>True if the Fraction is Negative Infinity</returns>
+			public bool IsNegativeInfinity()
+			{
+				if (this.m_Denominator == 0
+					&& NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NegativeInfinity)
+					return true;
+				else
+					return false;
+			}
+			#endregion
+
+			#region Inversion
+			/// <summary>
+			/// Inverts a Fraction
+			/// </summary>
+			/// <returns>The inverted Fraction (with Denominator over Numerator)</returns>
+			/// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks>
+			public Fraction Inverse()
+			{
+				// don't use the obvious constructor because we do not want it normalized at this time
+				Fraction frac = new Fraction();
+
+				frac.m_Numerator = this.m_Denominator;
+				frac.m_Denominator = this.m_Numerator;
+				return frac;
+			}
+
+			/// <summary>
+			/// Creates an inverted Fraction
+			/// </summary>
+			/// <returns>The inverted Fraction (with Denominator over Numerator)</returns>
+			/// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks>
+			public static Fraction Inverted(long value)
+			{
+				Fraction frac = new Fraction(value);
+				return frac.Inverse();
+			}
+
+			/// <summary>
+			/// Creates an inverted Fraction
+			/// </summary>
+			/// <returns>The inverted Fraction (with Denominator over Numerator)</returns>
+			/// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks>
+			public static Fraction Inverted(double value)
+			{
+				Fraction frac = new Fraction(value);
+				return frac.Inverse();
+			}
+			#endregion
+
+			#region Operators
+			#region Unary Negation operator
+			/// <summary>
+			/// Negates the Fraction
+			/// </summary>
+			/// <param name="left">The Fraction to negate</param>
+			/// <returns>The negative version of the Fraction</returns>
+			public static Fraction operator -(Fraction left)
+			{
+				return Negate(left);
+			}
+			#endregion
+
+			#region Addition operators
+			public static Fraction operator +(Fraction left, Fraction right)
+			{
+				return Add(left, right);
+			}
+	    
+			public static Fraction operator +(long left, Fraction right)
+			{
+				return Add(new Fraction(left), right);
+			}
+	    
+			public static Fraction operator +(Fraction left, long right)
+			{
+				return Add(left, new Fraction(right));
+			}
+
+			public static Fraction operator +(double left, Fraction right)
+			{
+				return Add(ToFraction(left), right);
+			}
+	    
+			public static Fraction operator +(Fraction left, double right)
+			{
+				return Add(left, ToFraction(right));
+			}
+			#endregion
+
+			#region Subtraction operators
+			public static Fraction operator -(Fraction left, Fraction right)
+			{
+				return Add(left, - right);
+			}
+	    
+			public static Fraction operator -(long left, Fraction right)
+			{
+				return Add(new Fraction(left), - right);
+			}
+	    
+			public static Fraction operator -(Fraction left, long right)
+			{
+				return Add(left, new Fraction(- right));
+			}
+
+			public static Fraction operator -(double left, Fraction right)
+			{
+				return Add(ToFraction(left), - right);
+			}
+	    
+			public static Fraction operator -(Fraction left, double right)
+			{
+				return Add(left, ToFraction(- right));
+			}
+			#endregion
+
+			#region Multiplication operators
+			public static Fraction operator *(Fraction left, Fraction right)
+			{
+				return Multiply(left, right);
+			}
+	    
+			public static Fraction operator *(long left, Fraction right)
+			{
+				return Multiply(new Fraction(left), right);
+			}
+	    
+			public static Fraction operator *(Fraction left, long right)
+			{
+				return Multiply(left, new Fraction(right));
+			}
+	    
+			public static Fraction operator *(double left, Fraction right)
+			{
+				return Multiply(ToFraction(left), right);
+			}
+	    
+			public static Fraction operator *(Fraction left, double right)
+			{
+				return Multiply(left, ToFraction(right));
+			}
+			#endregion
+
+			#region Division operators
+			public static Fraction operator /(Fraction left, Fraction right)
+			{
+				return Multiply(left, right.Inverse());
+			}
+	    
+			public static Fraction operator /(long left, Fraction right)
+			{
+				return Multiply(new Fraction(left), right.Inverse());
+			}
+	    
+			public static Fraction operator /(Fraction left, long right)
+			{
+				return Multiply(left, Inverted(right));
+			}
+	    
+			public static Fraction operator /(double left, Fraction right)
+			{
+				return Multiply(ToFraction(left), right.Inverse());
+			}
+	    
+			public static Fraction operator /(Fraction left, double right)
+			{
+				return Multiply(left, Inverted(right));
+			}
+			#endregion
+
+			#region Modulus operators
+			public static Fraction operator %(Fraction left, Fraction right)
+			{
+				return Modulus(left, right);
+			}
+	    
+			public static Fraction operator %(long left, Fraction right)
+			{
+				return Modulus(new Fraction(left), right);
+			}
+	    
+			public static Fraction operator %(Fraction left, long right)
+			{
+				return Modulus(left, right);
+			}
+	    
+			public static Fraction operator %(double left, Fraction right)
+			{
+				return Modulus(ToFraction(left), right);
+			}
+	    
+			public static Fraction operator %(Fraction left, double right)
+			{
+				return Modulus(left, right);
+			}
+			#endregion
+
+			#region Equal operators
+			public static bool operator ==(Fraction left, Fraction right)
+			{
+				return left.CompareEquality(right, false);
+			}
+
+			public static bool operator ==(Fraction left, long right)
+			{
+				return left.CompareEquality(new Fraction(right), false);
+			}
+
+			public static bool operator ==(Fraction left, double right)
+			{
+				return left.CompareEquality(new Fraction(right), false);
+			}
+			#endregion
+
+			#region Not-equal operators
+			public static bool operator !=(Fraction left, Fraction right)
+			{
+				return left.CompareEquality(right, true);
+			}
+
+			public static bool operator !=(Fraction left, long right)
+			{
+				return left.CompareEquality(new Fraction(right), true);
+			}
+	        
+			public static bool operator !=(Fraction left, double right)
+			{
+				return left.CompareEquality(new Fraction(right), true);
+			}
+			#endregion
+
+			#region Inequality operators
+			/// <summary>
+			/// Compares two Fractions to see if left is less than right
+			/// </summary>
+			/// <param name="left">The first Fraction</param>
+			/// <param name="right">The second Fraction</param>
+			/// <returns>True if <paramref name="left">left</paramref> is less
+			/// than <paramref name="right">right</paramref></returns>
+			/// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks>
+			/// <exception cref="FractionException">Throws an error if overflows occur while computing the 
+			/// difference with an InnerException of OverflowException</exception>
+			public static bool operator <(Fraction left, Fraction right)
+			{
+				return left.CompareTo(right) < 0;
+			}
+
+			/// <summary>
+			/// Compares two Fractions to see if left is greater than right
+			/// </summary>
+			/// <param name="left">The first Fraction</param>
+			/// <param name="right">The second Fraction</param>
+			/// <returns>True if <paramref name="left">left</paramref> is greater
+			/// than <paramref name="right">right</paramref></returns>
+			/// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks>
+			/// <exception cref="FractionException">Throws an error if overflows occur while computing the 
+			/// difference with an InnerException of OverflowException</exception>
+			public static bool operator >(Fraction left, Fraction right)
+			{
+				return left.CompareTo(right) > 0;
+			}
+
+			/// <summary>
+			/// Compares two Fractions to see if left is less than or equal to right
+			/// </summary>
+			/// <param name="left">The first Fraction</param>
+			/// <param name="right">The second Fraction</param>
+			/// <returns>True if <paramref name="left">left</paramref> is less than or 
+			/// equal to <paramref name="right">right</paramref></returns>
+			/// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks>
+			/// <exception cref="FractionException">Throws an error if overflows occur while computing the 
+			/// difference with an InnerException of OverflowException</exception>
+			public static bool operator <=(Fraction left, Fraction right)
+			{
+				return left.CompareTo(right) <= 0;
+			}
+	        
+			/// <summary>
+			/// Compares two Fractions to see if left is greater than or equal to right
+			/// </summary>
+			/// <param name="left">The first Fraction</param>
+			/// <param name="right">The second Fraction</param>
+			/// <returns>True if <paramref name="left">left</paramref> is greater than or 
+			/// equal to <paramref name="right">right</paramref></returns>
+			/// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks>
+			/// <exception cref="FractionException">Throws an error if overflows occur while computing the 
+			/// difference with an InnerException of OverflowException</exception>
+			public static bool operator >=(Fraction left, Fraction right)
+			{
+				return left.CompareTo(right) >= 0;
+			}
+			#endregion
+
+			#region Implict conversion from primitive operators
+			/// <summary>
+			/// Implicit conversion of a long integral value to a Fraction
+			/// </summary>
+			/// <param name="value">The long integral value to convert</param>
+			/// <returns>A Fraction whose denominator is 1</returns>
+			public static implicit operator Fraction(long value)
+			{
+				return new Fraction(value);
+			}
+
+			/// <summary>
+			/// Implicit conversion of a double floating point value to a Fraction
+			/// </summary>
+			/// <param name="value">The double value to convert</param>
+			/// <returns>A reduced Fraction</returns>
+			public static implicit operator Fraction(double value)
+			{
+				return new Fraction(value);
+			}
+
+			/// <summary>
+			/// Implicit conversion of a string to a Fraction
+			/// </summary>
+			/// <param name="value">The string to convert</param>
+			/// <returns>A reduced Fraction</returns>
+			public static implicit operator Fraction(string value)
+			{
+				return new Fraction(value);
+			}
+			#endregion
+
+			#region Explicit converstion to primitive operators
+			/// <summary>
+			/// Explicit conversion from a Fraction to an integer
+			/// </summary>
+			/// <param name="frac">the Fraction to convert</param>
+			/// <returns>The integral representation of the Fraction</returns>
+			public static explicit operator int(Fraction frac)
+			{
+				return frac.ToInt32();
+			}
+
+			/// <summary>
+			/// Explicit conversion from a Fraction to an integer
+			/// </summary>
+			/// <param name="frac">The Fraction to convert</param>
+			/// <returns>The integral representation of the Fraction</returns>
+			public static explicit operator long(Fraction frac)
+			{
+				return frac.ToInt64();
+			}
+
+			/// <summary>
+			/// Explicit conversion from a Fraction to a double floating-point value
+			/// </summary>
+			/// <param name="frac">The Fraction to convert</param>
+			/// <returns>The double representation of the Fraction</returns>
+			public static explicit operator double(Fraction frac)
+			{
+				return frac.ToDouble();
+			}
+
+			/// <summary>
+			/// Explicit conversion from a Fraction to a string
+			/// </summary>
+			/// <param name="frac">the Fraction to convert</param>
+			/// <returns>The string representation of the Fraction</returns>
+			public static implicit operator string(Fraction frac)
+			{
+				return frac.ToString();
+			}
+			#endregion
+			#endregion
+
+			#region Equals and GetHashCode overrides
+			/// <summary>
+			/// Compares for equality the current Fraction to the value passed.
+			/// </summary>
+			/// <param name="obj">A  Fraction,</param>
+			/// <returns>True if the value equals the current fraction, false otherwise (including for
+			/// non-Fraction types or null object.</returns>
+			public override bool Equals(object obj)
+			{
+				if (obj == null	|| ! (obj is Fraction))
+					return false;
+
+				try 
+				{
+					Fraction right = (Fraction)obj;
+					return this.CompareEquality(right, false);
+				}
+				catch
+				{
+					// can't throw in an Equals!
+					return false;
+				}
+			}
+	        
+			/// <summary>
+			/// Returns a hash code generated from the current Fraction
+			/// </summary>
+			/// <returns>The hash code</returns>
+			/// <remarks>Reduces (in-place) the Fraction first.</remarks>
+			public override int GetHashCode()
+			{
+				// insure we're as close to normalized as possible first
+				ReduceFraction(ref this);
+
+				int numeratorHash = this.m_Numerator.GetHashCode();
+				int denominatorHash = this.m_Denominator.GetHashCode();
+
+				return (numeratorHash ^ denominatorHash);
+			}
+			#endregion
+
+			#region IComparable member and type-specific version
+			/// <summary>
+			/// Compares an object to this Fraction
+			/// </summary>
+			/// <param name="obj">The object to compare against (null is less than everything)</param>
+			/// <returns>-1 if this is less than <paramref name="obj"></paramref>,
+			///  0 if they are equal,
+			///  1 if this is greater than <paramref name="obj"></paramref></returns>
+			/// <remarks>Will convert an object from longs, doubles, and strings as this is a value-type.</remarks>
+			public int CompareTo(object obj)
+			{
+				if (obj == null)
+					return 1;	// null is less than anything
+
+				Fraction right;
+
+				if (obj is Fraction)
+					right = (Fraction)obj;
+				else if (obj is long)
+					right = (long)obj;
+				else if (obj is double)
+					right = (double)obj;
+				else if (obj is string)
+					right = (string)obj;
+				else
+					throw new ArgumentException("Must be convertible to Fraction", "obj");
+
+				return this.CompareTo(right);
+			}
+
+			/// <summary>
+			/// Compares this Fraction to another Fraction
+			/// </summary>
+			/// <param name="right">The Fraction to compare against</param>
+			/// <returns>-1 if this is less than <paramref name="right"></paramref>,
+			///  0 if they are equal,
+			///  1 if this is greater than <paramref name="right"></paramref></returns>
+			public int CompareTo(Fraction right)
+			{
+				// if left is an indeterminate, punt to the helper...
+				if (this.m_Denominator == 0)
+				{
+					return IndeterminantCompare(NormalizeIndeterminate(this.m_Numerator), right);
+				}
+
+				// if right is an indeterminate, punt to the helper...
+				if (right.m_Denominator == 0)
+				{
+					// note sign-flip...
+					return - IndeterminantCompare(NormalizeIndeterminate(right.m_Numerator), this);
+				}
+
+				// they're both normal Fractions
+				CrossReducePair(ref this, ref right);
+
+				try
+				{
+					checked
+					{
+						long leftScale = this.m_Numerator * right.m_Denominator;
+						long rightScale = this.m_Denominator * right.m_Numerator;
+
+						if (leftScale < rightScale)
+							return -1;
+						else if (leftScale > rightScale)
+							return 1;
+						else
+							return 0;
+					}
+				}
+				catch (Exception e)
+				{
+					throw new FractionException(string.Format("CompareTo({0}, {1}) error", this, right), e);
+				}
+			}
+			#endregion
+
+			#region IFormattable Members
+			string System.IFormattable.ToString(string format, IFormatProvider formatProvider)
+			{
+				return this.m_Numerator.ToString(format, formatProvider) + "/" + this.m_Denominator.ToString(format, formatProvider);
+			}
+			#endregion
+
+			#region Reduction
+			/// <summary>
+			/// Reduces (simplifies) a Fraction by dividing down to lowest possible denominator (via GCD)
+			/// </summary>
+			/// <param name="frac">The Fraction to be reduced [WILL BE MODIFIED IN PLACE]</param>
+			/// <remarks>Modifies the input arguments in-place! Will normalize the NaN and infinites
+			/// representation. Will set Denominator to 1 for any zero numerator. Moves sign to the
+			/// Numerator.</remarks>
+			/// <example>2/4 will be reduced to 1/2</example>
+			public static void ReduceFraction(ref Fraction frac)
+			{
+				// clean up the NaNs and infinites
+				if (frac.m_Denominator == 0)
+				{
+					frac.m_Numerator = (long)NormalizeIndeterminate(frac.m_Numerator);
+					return;
+				}
+
+				// all forms of zero are alike.
+				if (frac.m_Numerator == 0)
+				{
+					frac.m_Denominator = 1;
+					return;
+				}
+	            
+				long iGCD = GCD(frac.m_Numerator, frac.m_Denominator);
+				frac.m_Numerator /= iGCD;
+				frac.m_Denominator /= iGCD;
+	        
+				// if negative sign in denominator
+				if ( frac.m_Denominator < 0 )
+				{
+					//move negative sign to numerator
+					frac.m_Numerator = - frac.m_Numerator;
+					frac.m_Denominator = - frac.m_Denominator;  
+				}
+			}
+
+			/// <summary>
+			/// Cross-reduces a pair of Fractions so that we have the best GCD-reduced values for multiplication
+			/// </summary>
+			/// <param name="frac1">The first Fraction [WILL BE MODIFIED IN PLACE]</param>
+			/// <param name="frac2">The second Fraction [WILL BE MODIFIED IN PLACE]</param>
+			/// <remarks>Modifies the input arguments in-place!</remarks>
+			/// <example>(3/4, 5/9) = (1/4, 5/3)</example>
+			public static void CrossReducePair(ref Fraction frac1, ref Fraction frac2)
+			{
+				// leave the indeterminates alone!
+				if (frac1.m_Denominator == 0 || frac2.m_Denominator == 0)
+					return;
+
+				long gcdTop = GCD(frac1.m_Numerator, frac2.m_Denominator);
+				frac1.m_Numerator = frac1.m_Numerator / gcdTop;
+				frac2.m_Denominator = frac2.m_Denominator / gcdTop;
+
+				long gcdBottom = GCD(frac1.m_Denominator, frac2.m_Numerator);
+				frac2.m_Numerator = frac2.m_Numerator / gcdBottom;
+				frac1.m_Denominator = frac1.m_Denominator / gcdBottom;
+			}
+			#endregion
+
+			#region Implementation
+			#region Convert a double to a fraction
+			private static Fraction ConvertPositiveDouble(int sign, double inValue)
+			{
+				// Shamelessly stolen from http://homepage.smc.edu/kennedy_john/CONFRAC.PDF
+				// with AccuracyFactor == double.Episilon
+				long fractionNumerator = (long)inValue;
+				double fractionDenominator = 1;
+				double previousDenominator = 0;
+				double remainingDigits = inValue;
+				int maxIterations = 594;	// found at http://www.ozgrid.com/forum/archive/index.php/t-22530.html
+
+				while (remainingDigits != Math.Floor(remainingDigits) 
+					&& Math.Abs(inValue - (fractionNumerator / fractionDenominator)) > double.Epsilon)
+				{
+					remainingDigits = 1.0 / (remainingDigits - Math.Floor(remainingDigits));
+
+					double scratch = fractionDenominator;
+
+					fractionDenominator =(Math.Floor(remainingDigits) * fractionDenominator) + previousDenominator;
+					fractionNumerator = (long)(inValue * fractionDenominator + 0.5);
+
+					previousDenominator = scratch;
+
+					if (maxIterations-- < 0)
+						break;
+				}
+
+				return new Fraction(fractionNumerator * sign, (long)fractionDenominator);
+			}
+			#endregion
+
+			#region Equality helper
+			/// <summary>
+			/// Compares for equality the current Fraction to the value passed.
+			/// </summary>
+			/// <param name="right">A Fraction to compare against</param>
+			/// <param name="notEqualCheck">If true, we're looking for not-equal</param>
+			/// <returns>True if the <paramref name="right"></paramref> equals the current 
+			/// fraction, false otherwise. If comparing two NaNs, they are always equal AND
+			/// not-equal.</returns>
+			private bool CompareEquality(Fraction right, bool notEqualCheck)
+			{
+				// insure we're normalized first
+				ReduceFraction(ref this);
+
+				// now normalize the comperand
+				ReduceFraction(ref right);
+
+				if (this.m_Numerator == right.m_Numerator && this.m_Denominator == right.m_Denominator)
+				{
+					// special-case rule, two NaNs are always both equal
+					if (notEqualCheck && this.IsNaN())
+						return true;
+					else
+						return ! notEqualCheck;
+				}
+				else
+				{
+					return notEqualCheck;
+				}
+			}
+			#endregion
+
+			#region Comparison helper
+			/// <summary>
+			/// Determines how this Fraction, of an indeterminate type, compares to another Fraction
+			/// </summary>
+			/// <param name="leftType">What kind of indeterminate</param>
+			/// <param name="right">The other Fraction to compare against</param>
+			/// <returns>-1 if this is less than <paramref name="right"></paramref>,
+			///  0 if they are equal,
+			///  1 if this is greater than <paramref name="right"></paramref></returns>
+			/// <remarks>NaN is less than anything except NaN and Negative Infinity. Negative Infinity is less
+			/// than anything except Negative Infinity. Positive Infinity is greater than anything except
+			/// Positive Infinity.</remarks>
+			private static int IndeterminantCompare(Indeterminates leftType, Fraction right)
+			{
+				switch (leftType)
+				{
+					case Indeterminates.NaN:
+						// A NaN is...
+						if (right.IsNaN())
+							return 0;	// equal to a NaN
+						else if (right.IsNegativeInfinity())
+							return 1;	// great than Negative Infinity
+						else
+							return -1;	// less than anything else
+
+					case Indeterminates.NegativeInfinity:
+						// Negative Infinity is...
+						if (right.IsNegativeInfinity())
+							return 0;	// equal to Negative Infinity
+						else
+							return -1;	// less than anything else
+
+					case Indeterminates.PositiveInfinity:
+						if (right.IsPositiveInfinity())
+							return 0;	// equal to Positive Infinity
+						else
+							return 1;	// greater than anything else
+
+					default:
+						// this CAN'T happen, something VERY wrong is going on...
+						return 0;
+				}
+			}
+			#endregion
+
+			#region Math helpers
+			/// <summary>
+			/// Negates the Fraction
+			/// </summary>
+			/// <param name="frac">Value to negate</param>
+			/// <returns>A new Fraction that is sign-flipped from the input</returns>
+			private static Fraction Negate(Fraction frac)
+			{
+				// for a NaN, it's still a NaN
+				return new Fraction( - frac.m_Numerator, frac.m_Denominator);
+			}
+
+			/// <summary>
+			/// Adds two Fractions
+			/// </summary>
+			/// <param name="left">A Fraction</param>
+			/// <param name="right">Another Fraction</param>
+			/// <returns>Sum of the Fractions. Returns NaN if either Fraction is a NaN.</returns>
+			/// <exception cref="FractionException">Will throw if an overflow occurs when computing the
+			/// GCD-normalized values.</exception>
+			private static Fraction Add(Fraction left, Fraction right)
+			{
+				if (left.IsNaN() || right.IsNaN())
+					return NaN;
+
+				long gcd = GCD(left.m_Denominator, right.m_Denominator); // cannot return less than 1
+				long leftDenominator = left.m_Denominator / gcd;
+				long rightDenominator = right.m_Denominator / gcd;
+
+				try
+				{
+					checked
+					{
+						long numerator = left.m_Numerator * rightDenominator + right.m_Numerator * leftDenominator;
+						long denominator = leftDenominator * rightDenominator * gcd;
+
+						return new Fraction(numerator, denominator);
+					}
+				}
+				catch (Exception e)
+				{
+					throw new FractionException("Add error", e);
+				}
+			}
+	    
+			/// <summary>
+			/// Multiplies two Fractions
+			/// </summary>
+			/// <param name="left">A Fraction</param>
+			/// <param name="right">Another Fraction</param>
+			/// <returns>Product of the Fractions. Returns NaN if either Fraction is a NaN.</returns>
+			/// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 
+			/// insure only the unavoidable overflows occur.</exception>
+			private static Fraction Multiply(Fraction left, Fraction right)
+			{
+				if (left.IsNaN() || right.IsNaN())
+					return NaN;
+
+				// this would be unsafe if we were not a ValueType, because we would be changing the
+				// caller's values.  If we change back to a class, must use temporaries
+				CrossReducePair(ref left, ref right);
+
+				try
+				{
+					checked
+					{
+						long numerator = left.m_Numerator * right.m_Numerator;
+						long denominator = left.m_Denominator * right.m_Denominator;
+
+						return new Fraction(numerator, denominator);
+					}
+				}
+				catch (Exception e)
+				{
+					throw new FractionException("Multiply error", e);
+				}
+			}
+
+			/// <summary>
+			/// Returns the modulus (remainder after dividing) two Fractions
+			/// </summary>
+			/// <param name="left">A Fraction</param>
+			/// <param name="right">Another Fraction</param>
+			/// <returns>Modulus of the Fractions. Returns NaN if either Fraction is a NaN.</returns>
+			/// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 
+			/// insure only the unavoidable overflows occur.</exception>
+			private static Fraction Modulus(Fraction left, Fraction right)
+			{
+				if (left.IsNaN() || right.IsNaN())
+					return NaN;
+
+				try
+				{
+					checked
+					{
+						// this will discard any fractional places...
+						Int64 quotient = (Int64)(left / right);
+						Fraction whole = new Fraction(quotient * right.m_Numerator, right.m_Denominator);
+						return left - whole;
+					}
+				}
+				catch (Exception e)
+				{
+					throw new FractionException("Modulus error", e);
+				}
+			}
+
+			/// <summary>
+			/// Computes the greatest common divisor for two values
+			/// </summary>
+			/// <param name="left">One value</param>
+			/// <param name="right">Another value</param>
+			/// <returns>The greatest common divisor of the two values</returns>
+			/// <example>(6, 9) returns 3 and (11, 4) returns 1</example>
+			private static long GCD(long left, long right)
+			{
+				// take absolute values
+				if (left < 0)
+					left = - left;
+
+				if (right < 0)
+					right = - right;
+	            
+				// if we're dealing with any zero or one, the GCD is 1
+				if (left < 2 || right < 2)
+					return 1;
+
+				do
+				{
+					if (left < right)
+					{
+						long temp = left;  // swap the two operands
+						left = right;
+						right = temp;
+					}
+
+					left %= right;
+				} while (left != 0);
+
+				return right;
+			}
+			#endregion
+
+			#region Indeterminate helpers
+			/// <summary>
+			/// Gives the culture-related representation of the indeterminate types NaN, PositiveInfinity
+			/// and NegativeInfinity
+			/// </summary>
+			/// <param name="numerator">The value in the numerator</param>
+			/// <returns>The culture-specific string representation of the implied value</returns>
+			/// <remarks>Only the sign and zero/non-zero information is relevant.</remarks>
+			private static string IndeterminateTypeName(long numerator)
+			{
+				// could also be NumberFormatInfo.InvariantInfo
+				System.Globalization.NumberFormatInfo info = NumberFormatInfo.CurrentInfo;
+
+				switch (NormalizeIndeterminate(numerator))
+				{
+					case Indeterminates.PositiveInfinity:
+						return info.PositiveInfinitySymbol;
+
+					case Indeterminates.NegativeInfinity:
+						return info.NegativeInfinitySymbol;
+
+					default:    // if this happens, something VERY wrong is going on...
+					case Indeterminates.NaN:
+						return info.NaNSymbol;
+				}
+			}
+
+			/// <summary>
+			/// Gives the normalize representation of the indeterminate types NaN, PositiveInfinity
+			/// and NegativeInfinity
+			/// </summary>
+			/// <param name="numerator">The value in the numerator</param>
+			/// <returns>The normalized version of the indeterminate type</returns>
+			/// <remarks>Only the sign and zero/non-zero information is relevant.</remarks>
+			private static Indeterminates NormalizeIndeterminate(long numerator)
+			{
+				switch (Math.Sign(numerator))
+				{
+					case 1:
+						return Indeterminates.PositiveInfinity;
+
+					case -1:
+						return Indeterminates.NegativeInfinity;
+
+					default:    // if this happens, your Math.Sign function is BROKEN!
+					case 0:
+						return Indeterminates.NaN;
+				}
+			}
+
+			// These are used to represent the indeterminate with a Denominator of zero
+			private enum Indeterminates
+			{
+				NaN = 0
+				, PositiveInfinity = 1
+				, NegativeInfinity = -1
+			}
+			#endregion
+
+			#region Member variables
+			private long m_Numerator;
+			private long m_Denominator;
+			#endregion
+			#endregion
+		}   //end class Fraction
+
+		/// <summary>
+		/// Exception class for Fraction, derived from System.Exception
+		/// </summary>
+		public class FractionException : Exception
+		{
+			/// <summary>
+			/// Constructs a FractionException
+			/// </summary>
+			/// <param name="Message">String associated with the error message</param>
+			/// <param name="InnerException">Actual inner exception caught</param>
+			public FractionException(string Message, Exception InnerException) : base(Message, InnerException)
+			{
+			}
+		}   //end class FractionException
+	}   //end namespace Mehroz
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/LiblrsWrapper.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/LiblrsWrapper.cs	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/LiblrsWrapper.cs	(revision 10198)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Testliblrs {
+  public static class LiblrsWrapper {
+    [System.Runtime.InteropServices.DllImportAttribute("liblrs.dll", EntryPoint = "calculate_volume")]
+    public static extern double calculate_volume(int numPoints, int dimension, [In] Int32[] num, [In] Int32[] den);
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Program.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Program.cs	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Program.cs	(revision 10198)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+
+namespace Testliblrs {
+  class Program {
+    static void Main(string[] args) {
+      const int numPoints = 4;
+      const int dimension = 3;
+
+      int[] num = new int[dimension * numPoints];
+      int[] den = new int[dimension * numPoints];
+
+      num[0] = 1;
+      num[1] = 2;
+      num[2] = 2;
+
+      num[3] = 3;
+      num[4] = 4;
+      num[5] = 2;
+
+      num[6] = 3;
+      num[7] = 6;
+      num[8] = 2;
+
+      num[9] = 7;
+      num[10] = 8;
+      num[11] = 2;
+
+      den[0] = 1;
+      den[1] = 1;
+      den[2] = 1;
+      den[3] = 1;
+      den[4] = 1;
+      den[5] = 1;
+      den[6] = 1;
+      den[7] = 1;
+      den[8] = 1;
+      den[9] = 1;
+      den[10] = 1;
+      den[11] = 1;
+
+      double volume = LiblrsWrapper.calculate_volume(numPoints, dimension, num, den);
+      Console.WriteLine("Volume is: " + volume);
+    }
+  }
+}
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Properties/AssemblyInfo.cs
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Properties/AssemblyInfo.cs	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Properties/AssemblyInfo.cs	(revision 10198)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Testliblrs")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Testliblrs")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("049676a5-2c01-4b8a-887f-7a55f3c610be")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Testliblrs.csproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Testliblrs.csproj	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/Testliblrs/Testliblrs.csproj	(revision 10198)
@@ -0,0 +1,96 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{7D0D7893-468C-4B06-8B48-6358219D9ADD}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Testliblrs</RootNamespace>
+    <AssemblyName>Testliblrs</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="FractionClass.cs" />
+    <Compile Include="LiblrsWrapper.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 4.5</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/ctest_liblrs.vcxproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/ctest_liblrs.vcxproj	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/ctest_liblrs.vcxproj	(revision 10198)
@@ -0,0 +1,82 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}</ProjectGuid>
+    <RootNamespace>ctest_liblrs</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)Debug;$(LibraryPath)</LibraryPath>
+    <ReferencePath>$(SolutionDir)Debug;$(ReferencePath)</ReferencePath>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath>
+    <LibraryPath>$(SolutionDir)\Release;$(LibraryPath)</LibraryPath>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <AdditionalDependencies>liblrs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalDependencies>$(SolutionDir)Release\liblrs.lib;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="main.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/main.cpp
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/main.cpp	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/main.cpp	(revision 10198)
@@ -0,0 +1,68 @@
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <extfunc.h>
+
+int main (int argc, char *argv[])
+{
+  const int numPoints = 4;
+  const int dimension = 3;
+
+  long num[dimension*numPoints];
+  long den[dimension*numPoints];
+
+  num[0] = 1;
+  num[1] = 2;
+  num[2] = 2;
+
+  num[3] = 3;
+  num[4] = 4;
+  num[5] = 2;
+
+  num[6] = 3;
+  num[7] = 6;
+  num[8] = 2;
+
+  num[9] = 7;
+  num[10] = 8;
+  num[11] = 2;
+
+  den[0] = 1;
+  den[1] = 1;
+  den[2] = 1;
+  den[3] = 1;
+  den[4] = 1;
+  den[5] = 1;
+  den[6] = 1;
+  den[7] = 1;
+  den[8] = 1;
+  den[9] = 1;
+  den[10] = 1;
+  den[11] = 1;
+
+
+  double volume = calculate_volume(numPoints, dimension, num, den);
+  printf ("Volume is: %f", volume);
+  return 0;
+}
+
+
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.c
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.c	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.c	(revision 10198)
@@ -0,0 +1,139 @@
+/* HeuristicLab
+* Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+*
+* This file is part of HeuristicLab.
+*
+* HeuristicLab is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* HeuristicLab is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Source based on lrslib's chdemo.c 
+Copyright: David Avis 2001, avis@cs.mcgill.ca 
+Licensed under the GNU GPL
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "extfunc.h"
+
+ __declspec(dllexport) double calculate_volume(int numPoints, int dimension, long *num, long *den) {
+  double result = 0.0;
+
+  lrs_dic *P;	/* structure for holding current dictionary and indices  */
+  lrs_dat *Q;	/* structure for holding static problem data             */
+  lrs_mp_vector output;	/* one line of output:ray,vertex,facet,linearity */
+  lrs_mp_matrix Lin;    /* holds input linearities if any are found      */
+
+  long i;
+  long col;    	/* output column index for dictionary            */
+
+  printf("\nnumPoints: %d", numPoints);
+  printf("\ndimension: %d", dimension);
+  printf("\nnum: %d", num[11]);
+  printf("\nden: %d", den[11]);
+  printf("\nsizeofint: %d", sizeof(int));
+  printf("\nsizeoflong: %d", sizeof(long));    
+
+  /* Global initialization - done once */   
+  if ( !lrs_init ("\nHeuristicLab lrslib wrapper"))
+    return -1.0;
+
+  /* allocate and init structure for static problem data */
+  Q = lrs_alloc_dat ("LRS globals");
+  if (Q == NULL)
+    return -1.0;
+
+  /* now flags in lrs_dat can be set */     
+  Q->m=numPoints;           /* number of input rows = number of vertices   */ 
+  Q->n=dimension;/*TODO: +1?*/           /* number of input columns   (dimension + 1 )  */
+  Q->hull = TRUE;     /* convex hull problem: facet enumeration      */
+  Q->polytope= TRUE;  /* input is a polytope                         */
+  Q->getvolume= TRUE; /* compute the volume                          */
+
+  output = lrs_alloc_mp_vector (Q->n);
+
+  
+  P = lrs_alloc_dic (Q);   /* allocate and initialize lrs_dic      */
+  if (P == NULL)
+    return -1.0;
+       
+  /* Build polytope */   
+  fill_data(P,Q, num, den);
+    
+  /* code from here is borrowed from lrs_main */
+
+  /* Pivot to a starting dictionary                      */    
+  if (!lrs_getfirstbasis (&P, Q, &Lin, FALSE))
+    return -1.0;
+
+  /* We initiate reverse search from this dictionary       */
+  /* getting new dictionaries until the search is complete */
+  /* User can access each output line from output which is */
+  /* vertex/ray/facet from the lrs_mp_vector output        */
+  do
+  {
+    for (col = 0; col <= P->d; col++)
+      if (lrs_getsolution (P, Q, output, col))
+        lrs_printoutput (Q, output);
+  }
+  while (lrs_getnextbasis (&P, Q, FALSE));
+  result = get_volume(P,Q);
+
+  lrs_printtotals (P, Q);    /* print final totals */
+
+  /* free space : do not change order of next 3 lines! */
+  lrs_clear_mp_vector (output, Q->n);
+  lrs_free_dic (P,Q);           /* deallocate lrs_dic */
+  lrs_free_dat (Q);             /* deallocate lrs_dat */
+  lrs_close ("HeuristicLab lrslib wrapper");        
+
+  return result;
+}
+
+double get_volume (lrs_dic *P, lrs_dat *Q) {
+  double vol;
+
+  if (Q->getvolume)
+  {
+    rescalevolume (P, Q, Q->Nvolume, Q->Dvolume);
+
+    if (Q->polytope){
+      prat ("\n*Volume=", Q->Nvolume, Q->Dvolume);
+    } else {
+      prat ("\n*Pseudovolume=", Q->Nvolume, Q->Dvolume); 
+    }          
+
+    rattodouble (Q->Nvolume, Q->Dvolume, &vol);
+    return vol;
+  }
+  return -1.0;
+}
+
+void fill_data (lrs_dic *P, lrs_dat *Q, long *num, long *den)   
+{
+  int i, j;
+  long *tmpNum = (long*)malloc(sizeof(long)* Q->n);
+  long *tmpDen = (long*)malloc(sizeof(long)* Q->n);
+
+  for (i=0;i<Q->m;i++)
+  {     
+    for(j=0;j<Q->n;j++) {
+      tmpNum[j] = num[i*Q->n+j];
+      tmpDen[j] = den[i*Q->n+j];
+    }
+    lrs_set_row(P,Q,i+1,tmpNum,tmpDen,GE);          
+  }
+  free(tmpNum);
+  free(tmpDen);
+} 
+
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.h
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.h	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.h	(revision 10198)
@@ -0,0 +1,37 @@
+/* HeuristicLab
+* Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+*
+* This file is part of HeuristicLab.
+*
+* HeuristicLab is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* HeuristicLab is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* Source based on lrslib's chdemo.c 
+Copyright: David Avis 2001, avis@cs.mcgill.ca 
+Licensed under the GNU GPL
+*/
+
+#include "lrslib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_data (lrs_dic *P, lrs_dat *Q, long *num, long *den);  
+double get_volume (lrs_dic *P, lrs_dat *Q);
+__declspec(dllexport) double calculate_volume(int numPoints, int dimension, long *num, long *den);
+
+#ifdef __cplusplus
+}
+#endif
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs License.txt
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs License.txt	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs License.txt	(revision 10198)
@@ -0,0 +1,344 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.sln
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.sln	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.sln	(revision 10198)
@@ -0,0 +1,66 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblrs", "liblrs.vcxproj", "{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testliblrs", "..\Testliblrs\Testliblrs.csproj", "{7D0D7893-468C-4B06-8B48-6358219D9ADD}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctest_liblrs", "..\ctest_liblrs\ctest_liblrs.vcxproj", "{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|Mixed Platforms = Debug|Mixed Platforms
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Any CPU = Release|Any CPU
+		Release|Mixed Platforms = Release|Mixed Platforms
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|Any CPU.ActiveCfg = Debug|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|Win32.Build.0 = Debug|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|x64.ActiveCfg = Debug|x64
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Debug|x64.Build.0 = Debug|x64
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|Any CPU.ActiveCfg = Release|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|Win32.ActiveCfg = Release|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|Win32.Build.0 = Release|Win32
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|x64.ActiveCfg = Release|x64
+		{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}.Release|x64.Build.0 = Release|x64
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|Win32.ActiveCfg = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Debug|x64.Build.0 = Debug|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|Win32.ActiveCfg = Release|Any CPU
+		{7D0D7893-468C-4B06-8B48-6358219D9ADD}.Release|x64.ActiveCfg = Release|Any CPU
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Any CPU.ActiveCfg = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Mixed Platforms.Build.0 = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Win32.Build.0 = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.ActiveCfg = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.Build.0 = Debug|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Any CPU.ActiveCfg = Release|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Mixed Platforms.ActiveCfg = Release|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Mixed Platforms.Build.0 = Release|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Win32.ActiveCfg = Release|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Win32.Build.0 = Release|Win32
+		{B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|x64.ActiveCfg = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.vcxproj
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.vcxproj	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.vcxproj	(revision 10198)
@@ -0,0 +1,106 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="extfunc.c" />
+    <ClCompile Include="lrslib.c" />
+    <ClCompile Include="lrsmp.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="extfunc.h" />
+    <ClInclude Include="lrslib.h" />
+    <ClInclude Include="lrsmp.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{2FDA9BB3-C904-4A88-BDD7-3F6B3B65C7F7}</ProjectGuid>
+    <RootNamespace>liblrs</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v110</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <PlatformToolset>v110</PlatformToolset>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <PlatformToolset>v110</PlatformToolset>
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>false</SDLCheck>
+      <CompileAs>Default</CompileAs>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>false</SDLCheck>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);B64</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions);B64</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.c
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.c	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.c	(revision 10198)
@@ -0,0 +1,4626 @@
+/* lrslib.c     library code for lrs                     */
+
+/* last modified: 2012.6.1                               */
+/* truncate needs mod to supress last pivot */
+/* need to add a test for non-degenerate pivot step in reverse I guess */
+/* Copyright: David Avis 2003,2011 avis@cs.mcgill.ca         */
+
+/* This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "lrslib.h"
+
+/* Globals; these need to be here, rather than lrslib.h, so they are
+   not multiply defined. */
+
+FILE *lrs_cfp;			/* output file for checkpoint information       */
+FILE *lrs_ifp;			/* input file pointer       */
+FILE *lrs_ofp;			/* output file pointer      */
+
+unsigned long dict_count, dict_limit, cache_tries, cache_misses;
+
+/* Variables and functions global to this file only */
+static long lrs_checkpoint_seconds = 0;
+
+static long lrs_global_count = 0;	/* Track how many lrs_dat records are 
+					   allocated */
+
+static lrs_dat_p *lrs_global_list[MAX_LRS_GLOBALS + 1];
+
+
+static void lrs_dump_state ();
+
+
+/*******************************/
+/* functions  for external use */
+/*******************************/
+
+/*******************************************************/
+/* lrs_main is driver for lrs.c does H/V enumeration   */
+/* showing function calls intended for public use      */
+/*******************************************************/
+long
+lrs_main (int argc, char *argv[])
+
+{
+
+  lrs_dic *P;			/* structure for holding current dictionary and indices */
+  lrs_dat *Q;			/* structure for holding static problem data            */
+
+  lrs_mp_vector output;		/* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp_matrix Lin;		/* holds input linearities if any are found             */
+  long col;			/* output column index for dictionary                   */
+  long startcol = 0;
+  long prune = FALSE;		/* if TRUE, getnextbasis will prune tree and backtrack  */
+
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+/* they default to stdin and stdout, but may be overidden by command line parms. */
+
+
+/***************************************************
+ Step 0: 
+  Do some global initialization that should only be done once,
+  no matter how many lrs_dat records are allocated. db
+
+***************************************************/
+
+  if ( !lrs_init ("\n*lrs:"))
+    return 1;
+  printf(AUTHOR);
+
+/*********************************************************************************/
+/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem                      */
+/*********************************************************************************/
+
+  Q = lrs_alloc_dat ("LRS globals");	/* allocate and init structure for static problem data */
+
+  if (Q == NULL)
+    return 1;
+
+  if (!lrs_read_dat (Q, argc, argv))	/* read first part of problem data to get dimensions   */
+    return 1;                   	/* and problem type: H- or V- input representation     */
+
+  P = lrs_alloc_dic (Q);	/* allocate and initialize lrs_dic                     */
+  if (P == NULL)
+    return 1;
+
+  if (!lrs_read_dic (P, Q))	/* read remainder of input to setup P and Q            */
+    return 1;
+
+  output = lrs_alloc_mp_vector (Q->n);	/* output holds one line of output from dictionary     */
+
+
+/*********************************************************************************/
+/* Step 2: Find a starting cobasis from default of specified order               */
+/*         P is created to hold  active dictionary data and may be cached        */
+/*         Lin is created if necessary to hold linearity space                   */
+/*         Print linearity space if any, and retrieve output from first dict.    */
+/*********************************************************************************/
+
+  if (!lrs_getfirstbasis (&P, Q, &Lin, FALSE))
+    return 1;
+
+  /* Pivot to a starting dictionary                      */
+  /* There may have been column redundancy               */
+  /* If so the linearity space is obtained and redundant */
+  /* columns are removed. User can access linearity space */
+  /* from lrs_mp_matrix Lin dimensions nredundcol x d+1  */
+
+
+
+  if (Q->homogeneous && Q->hull)
+    startcol++;			/* col zero not treated as redundant   */
+
+  for (col = startcol; col < Q->nredundcol; col++)	/* print linearity space               */
+    lrs_printoutput (Q, Lin[col]);	/* Array Lin[][] holds the coeffs.     */
+
+
+
+/*********************************************************************************/
+/* Step 3: Terminate if lponly option set, otherwise initiate a reverse          */
+/*         search from the starting dictionary. Get output for each new dict.    */
+/*********************************************************************************/
+
+
+
+  /* We initiate reverse search from this dictionary       */
+  /* getting new dictionaries until the search is complete */
+  /* User can access each output line from output which is */
+  /* vertex/ray/facet from the lrs_mp_vector output         */
+  /* prune is TRUE if tree should be pruned at current node */
+  do
+    {
+     prune=lrs_checkbound(P,Q);
+     if (!prune)
+      for (col = 0; col <= P->d; col++)
+	if (lrs_getsolution (P, Q, output, col))
+	    lrs_printoutput (Q, output);
+    }
+  while (!Q->lponly && lrs_getnextbasis (&P, Q, prune));
+
+  if (Q->lponly)
+    lrs_lpoutput(P,Q,output);
+  else
+    lrs_printtotals (P, Q);	/* print final totals, including estimates       */
+
+  lrs_clear_mp_vector(output, Q->n);
+  lrs_free_dic (P,Q);           /* deallocate lrs_dic */
+
+  lrs_free_dat (Q);             /* deallocate lrs_dat */
+
+  lrs_close ("lrs:");
+
+  return 0;
+}
+/*********************************************/
+/* end of model test program for lrs library */
+/*********************************************/
+
+/*******************************************************/
+/* redund_main is driver for redund.c, removes all     */
+/* redundant rows from an H or V-representation        */
+/* showing function calls intended for public use      */
+/*******************************************************/
+long
+redund_main (int argc, char *argv[])
+
+{
+  lrs_mp_matrix Ain;		/* holds a copy of the input matrix to output at the end */
+
+  long *redineq;		/* redineq[i]=0 if ineq i non-red,1 if red,2 linearity  */
+  long ineq;			/* input inequality number of current index             */
+
+  lrs_dic *P;			/* structure for holding current dictionary and indices */
+  lrs_dat *Q;			/* structure for holding static problem data            */
+
+  lrs_mp_matrix Lin;		/* holds input linearities if any are found             */
+
+  long i, j, d, m;
+  long nlinearity;		/* number of linearities in input file                  */
+  long nredund;			/* number of redundant rows in input file               */
+  long lastdv;
+  long debug;
+  long index;			/* basic index for redundancy test */
+
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+/* they default to stdin and stdout, but may be overidden by command line parms. */
+/* Lin is global 2-d array for linearity space if it is found (redund columns)   */
+
+  lrs_ifp = stdin;
+  lrs_ofp = stdout;
+/***************************************************
+ Step 0: 
+  Do some global initialization that should only be done once,
+  no matter how many lrs_dat records are allocated. db
+
+***************************************************/
+
+  if ( !lrs_init ("\n*redund:"))
+    return 1;
+
+  printf (AUTHOR);
+
+/*********************************************************************************/
+/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem                      */
+/*********************************************************************************/
+
+  Q = lrs_alloc_dat ("LRS globals");	/* allocate and init structure for static problem data */
+
+  if (Q == NULL)
+    return 1;
+
+  if (!lrs_read_dat (Q, argc, argv))	/* read first part of problem data to get dimensions   */
+    return 1;                         	/* and problem type: H- or V- input representation     */
+
+  P = lrs_alloc_dic (Q);	/* allocate and initialize lrs_dic                     */
+  if (P == NULL)
+    return 1;
+
+  if (!lrs_read_dic (P, Q))	/* read remainder of input to setup P and Q            */
+    return 1;
+
+/* if non-negative flag is set, non-negative constraints are not input */
+/* explicitly, and are not checked for redundancy                      */
+
+  m = P->m_A;              /* number of rows of A matrix */   
+  d = P->d;
+  debug = Q->debug;
+
+  redineq = calloc ((m + 1), sizeof (long));
+  Ain = lrs_alloc_mp_matrix (m, d);	/* make a copy of A matrix for output later            */
+
+  for (i = 1; i <= m; i++)
+    {
+      for (j = 0; j <= d; j++)
+	copy (Ain[i][j], P->A[i][j]);
+
+      if (debug)
+	lrs_printrow ("*", Q, Ain[i], d);
+    }
+
+/*********************************************************************************/
+/* Step 2: Find a starting cobasis from default of specified order               */
+/*         Lin is created if necessary to hold linearity space                   */
+/*********************************************************************************/
+
+  if (!lrs_getfirstbasis (&P, Q, &Lin, TRUE))
+    return 1;
+
+  /* Pivot to a starting dictionary                      */
+  /* There may have been column redundancy               */
+  /* If so the linearity space is obtained and redundant */
+  /* columns are removed. User can access linearity space */
+  /* from lrs_mp_matrix Lin dimensions nredundcol x d+1  */
+
+
+/*********************************************************************************/
+/* Step 3: Test each row of the dictionary to see if it is redundant             */
+/*********************************************************************************/
+
+/* note some of these may have been changed in getting initial dictionary        */
+  m = P->m_A;
+  d = P->d;
+  nlinearity = Q->nlinearity;
+  lastdv = Q->lastdv;
+      if (debug)
+	fprintf (lrs_ofp, "\ncheckindex m=%ld, n=%ld, nlinearity=%ld lastdv=%ld", m,d,nlinearity,lastdv);
+
+/* linearities are not considered for redundancy */
+
+  for (i = 0; i < nlinearity; i++)
+    redineq[Q->linearity[i]] = 2L;
+
+/* rows 0..lastdv are cost, decision variables, or linearities  */
+/* other rows need to be tested                                */
+
+  for (index = lastdv + 1; index <= m + d; index++)
+    {
+      ineq = Q->inequality[index - lastdv];	/* the input inequality number corr. to this index */
+
+      redineq[ineq] = checkindex (P, Q, index);
+      if (debug)
+	fprintf (lrs_ofp, "\ncheck index=%ld, inequality=%ld, redineq=%ld", index, ineq, redineq[ineq]);
+      if (redineq[ineq] == ONE)
+        {
+	fprintf (lrs_ofp, "\n*row %ld was redundant and removed", ineq);
+        fflush  (lrs_ofp);
+        }
+
+    }				/* end for index ..... */
+
+  if (debug)
+    {
+      fprintf (lrs_ofp, "\n*redineq:");
+      for (i = 1; i <= m; i++)
+	fprintf (lrs_ofp, " %ld", redineq[i]);
+    }
+
+  if (!Q->hull)
+    fprintf (lrs_ofp, "\nH-representation");
+  else
+    fprintf (lrs_ofp, "\nV-representation");
+
+/* linearities will be printed first in output */
+
+  if (nlinearity > 0)
+    {
+      fprintf (lrs_ofp, "\nlinearity %ld", nlinearity);
+      for (i = 1; i <= nlinearity; i++)
+	fprintf (lrs_ofp, " %ld", i);
+
+    }
+  nredund = nlinearity;		/* count number of non-redundant inequalities */
+  for (i = 1; i <= m; i++)
+    if (redineq[i] == 0)
+      nredund++;
+  fprintf (lrs_ofp, "\nbegin");
+  fprintf (lrs_ofp, "\n%ld %ld rational", nredund, Q->n);
+
+/* print the linearities first */
+
+  for (i = 0; i < nlinearity; i++)
+    lrs_printrow ("", Q, Ain[Q->linearity[i]], Q->inputd);
+
+  for (i = 1; i <= m; i++)
+    if (redineq[i] == 0)
+      lrs_printrow ("", Q, Ain[i], Q->inputd);
+  fprintf (lrs_ofp, "\nend");
+  fprintf (lrs_ofp, "\n*Input had %ld rows and %ld columns", m, Q->n);
+  fprintf (lrs_ofp, ": %ld row(s) redundant", m - nredund);
+
+  lrs_free_dic (P,Q);           /* deallocate lrs_dic */
+  lrs_free_dat (Q);             /* deallocate lrs_dat */
+
+  lrs_close ("redund:");
+
+  return 0;
+}
+/*********************************************/
+/* end of redund.c                           */
+/*********************************************/
+/*******************/
+/* lrs_printoutput */
+/*******************/
+void 
+lrs_printoutput (lrs_dat * Q, lrs_mp_vector output)
+{
+  long i;
+
+  fprintf (lrs_ofp, "\n");
+  if (Q->hull || zero (output[0]))	/*non vertex */
+    {
+      for (i = 0; i < Q->n; i++)
+	pmp ("", output[i]);
+
+    }
+  else
+    {				/* vertex   */
+      fprintf (lrs_ofp, " 1 ");
+      for (i = 1; i < Q->n; i++)
+	prat ("", output[i], output[0]);
+    }
+  fflush(lrs_ofp);
+
+}
+/**************************/
+/* end of lrs_printoutput */
+/**************************/
+
+/****************/
+/* lrs_lpoutput */
+/****************/
+void lrs_lpoutput(lrs_dic * P,lrs_dat * Q, lrs_mp_vector output)
+{
+	
+
+#ifndef LRS_QUIET
+  lrs_mp Temp1, Temp2;
+  long i;
+
+  lrs_alloc_mp (Temp1);
+  lrs_alloc_mp (Temp2);
+
+  fprintf (lrs_ofp, "\n*LP solution only requested");
+  prat ("\n\n*Objective function has value ", P->objnum, P->objden);
+
+  fprintf (lrs_ofp, "\n\n*Primal: ");
+  for (i = 1; i < Q->n; i++)
+      {
+        fprintf(lrs_ofp,"x_%ld=",i);
+        prat ("", output[i], output[0]);
+       }
+
+  if(Q->nlinearity > 0)
+      fprintf (lrs_ofp, "\n\n*Linearities in input file - partial dual solution only");
+  fprintf (lrs_ofp, "\n\n*Dual: ");
+
+  for (i = 0; i < P->d; i++)
+	  {
+	        fprintf(lrs_ofp,"y_%ld=",Q->inequality[P->C[i]-Q->lastdv]);
+	        changesign(P->A[0][P->Col[i]]);
+                mulint(Q->Lcm[P->Col[i]],P->A[0][P->Col[i]],Temp1);
+                mulint(Q->Gcd[P->Col[i]],P->det,Temp2);
+	        prat("",Temp1,Temp2);
+	        changesign(P->A[0][P->Col[i]]);
+          }
+  fprintf (lrs_ofp, "\n");
+  lrs_clear_mp (Temp1);
+  lrs_clear_mp (Temp2);
+#endif
+ }
+/***********************/
+/* end of lrs_lpoutput */
+/***********************/
+void 
+lrs_printrow (char name[], lrs_dat * Q, lrs_mp_vector output, long rowd)
+/* print a row of A matrix in output in "original" form  */
+/* rowd+1 is the dimension of output vector                */
+/* if input is H-rep. output[0] contains the RHS      */
+/* if input is V-rep. vertices are scaled by 1/output[1] */
+{
+  long i;
+
+  fprintf (lrs_ofp, "\n%s", name);
+  if (!Q->hull)			/* input was inequalities, print directly */
+
+    {
+
+      for (i = 0; i <= rowd; i++)
+	pmp ("", output[i]);
+      return;
+    }
+
+/* input was vertex/ray */
+
+  if (zero (output[1]))		/*non-vertex */
+    {
+      for (i = 1; i <= rowd; i++)
+	pmp ("", output[i]);
+
+    }
+  else
+    {				/* vertex */
+      fprintf (lrs_ofp, " 1 ");
+      for (i = 2; i <= rowd; i++)
+	prat ("", output[i], output[1]);
+    }
+
+  return;
+
+}				/* end of lrs_printrow */
+
+long 
+lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col)
+   /* check if column indexed by col in this dictionary */
+   /* contains output                                   */
+   /* col=0 for vertex 1....d for ray/facet             */
+{
+  long j;			/* cobasic index     */
+
+  lrs_mp_matrix A = P->A;
+  long *Row = P->Row;
+
+  if (col == ZERO)		/* check for lexmin vertex */
+    return lrs_getvertex (P, Q, output);
+
+/*  check for rays: negative in row 0 , positive if lponly */
+
+  if (Q->lponly)
+    {
+      if (!positive (A[0][col]))
+	return FALSE;
+    }
+
+  else if (!negative (A[0][col]))
+    return FALSE;
+
+/*  and non-negative for all basic non decision variables */
+
+  j = Q->lastdv + 1;
+  while (j <= P->m && !negative (A[Row[j]][col]))
+    j++;
+
+  if (j <= P->m)
+    return FALSE;
+
+  if (Q->geometric || Q->allbases || lexmin (P, Q, col) || Q->lponly)
+
+    return lrs_getray (P, Q, col, Q->n, output);
+
+  return FALSE;			/* no more output in this dictionary */
+
+}				/* end of lrs_getsolution */
+
+
+long
+lrs_init (char *name)       /* returns TRUE if successful, else FALSE */
+{
+  printf ("%s", name);
+  printf (TITLE);
+  printf (VERSION);
+  printf ("(");
+  printf (BIT);
+  printf (",");
+  printf (ARITH);
+  if (!lrs_mp_init (ZERO, stdin, stdout))  /* initialize arithmetic */
+    return FALSE;
+  printf (")");
+
+
+  lrs_global_count = 0;
+  lrs_checkpoint_seconds = 0;
+#ifdef SIGNALS
+  setup_signals ();
+#endif
+  return TRUE;
+}
+
+void 
+lrs_close (char *name)
+{
+
+  fprintf (lrs_ofp, "\n*%s", name);
+  fprintf (lrs_ofp, TITLE);
+  fprintf (lrs_ofp, VERSION);
+  fprintf (lrs_ofp, "(");
+  fprintf (lrs_ofp, BIT);
+  fprintf (lrs_ofp, ",");
+  fprintf (lrs_ofp, ARITH);
+  fprintf (lrs_ofp, ")");
+
+#ifdef MP   
+  fprintf (lrs_ofp, " max digits=%ld/%ld", DIG2DEC (lrs_record_digits), DIG2DEC (lrs_digits));
+#endif
+
+#ifdef TIMES
+  ptimes ();
+#endif
+
+  fprintf (lrs_ofp, "\n");
+  fclose (lrs_ifp);
+  if (lrs_ofp != stdout)
+    fclose (lrs_ofp);
+}
+
+/***********************************/
+/* allocate and initialize lrs_dat */
+/***********************************/
+lrs_dat *
+lrs_alloc_dat (char *name)
+{
+  lrs_dat *Q;
+  long i;
+
+
+  if (lrs_global_count >= MAX_LRS_GLOBALS)
+    {
+      fprintf (stderr,
+	       "Fatal: Attempt to allocate more than %ld global data blocks\n", MAX_LRS_GLOBALS);
+      exit (1);
+
+    }
+
+  Q = (lrs_dat *) malloc (sizeof (lrs_dat));
+  if (Q == NULL)
+    return Q;			/* failure to allocate */
+
+  lrs_global_list[lrs_global_count] = Q;
+  Q->id = lrs_global_count;
+  lrs_global_count++;
+  Q->name=(char *) CALLOC ((unsigned) strlen(name)+1, sizeof (char));
+  strcpy(Q->name,name); 
+
+/* initialize variables */
+  Q->m = 0L;
+  Q->n = 0L;
+  Q->inputd = 0L;
+  Q->deepest = 0L;
+  Q->nlinearity = 0L;
+  Q->nredundcol = 0L;
+  Q->runs = 0L;
+  Q->seed = 1234L;
+  Q->totalnodes = 0L;
+  for (i = 0; i < 10; i++)
+    {
+      Q->count[i] = 0L;
+      Q->cest[i] = 0.0;
+    }
+  Q->count[2] = 1L;		/* basis counter */
+/* initialize flags */
+  Q->allbases = FALSE;
+  Q->bound = FALSE;            /* upper/lower bound on objective function given */
+  Q->debug = FALSE;
+  Q->frequency = 0L;
+  Q->dualdeg = FALSE;          /* TRUE if dual degenerate starting dictionary */
+  Q->geometric = FALSE;
+  Q->getvolume = FALSE;
+  Q->homogeneous = TRUE;
+  Q->polytope = FALSE;
+  Q->hull = FALSE;
+  Q->incidence = FALSE;
+  Q->lponly = FALSE;
+  Q->maxdepth = MAXD;
+  Q->mindepth = -MAXD;
+  Q->maxoutput = 0L;
+  Q->nash = FALSE;
+  Q->nonnegative = FALSE;
+  Q->printcobasis = FALSE;
+  Q->printslack = FALSE;
+  Q->truncate = FALSE;          /* truncate tree when moving from opt vertex        */
+  Q->verbose=FALSE;
+  Q->voronoi = FALSE;
+  Q->maximize = FALSE;		/*flag for LP maximization                          */
+  Q->minimize = FALSE;		/*flag for LP minimization                          */
+  Q->restart = FALSE;		/* TRUE if restarting from some cobasis             */
+  Q->givenstart = FALSE;	/* TRUE if a starting cobasis is given              */
+  Q->strace = -1L;		/* turn on  debug at basis # strace */
+  Q->etrace = -1L;		/* turn off debug at basis # etrace */
+
+  Q->saved_flag = 0;		/* no cobasis saved initially, db */
+  lrs_alloc_mp (Q->Nvolume);
+  lrs_alloc_mp (Q->Dvolume);
+  lrs_alloc_mp (Q->sumdet);
+  lrs_alloc_mp (Q->saved_det);
+  lrs_alloc_mp (Q->boundn);
+  lrs_alloc_mp (Q->boundd);
+  itomp (ZERO, Q->Nvolume);
+  itomp (ONE, Q->Dvolume);
+  itomp (ZERO, Q->sumdet);
+/* 2012.6.1 */
+  Q->unbounded = FALSE;
+
+  return Q;
+}				/* end of allocate and initialize lrs_dat */
+
+/*******************************/
+/*  lrs_read_dat               */
+/*******************************/
+long 
+lrs_read_dat (lrs_dat * Q, int argc, char *argv[])
+{
+  char name[100];
+  long dec_digits = 0;
+  long infile=0;                /*input file number to open if any        */
+  long firstline = TRUE;	/*flag for picking off name at line 1     */
+
+  int c;			/* for fgetc */
+
+
+  if(argc > 1 )
+	  infile=1;
+  if(Q->nash && argc == 2)        /* open second nash input file */
+	  infile=2;
+
+  if (infile > 0)			/* command line argument overides stdin   */
+    {
+      if ((lrs_ifp = fopen (argv[infile], "r")) == NULL)
+	{
+	  printf ("\nBad input file name\n");
+	  return (FALSE);
+	}
+      else
+      { if (infile==1)
+	printf ("\n*Input taken from file %s", argv[infile]);
+      }
+    }
+
+       	  /* command line argument overides stdout   */
+  if ((!Q->nash && argc == 3) || (Q->nash && argc == 4)) 
+    {
+      if ((lrs_ofp = fopen (argv[argc-1], "w")) == NULL)
+	{
+	  printf ("\nBad output file name\n");
+	  return (FALSE);
+	}
+      else
+	printf ("\n*Output sent to file %s\n", argv[argc-1]);
+    }
+
+
+/* process input file */
+  if( fscanf (lrs_ifp, "%s", name) == EOF)
+	    {
+	      fprintf (lrs_ofp, "\nNo begin line");
+	      return (FALSE);
+	    }
+
+  while (strcmp (name, "begin") != 0)	/*skip until "begin" found processing options */
+    {
+      if (strncmp (name, "*", 1) == 0)	/* skip any line beginning with * */
+	{
+	  c = name[0];
+	  while (c != EOF && c != '\n')
+	    c = fgetc (lrs_ifp);
+	}
+
+      else if (strcmp (name, "H-representation") == 0)
+	Q->hull = FALSE;
+      else if ((strcmp (name, "hull") == 0) || (strcmp (name, "V-representation") == 0))
+        {
+	   Q->hull = TRUE;
+           Q->polytope = TRUE;		/* will be updated as input read */
+        }
+      else if (strcmp (name, "digits") == 0)
+	{
+	  if (fscanf (lrs_ifp, "%ld", &dec_digits) == EOF)
+	    {
+	      fprintf (lrs_ofp, "\nNo begin line");
+	      return (FALSE);
+	    }
+          if  (!lrs_set_digits(dec_digits))
+             return (FALSE);
+	}
+      else if (strcmp (name, "linearity") == 0)
+	{
+	  if (!readlinearity (Q))
+	    return FALSE;
+	}
+      else if (strcmp (name, "nonnegative") == 0)
+	{
+         if(Q->nash)
+	  fprintf (lrs_ofp, "\nNash incompatibile with nonnegative option - skipped");
+         else
+	  Q->nonnegative = TRUE;
+	}
+      else if (firstline)
+	{
+	  stringcpy (Q->fname, name);
+	  fprintf (lrs_ofp, "\n%s", Q->fname);
+	  firstline = FALSE;
+	}
+
+      if (fscanf (lrs_ifp, "%s", name) == EOF)
+	{
+	  fprintf (lrs_ofp, "\nNo begin line");
+	  return (FALSE);
+	}
+
+    }				/* end of while */
+
+
+  if (fscanf (lrs_ifp, "%ld %ld %s", &Q->m, &Q->n, name) == EOF)
+    {
+      fprintf (lrs_ofp, "\nNo data in file");
+      return (FALSE);
+    }
+  if (strcmp (name, "integer") != 0 && strcmp (name, "rational") != 0)
+    {
+      fprintf (lrs_ofp, "\nData type must be integer of rational");
+      return (FALSE);
+    }
+
+
+  if (Q->m == 0)
+    {
+      fprintf (lrs_ofp, "\nNo input given");	/* program dies ungracefully */
+      return (FALSE);
+    }
+
+
+
+  /* inputd may be reduced in preprocessing of linearities and redund cols */
+
+  return TRUE;
+}				/* end of lrs_read_dat */
+
+/****************************/
+/* set up lrs_dic structure */
+/****************************/
+long 
+lrs_read_dic (lrs_dic * P, lrs_dat * Q)
+/* read constraint matrix and set up problem and dictionary  */
+
+{
+  lrs_mp Temp,Tempn,Tempd, mpone, mpten;
+  lrs_mp_vector oD;		/* Denom for objective function */
+
+  long i, j;
+  char name[100];
+  int c; /* fgetc actually returns an int. db */
+
+/* assign local variables to structures */
+
+  lrs_mp_matrix A;
+  lrs_mp_vector Gcd, Lcm;
+  long hull = Q->hull;
+  long m, d;
+  long dualperturb=FALSE;    /* dualperturb=TRUE: objective function perturbed */
+
+  lrs_alloc_mp(Temp); lrs_alloc_mp(mpone);
+  lrs_alloc_mp(Tempn); lrs_alloc_mp(Tempd); lrs_alloc_mp(mpten);
+  A = P->A;
+  m = Q->m;
+  d = Q->inputd;
+  Gcd = Q->Gcd;
+  Lcm = Q->Lcm;
+
+  oD = lrs_alloc_mp_vector (d);
+
+
+  itomp (ONE, mpone);
+  itomp (ONE, A[0][0]);
+  itomp (ONE, Lcm[0]);
+  itomp (ONE, Gcd[0]);
+
+  for (i = 1; i <= m; i++)	/* read in input matrix row by row                 */
+    {
+      itomp (ONE, Lcm[i]);	/* Lcm of denominators */
+      itomp (ZERO, Gcd[i]);	/* Gcd of numerators */
+      for (j = hull; j <= d; j++)	/* hull data copied to cols 1..d */
+	{
+	  if (readrat (A[i][j], A[0][j]))
+	    lcm (Lcm[i], A[0][j]);	/* update lcm of denominators */
+	  copy (Temp, A[i][j]);
+	  gcd (Gcd[i], Temp);	/* update gcd of numerators   */
+	}
+
+      if (hull)
+	{
+	  itomp (ZERO, A[i][0]);	/*for hull, we have to append an extra column of zeroes */
+	  if (!one (A[i][1]) || !one (A[0][1]))		/* all rows must have a one in column one */
+	    Q->polytope = FALSE;
+	}
+      if (!zero (A[i][hull]))	/* for H-rep, are zero in column 0     */
+	Q->homogeneous = FALSE;	/* for V-rep, all zero in column 1     */
+
+
+      storesign (Gcd[i], POS);
+      storesign (Lcm[i], POS);
+      if (greater (Gcd[i], mpone) || greater (Lcm[i], mpone))
+	for (j = 0; j <= d; j++)
+	  {
+	    exactdivint (A[i][j], Gcd[i], Temp);	/*reduce numerators by Gcd  */
+	    mulint (Lcm[i], Temp, Temp);	/*remove denominators */
+	    exactdivint (Temp, A[0][j], A[i][j]);	/*reduce by former denominator */
+	  }
+
+    }				/* end of for i=       */
+
+/* 2010.4.26 patch */
+  if(Q->nonnegative)    /* set up Gcd and Lcm for nonexistent nongative inequalities */
+      for (i=m+1;i<=m+d;i++)
+          { itomp (ONE, Lcm[i]);
+            itomp (ONE, Gcd[i]);
+          }
+  
+  if (Q->homogeneous && Q->verbose)
+    {
+      fprintf (lrs_ofp, "\n*Input is homogeneous, column 1 not treated as redundant");
+    }
+
+
+/* read in flags */
+  while (fscanf (lrs_ifp, "%s", name) != EOF)
+    {
+      if (strncmp (name, "*", 1) == 0)	/* skip any line beginning with * */
+	{
+	  c = name[0];
+	  while (c != EOF && c != '\n')
+	    c = fgetc (lrs_ifp);
+	}
+
+
+      if (strcmp (name, "checkpoint") == 0)
+	{
+	  long seconds;
+
+	  if(fscanf (lrs_ifp, "%ld", &seconds) == EOF)
+            {
+              fprintf (lrs_ofp, "\nInvalid checkpoint option");
+              return (FALSE);
+            }
+
+#ifdef SIGNALS
+	  if (seconds > 0)
+	    {
+	      lrs_checkpoint_seconds = seconds;
+	      errcheck ("signal", signal (SIGALRM, timecheck));
+	      alarm (lrs_checkpoint_seconds);
+	    }
+#endif
+	}
+
+      if (strcmp (name, "debug") == 0)
+	{
+          Q->etrace =0;
+	  if(fscanf (lrs_ifp, "%ld %ld", &Q->strace, &Q->etrace)==EOF)
+             Q->strace =0;
+	  fprintf (lrs_ofp, "\n*%s from B#%ld to B#%ld", name, Q->strace, Q->etrace);
+          Q->verbose=TRUE;
+	  if (Q->strace <= 1)
+	    Q->debug = TRUE;
+	}
+      if (strcmp (name, "startingcobasis") == 0)
+	{
+          if(Q->nonnegative)
+	      fprintf (lrs_ofp, "\n*startingcobasis incompatible with nonnegative option:skipped");
+          else
+            {    
+	      fprintf (lrs_ofp, "\n*startingcobasis");
+	      Q->givenstart = TRUE;
+	      if (!readfacets (Q, Q->inequality))
+	          return FALSE;
+	    }
+        }
+
+      if (strcmp (name, "restart") == 0)
+	{
+	  Q->restart = TRUE;
+          if(Q->voronoi)
+           {
+             if(fscanf (lrs_ifp, "%ld %ld %ld %ld", &Q->count[1], &Q->count[0], &Q->count[2], &P->depth)==EOF)
+               return FALSE;
+             fprintf (lrs_ofp, "\n*%s V#%ld R#%ld B#%ld h=%ld data points", name, Q->count[1], Q->count[0], Q->count[2], P->depth);
+            }
+          else if(hull)
+            {
+	    if( fscanf (lrs_ifp, "%ld %ld %ld", &Q->count[0], &Q->count[2], &P->depth)==EOF)
+	     fprintf (lrs_ofp, "\n*%s F#%ld B#%ld h=%ld vertices/rays", name, Q->count[0], Q->count[2], P->depth);
+            }
+          else
+            {
+	     if(fscanf (lrs_ifp, "%ld %ld %ld %ld", &Q->count[1], &Q->count[0], &Q->count[2], &P->depth)==EOF)
+               return FALSE;
+	     fprintf (lrs_ofp, "\n*%s V#%ld R#%ld B#%ld h=%ld facets", name, Q->count[1], Q->count[0], Q->count[2], P->depth);
+            }
+	  if (!readfacets (Q, Q->facet))
+	    return FALSE;
+	}			/* end of restart */
+
+/* The next flag request a LP solution only */
+      if (strcmp (name, "lponly") == 0)
+	{
+	  if (Q->hull)
+	    fprintf (lrs_ofp, "\n*lponly  option not valid for V-representation-skipped");
+	  else
+	    Q->lponly = TRUE;
+	}
+
+
+/* The LP will be solved after initialization to get starting vertex   */
+/* Used also with lponly flag                                          */
+      if (strcmp (name, "maximize") == 0 || strcmp (name, "minimize") == 0)
+	{
+	  if (Q->hull)
+	    fprintf (lrs_ofp, "\n*%s option not valid for V-representation-skipped", name);
+	  else
+	    {
+	      {
+		if (strcmp (name, "maximize") == 0)
+		  Q->maximize = TRUE;
+		else
+		  Q->minimize = TRUE;
+	      }
+	      fprintf (lrs_ofp,"\n*%s", name);
+
+              if(dualperturb)   /* apply a perturbation to objective function */
+                {
+	          fprintf (lrs_ofp, " - Objective function perturbed");
+                  itomp(10L,mpten);
+                  copy(Temp,mpten);
+                  for (j = 0; j <= 10; j++)
+                      mulint(mpten,Temp,Temp);
+                }
+
+              fprintf (lrs_ofp, ":  ");
+
+	      for (j = 0; j <= d; j++)
+		{
+		  if (readrat (A[0][j], oD[j]) || dualperturb )
+		    {
+                      if(dualperturb && j > 0 && j < d )
+                        {
+                         if (Q->maximize)
+                          linrat(A[0][j], oD[j],ONE,mpone,Temp,ONE,Tempn,Tempd);
+                         else
+                          linrat(A[0][j], oD[j],ONE,mpone,Temp,-1L,Tempn,Tempd);
+
+                         copy(A[0][j],Tempn);
+                         copy(oD[j],Tempd);
+                         mulint(mpten,Temp,Temp);
+                        }
+
+		      reduce (A[0][j], oD[j]);
+		      lcm (Q->Lcm[0], oD[j]);	/* update lcm of denominators */
+		    }
+		  prat ("", A[0][j], oD[j]);
+		  if (!Q->maximize)
+		    changesign (A[0][j]);
+		}
+	      storesign (Q->Lcm[0], POS);
+	      if (greater (Q->Lcm[0], mpone))
+		for (j = 0; j <= d; j++)
+		  {
+		    mulint (Q->Lcm[0], A[0][j], A[0][j]);	/*remove denominators */
+		    copy (Temp, A[0][j]);
+		    exactdivint (Temp, oD[j], A[0][j]);
+		  }
+	      if (Q->debug)
+		printA (P, Q);
+	    }
+	}			/* end of LP setup */
+      if (strcmp (name, "volume") == 0)
+	{
+	  fprintf (lrs_ofp, "\n*%s", name);
+	  Q->getvolume = TRUE;
+	}
+      if (strcmp (name, "geometric") == 0)
+	{
+	  fprintf (lrs_ofp, "\n*%s", name);
+	  if (hull & !Q->voronoi)
+	    fprintf (lrs_ofp, " - option for H-representation or voronoi only, skipped");
+	  else
+	    Q->geometric = TRUE;
+	}
+      if (strcmp (name, "allbases") == 0)
+	{
+	  fprintf (lrs_ofp, "\n*%s", name);
+	  Q->allbases = TRUE;
+	}
+      if (strcmp (name, "dualperturb") == 0)
+	{
+	  dualperturb = TRUE;
+	}
+
+      if (strcmp (name, "incidence") == 0)
+	{
+	  fprintf (lrs_ofp, "\n*%s", name);
+	  Q->incidence = TRUE;
+	}
+
+      if (strcmp (name, "#incidence") == 0) /* number of incident inequalities only */
+	{
+	  Q->printcobasis = TRUE;
+	}
+
+      if (strcmp (name, "printcobasis") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &Q->frequency)==EOF)
+/*2010.7.7  set default to zero = print only when outputting vertex/ray/facet */
+             Q->frequency=0;
+	  fprintf (lrs_ofp, "\n*%s", name);
+          if (Q->frequency > 0)
+            fprintf(lrs_ofp," %ld", Q->frequency);
+	  Q->printcobasis = TRUE;
+	}
+
+      if (strcmp (name, "printslack") == 0)
+	{
+	  Q->printslack = TRUE;
+	}
+
+      if (strcmp (name, "cache") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &dict_limit)==EOF)
+              dict_limit=1;
+	  fprintf (lrs_ofp, "\n*cache %ld", dict_limit);
+	  if (dict_limit < 1)
+	    dict_limit = 1;
+	}
+      if (strcmp (name, "linearity") == 0)
+	{
+	  if (!readlinearity (Q))
+	    return FALSE;
+	}
+
+      if (strcmp (name, "maxdepth") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &Q->maxdepth)==EOF)
+                    Q->maxdepth=1;
+	  fprintf (lrs_ofp, "\n*%s  %ld", name, Q->maxdepth);
+	}
+
+      if (strcmp (name, "maxoutput") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &Q->maxoutput)==EOF)
+             Q->maxoutput = 100;
+	  fprintf (lrs_ofp, "\n*%s  %ld", name, Q->maxoutput);
+	}
+      if (strcmp (name, "mindepth") == 0)
+	{
+	if( fscanf (lrs_ifp, "%ld", &Q->mindepth)==EOF)
+           Q->mindepth = 0;
+	  fprintf (lrs_ofp, "\n*%s  %ld", name, Q->mindepth);
+	}
+
+      if (strcmp (name, "truncate") == 0)
+        {
+          fprintf (lrs_ofp, "\n*%s", name);
+          if (!hull)
+            Q->truncate = TRUE;
+          else
+            fprintf (lrs_ofp, " - option for H-representation only, skipped");
+        }
+
+
+      if (strcmp (name, "verbose") == 0)
+          Q->verbose = TRUE;
+
+      if (strcmp (name, "bound") == 0)
+         {
+          readrat(Q->boundn,Q->boundd);
+          Q->bound = TRUE;
+         }
+
+      if (strcmp (name, "nonnegative") == 0)
+	{
+	  fprintf (lrs_ofp, "\n*%s", name);
+	  fprintf (lrs_ofp, " - option must come before begin line - skipped");
+	}
+
+      if (strcmp (name, "seed") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &Q->seed)==EOF)
+               Q->seed = 3142;
+	  fprintf (lrs_ofp, "\n*seed= %ld ", Q->seed);
+	}
+
+      if (strcmp (name, "estimates") == 0)
+	{
+	  if(fscanf (lrs_ifp, "%ld", &Q->runs)==EOF)
+             Q->runs=1;
+	  fprintf (lrs_ofp, "\n*%ld %s", Q->runs, name);
+	}
+
+      if ((strcmp (name, "voronoi") == 0) || (strcmp (name, "Voronoi") == 0))
+	{
+	  if (!hull)
+	    fprintf (lrs_ofp, "\n*voronoi requires V-representation - option skipped");
+	  else
+	    {
+	      Q->voronoi = TRUE;
+	      Q->polytope = FALSE;
+	    }
+	}
+
+    }				/* end of while for reading flags */
+
+  if (Q->polytope)
+    Q->getvolume = TRUE; 	/* might as well get volume, it doesn't cost much */
+
+  if (Q->bound && Q->maximize)
+    prat("\n*Lower bound on objective function:",Q->boundn,Q->boundd);
+
+  if (Q->bound && Q->minimize)
+    prat("\n*Upper bound on objective function:",Q->boundn,Q->boundd);
+
+/* Certain options are incompatible, this is fixed here */
+
+  if (Q->restart)
+    Q->getvolume = FALSE;       /* otherwise incorrect volume reported            */
+
+  if (Q->incidence)
+    {
+      Q->printcobasis = TRUE;
+/* 2010.5.7    No need to reset this, as it may have been set by printcobasis */
+/*    Q->frequency    = ZERO;                     */                                                      
+    }
+
+  if (Q->debug)
+    {
+      printA (P, Q);
+      fprintf (lrs_ofp, "\nexiting lrs_read_dic");
+    }
+  lrs_clear_mp(Temp); lrs_clear_mp(mpone);
+  lrs_clear_mp(Tempn); lrs_clear_mp(Tempd); lrs_clear_mp(mpten);
+  lrs_clear_mp_vector (oD,d);
+  return TRUE;
+
+}
+/********* end of lrs_read_dic ***************/
+
+/* In lrs_getfirstbasis and lrs_getnextbasis we use D instead of P */
+/* since the dictionary P may change, ie. &P in calling routine    */
+
+#define D (*D_p)
+
+long 
+lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_output)
+/* gets first basis, FALSE if none              */
+/* P may get changed if lin. space Lin found    */
+/* no_output is TRUE supresses output headers   */
+{
+  lrs_mp scale, Temp;
+
+  long i, j, k;
+
+/* assign local variables to structures */
+
+  lrs_mp_matrix A;
+  long *B, *C, *Row, *Col;
+  long *inequality;
+  long *linearity;
+  long hull = Q->hull;
+  long m, d, lastdv, nlinearity, nredundcol;
+
+  static long ocount=0;
+
+  lrs_alloc_mp(Temp); lrs_alloc_mp(scale);
+
+  if (Q->lponly)
+    no_output = TRUE;
+  m = D->m;
+  d = D->d;
+  lastdv = Q->lastdv;
+
+  nredundcol = 0L;		/* will be set after getabasis        */
+  nlinearity = Q->nlinearity;	/* may be reset if new linearity read or in getabasis*/
+  linearity = Q->linearity;
+
+  A = D->A;
+  B = D->B;
+  C = D->C;
+  Row = D->Row;
+  Col = D->Col;
+  inequality = Q->inequality;
+
+
+  if (Q->nlinearity > 0 && Q->nonnegative)
+   {
+    fprintf (lrs_ofp, "\n*linearity and nonnegative options incompatible");
+    fprintf (lrs_ofp, " - all linearities are skipped");
+    fprintf (lrs_ofp, "\n*add nonnegative constraints explicitly and ");
+    fprintf (lrs_ofp, " remove nonnegative option");
+   }
+
+  if (Q->nlinearity && Q->voronoi)
+    fprintf (lrs_ofp, "\n*linearity and Voronoi options set - results unpredictable");
+  if (Q->lponly && !Q->maximize && !Q->minimize)
+    fprintf (lrs_ofp, "\n*LP has no objective function given - assuming all zero");
+
+
+  if (Q->runs > 0)		/* arrays for estimator */
+    {
+      Q->isave = (long *) CALLOC ((unsigned) (m * d), sizeof (long));
+      Q->jsave = (long *) CALLOC ((unsigned) (m * d), sizeof (long));
+    }
+/* default is to look for starting cobasis using linearies first, then     */
+/* filling in from last rows of input as necessary                         */
+/* linearity array is assumed sorted here                                  */
+/* note if restart/given start inequality indices already in place         */
+/* from nlinearity..d-1                                                    */
+  for (i = 0; i < nlinearity; i++)	/* put linearities first in the order */
+    inequality[i] = linearity[i];
+
+  k = 0;			/* index for linearity array   */
+
+  if (Q->givenstart)
+    k = d;
+  else
+    k = nlinearity;
+  for (i = m; i >= 1; i--)
+    {
+      j = 0;
+      while (j < k && inequality[j] != i)
+	j++;			/* see if i is in inequality  */
+      if (j == k)
+	inequality[k++] = i;
+    }
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\n*Starting cobasis uses input row order");
+      for (i = 0; i < m; i++)
+	fprintf (lrs_ofp, " %ld", inequality[i]);
+    }
+/* for voronoi convert to h-description using the transform                  */
+/* a_0 .. a_d-1 -> (a_0^2 + ... a_d-1 ^2)-2a_0x_0-...-2a_d-1x_d-1 + x_d >= 0 */
+/* note constant term is stored in column d, and column d-1 is all ones      */
+/* the other coefficients are multiplied by -2 and shifted one to the right  */
+  if (Q->debug)
+    printA (D, Q);
+  if (Q->voronoi)
+    {
+      Q->hull = FALSE;
+      hull = FALSE;
+      for (i = 1; i <= m; i++)
+	{
+	  if (zero (A[i][1]))
+	    {
+	      fprintf (lrs_ofp, "\nWith voronoi option column one must be all one");
+	      return (FALSE);
+	    }
+	  copy (scale, A[i][1]);	/*adjust for scaling to integers of rationals */
+	  itomp (ZERO, A[i][0]);
+	  for (j = 2; j <= d; j++)	/* transform each input row */
+	    {
+	      copy (Temp, A[i][j]);
+	      mulint (A[i][j], Temp, Temp);
+	      linint (A[i][0], ONE, Temp, ONE);
+	      linint (A[i][j - 1], ZERO, A[i][j], -TWO);
+	      mulint (scale, A[i][j - 1], A[i][j - 1]);
+	    }			/* end of for (j=1;..) */
+	  copy (A[i][d], scale);
+	  mulint (scale, A[i][d], A[i][d]);
+	}			/* end of for (i=1;..) */
+      if (Q->debug)
+	printA (D, Q);
+    }				/* end of if(voronoi)     */
+  if (!Q->maximize && !Q->minimize)
+    for (j = 0; j <= d; j++)
+      itomp (ZERO, A[0][j]);
+
+/* Now we pivot to standard form, and then find a primal feasible basis       */
+/* Note these steps MUST be done, even if restarting, in order to get         */
+/* the same index/inequality correspondance we had for the original prob.     */
+/* The inequality array is used to give the insertion order                   */
+/* and is defaulted to the last d rows when givenstart=FALSE                  */
+
+  if(Q->nonnegative) 
+   {
+/* no need for initial pivots here, labelling already done */
+     Q->lastdv = d;
+     Q->nredundcol = 0;
+   }
+  else
+  {
+     if (!getabasis (D, Q, inequality))
+          return FALSE;
+/* bug fix 2009.12.2 */
+     nlinearity=Q->nlinearity;   /*may have been reset if some lins are redundant*/
+  }
+  if(Q->debug)
+  {
+    fprintf(lrs_ofp,"\nafter getabasis");
+    printA(D, Q);
+  }
+  nredundcol = Q->nredundcol;
+  lastdv = Q->lastdv;
+  d = D->d;
+
+/********************************************************************/
+/* now we start printing the output file  unless no output requested */
+/********************************************************************/
+  if (!no_output || Q->debug)
+    {
+      if (Q->voronoi)
+	fprintf (lrs_ofp, "\n*Voronoi Diagram: Voronoi vertices and rays are output");
+      if (hull)
+	fprintf (lrs_ofp, "\nH-representation");
+      else
+	fprintf (lrs_ofp, "\nV-representation");
+
+/* Print linearity space                 */
+/* Don't print linearity if first column zero in hull computation */
+
+      if (hull && Q->homogeneous)
+	k = 1;			/* 0 normally, 1 for homogeneous case     */
+      else
+	k = 0;
+
+      if (nredundcol > k)
+	{
+	  fprintf (lrs_ofp, "\nlinearity %ld ", nredundcol - k);	/*adjust nredundcol for homog. */
+	  for (i = 1; i <= nredundcol - k; i++)
+	    fprintf (lrs_ofp, " %ld", i);
+	}			/* end print of linearity space */
+
+      fprintf (lrs_ofp, "\nbegin");
+      fprintf (lrs_ofp, "\n***** %ld rational", Q->n);
+
+    }				/* end of if !no_output .......   */
+
+
+/* Reset up the inequality array to remember which index is which input inequality */
+/* inequality[B[i]-lastdv] is row number of the inequality with index B[i]              */
+/* inequality[C[i]-lastdv] is row number of the inequality with index C[i]              */
+
+  for (i = 1; i <= m; i++)
+    inequality[i] = i;
+  if (nlinearity > 0)		/* some cobasic indices will be removed */
+    {
+      for (i = 0; i < nlinearity; i++)	/* remove input linearity indices */
+	inequality[linearity[i]] = 0;
+      k = 1;			/* counter for linearities         */
+      for (i = 1; i <= m - nlinearity; i++)
+	{
+	  while (k <= m && inequality[k] == 0)
+	    k++;		/* skip zeroes in corr. to linearity */
+	  inequality[i] = inequality[k++];
+	}
+    }				/* end if linearity */
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\ninequality array initialization:");
+      for (i = 1; i <= m - nlinearity; i++)
+	fprintf (lrs_ofp, " %ld", inequality[i]);
+    }
+  if (nredundcol > 0)
+    {
+      *Lin = lrs_alloc_mp_matrix (nredundcol, Q->n);
+
+      for (i = 0; i < nredundcol; i++)
+	{
+	  if (!(Q->homogeneous && Q->hull && i == 0))	/* skip redund col 1 for homog. hull */
+	    {
+	      lrs_getray (D, Q, Col[0], D->C[0] + i - hull, (*Lin)[i]);		/* adjust index for deletions */
+	    }
+
+	  if (!removecobasicindex (D, Q, 0L))
+	    return FALSE;
+	}
+    }				/* end if nredundcol > 0 */
+
+  if (Q->lponly || Q->nash )
+      if (Q->verbose)
+      {
+      fprintf (lrs_ofp, "\nNumber of pivots for starting dictionary: %ld",Q->count[3]);
+      ocount=Q->count[3];
+      if(Q->lponly)
+                     printA (D, Q);
+       }
+
+/* Do dual pivots to get primal feasibility */
+  if (!primalfeasible (D, Q))
+    {
+#ifndef LRS_QUIET
+          fprintf (lrs_ofp, "\nNo feasible solution");
+#endif
+     if (Q->nash && Q->verbose )
+      {
+          fprintf (lrs_ofp, "\nNumber of pivots for feasible solution: %ld",Q->count[3]);
+          fprintf (lrs_ofp, " - No feasible solution");
+          ocount=Q->count[3];
+      }
+      return FALSE;
+    }
+
+  if (Q->lponly || Q->nash )
+      if (Q->verbose)
+     {
+      fprintf (lrs_ofp, "\nNumber of pivots for feasible solution: %ld",Q->count[3]);
+      ocount=Q->count[3];
+      if(Q->lponly)
+	      printA (D, Q);
+     }
+
+
+/* Now solve LP if objective function was given */
+  if (Q->maximize || Q->minimize)
+    {
+      Q->unbounded = !lrs_solvelp (D, Q, Q->maximize);
+      if (Q->lponly)		
+        {
+
+         if (Q->verbose)
+         {
+           fprintf (lrs_ofp, "\nNumber of pivots for optimum solution: %ld",Q->count[3]);
+           printA (D, Q);
+           ocount=Q->count[3];
+          }
+          lrs_clear_mp(Temp); lrs_clear_mp(scale);
+          return TRUE;
+        }
+
+      else                         /* check to see if objective is dual degenerate */
+       {
+	  j = 1;
+	  while (j <= d && !zero (A[0][j]))
+	    j++;
+	  if (j <= d)
+	    Q->dualdeg = TRUE;
+	}
+    }
+  else
+/* re-initialize cost row to -det */
+    {
+      for (j = 1; j <= d; j++)
+	{
+	  copy (A[0][j], D->det);
+	  storesign (A[0][j], NEG);
+	}
+
+      itomp (ZERO, A[0][0]);	/* zero optimum objective value */
+    }
+
+
+/* reindex basis to 0..m if necessary */
+/* we use the fact that cobases are sorted by index value */
+  if (Q->debug)
+    printA (D, Q);
+  while (C[0] <= m)
+    {
+      i = C[0];
+      j = inequality[B[i] - lastdv];
+      inequality[B[i] - lastdv] = inequality[C[0] - lastdv];
+      inequality[C[0] - lastdv] = j;
+      C[0] = B[i];
+      B[i] = i;
+      reorder1 (C, Col, ZERO, d);
+    }
+
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\n*Inequality numbers for indices %ld .. %ld : ", lastdv + 1, m + d);
+      for (i = 1; i <= m - nlinearity; i++)
+	fprintf (lrs_ofp, " %ld ", inequality[i]);
+      printA (D, Q);
+    }
+
+
+
+  if (Q->restart)
+    {
+      if (Q->debug)
+	fprintf (lrs_ofp, "\nPivoting to restart co-basis");
+      if (!restartpivots (D, Q))
+	return FALSE;
+      D->lexflag = lexmin (D, Q, ZERO);		/* see if lexmin basis */
+      if (Q->debug)
+	printA (D, Q);
+    }
+/* Check to see if necessary to resize */
+  if (Q->inputd > D->d)
+    *D_p = resize (D, Q);
+
+  lrs_clear_mp(Temp); lrs_clear_mp(scale);
+  return TRUE;
+}
+/********* end of lrs_getfirstbasis  ***************/
+
+
+/*****************************************/
+/* getnextbasis in reverse search order  */
+/*****************************************/
+
+
+long 
+lrs_getnextbasis (lrs_dic ** D_p, lrs_dat * Q, long backtrack)
+	 /* gets next reverse search tree basis, FALSE if none  */
+	 /* switches to estimator if maxdepth set               */
+	 /* backtrack TRUE means backtrack from here            */
+
+{
+  /* assign local variables to structures */
+  long i = 0L, j = 0L;
+  long m = D->m;
+  long d = D->d;
+
+
+
+  if (backtrack && D->depth == 0)
+    return FALSE;                       /* cannot backtrack from root      */
+
+  if (Q->maxoutput > 0 && Q->count[0]+Q->count[1]-Q->hull >= Q->maxoutput)
+     return FALSE;                      /* output limit reached            */
+
+  while ((j < d) || (D->B[m] != m))	/*main while loop for getnextbasis */
+    {
+      if (D->depth >= Q->maxdepth)
+	{
+	  backtrack = TRUE;
+	  if (Q->runs > 0)	/*get an estimate of remaining tree */
+	    lrs_estimate (D, Q);
+	  if (Q->maxdepth == 0)	/* estimate only */
+	    return FALSE;	/* no nextbasis  */
+	}
+
+/*      if ( Q->truncate && negative(D->A[0][0]))*/   /* truncate when moving from opt. vertex */
+/*          backtrack = TRUE;    2011.7.14 */
+
+      if (backtrack)		/* go back to prev. dictionary, restore i,j */
+	{
+	  backtrack = FALSE;
+
+	  if (check_cache (D_p, Q, &i, &j))
+	    {
+	      if (Q->debug)
+		fprintf (lrs_ofp, "\n Cached Dict. restored to depth %ld\n", D->depth);
+	    }
+	  else
+	    {
+	      D->depth--;
+	      selectpivot (D, Q, &i, &j);
+	      pivot (D, Q, i, j);
+	      update (D, Q, &i, &j);	/*Update B,C,i,j */
+	    }
+
+	  if (Q->debug)
+	    {
+	      fprintf (lrs_ofp, "\n Backtrack Pivot: indices i=%ld j=%ld depth=%ld", i, j, D->depth);
+	      printA (D, Q);
+	    };
+
+	  j++;			/* go to next column */
+	}			/* end of if backtrack  */
+
+      if (D->depth < Q->mindepth)
+	break;
+
+      /* try to go down tree */
+
+/* 2011.7.14 patch */
+      while ((j < d) && (!reverse (D, Q, &i, j) || (Q->truncate && Q->minratio[D->m]==1)))
+	j++;
+      if (j == d )
+	backtrack = TRUE;
+      else
+	/*reverse pivot found */
+	{
+	  cache_dict (D_p, Q, i, j);
+	  /* Note that the next two lines must come _after_ the 
+	     call to cache_dict */
+
+	  D->depth++;
+	  if (D->depth > Q->deepest)
+	    Q->deepest++;
+
+	  pivot (D, Q, i, j);
+	  update (D, Q, &i, &j);	/*Update B,C,i,j */
+
+	  D->lexflag = lexmin (D, Q, ZERO);	/* see if lexmin basis */
+	  Q->count[2]++;
+	  Q->totalnodes++;
+
+	  save_basis (*D_p, Q);
+	  if (Q->strace == Q->count[2])
+	    Q->debug = TRUE;
+	  if (Q->etrace == Q->count[2])
+	    Q->debug = FALSE;
+	  return TRUE;		/*return new dictionary */
+	}
+
+
+    }				/* end of main while loop for getnextbasis */
+  return FALSE;			/* done, no more bases */
+}				/*end of lrs_getnextbasis */
+
+/*************************************/
+/* print out one line of output file */
+/*************************************/
+long 
+lrs_getvertex (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output)
+/*Print out current vertex if it is lexmin and return it in output */
+/* return FALSE if no output generated  */
+{
+  lrs_mp_matrix A = P->A;
+
+  long i;
+  long ind;			/* output index                                  */
+  long ired;			/* counts number of redundant columns            */
+/* assign local variables to structures */
+  long *redundcol = Q->redundcol;
+  long *count = Q->count;
+  long *B = P->B;
+  long *Row = P->Row;
+
+  long lastdv = Q->lastdv;
+
+  long hull;
+  long m, d;
+  long lexflag;
+
+  hull = Q->hull;
+  m = P->m;
+  d = P->d;
+  lexflag = P->lexflag;
+  if (lexflag || Q->allbases)
+    ++(Q->count[1]);
+
+  if (Q->debug)
+    printA (P, Q);
+
+  linint (Q->sumdet, 1, P->det, 1);
+  if (Q->getvolume)
+   {
+    updatevolume (P, Q);
+    if(Q->verbose)   /* this will print out a triangulation */
+      lrs_printcobasis(P,Q,ZERO);
+   }
+
+
+  /*print cobasis if printcobasis=TRUE and count[2] a multiple of frequency */
+  /* or for lexmin basis, except origin for hull computation - ugly!        */
+
+  if (Q->printcobasis)
+    if ((lexflag && !hull)  || ((Q->frequency > 0) && (count[2] == (count[2] / Q->frequency) * Q->frequency)))
+      lrs_printcobasis (P, Q, ZERO);
+
+  if (hull)
+    return FALSE;		/* skip printing the origin */
+
+  if (!lexflag && !Q->allbases && !Q->lponly)	/* not lexmin, and not printing forced */
+    return FALSE;
+
+
+  /* copy column 0 to output */
+
+  i = 1;
+  ired = 0;
+  copy (output[0], P->det);
+
+  for (ind = 1; ind < Q->n; ind++)	/* extract solution */
+
+    if ((ired < Q->nredundcol) && (redundcol[ired] == ind))
+      /* column was deleted as redundant */
+      {
+	itomp (ZERO, output[ind]);
+	ired++;
+      }
+    else
+      /* column not deleted as redundant */
+      {
+	getnextoutput (P, Q, i, ZERO, output[ind]);
+	i++;
+      }
+
+  reducearray (output, Q->n);
+  if (lexflag && one(output[0]))
+      ++Q->count[4];               /* integer vertex */
+
+
+/* uncomment to print nonzero basic variables 
+
+ printf("\n nonzero basis: vars");
+  for(i=1;i<=lastdv; i++)
+   {
+    if ( !zero(A[Row[i]][0]) )
+         printf(" %ld ",B[i]);
+   }
+*/
+
+/* printslack inequality indices  */
+
+   if (Q->printslack)
+    {
+       fprintf(lrs_ofp,"\nslack ineq:");
+       for(i=lastdv+1;i<=P->m; i++)
+         {
+           if (!zero(A[Row[i]][0]))
+                 fprintf(lrs_ofp," %ld ", Q->inequality[B[i]-lastdv]);
+         }
+    }
+
+  return TRUE;
+}				/* end of lrs_getvertex */
+
+long 
+lrs_getray (lrs_dic * P, lrs_dat * Q, long col, long redcol, lrs_mp_vector output)
+/*Print out solution in col and return it in output   */
+/*redcol =n for ray/facet 0..n-1 for linearity column */
+/*hull=1 implies facets will be recovered             */
+/* return FALSE if no output generated in column col  */
+{
+  long i;
+  long ind;			/* output index                                  */
+  long ired;			/* counts number of redundant columns            */
+/* assign local variables to structures */
+  long *redundcol = Q->redundcol;
+  long *count = Q->count;
+  long hull = Q->hull;
+  long n = Q->n;
+
+  long *B = P->B;
+  long *Row = P->Row;
+  long lastdv = Q->lastdv;
+
+  if (Q->debug)
+    {
+      printA (P, Q);
+      for (i = 0; i < Q->nredundcol; i++)
+	fprintf (lrs_ofp, " %ld", redundcol[i]);
+      fflush(lrs_ofp);
+    }
+
+  if (redcol == n)
+    {
+      ++count[0];
+      if (Q->printcobasis)
+	lrs_printcobasis (P, Q, col);
+    }
+
+  i = 1;
+  ired = 0;
+
+  for (ind = 0; ind < n; ind++)	/* print solution */
+    {
+      if (ind == 0 && !hull)	/* must have a ray, set first column to zero */
+	itomp (ZERO, output[0]);
+
+      else if ((ired < Q->nredundcol) && (redundcol[ired] == ind))
+	/* column was deleted as redundant */
+	{
+	  if (redcol == ind)	/* true for linearity on this cobasic index */
+	    /* we print reduced determinant instead of zero */
+	    copy (output[ind], P->det);
+	  else
+	    itomp (ZERO, output[ind]);
+	  ired++;
+	}
+      else
+	/* column not deleted as redundant */
+	{
+	  getnextoutput (P, Q, i, col, output[ind]);
+	  i++;
+	}
+
+    }
+  reducearray (output, n);
+/* printslack for rays: 2006.10.10 */
+/* printslack inequality indices  */
+
+   if (Q->printslack)
+    {
+       fprintf(lrs_ofp,"\nslack ineq:");
+       for(i=lastdv+1;i<=P->m; i++)
+         {
+           if (!zero(P->A[Row[i]][col]))
+                 fprintf(lrs_ofp," %ld ", Q->inequality[B[i]-lastdv]);
+         }
+    }
+
+
+  return TRUE;
+}				/* end of lrs_getray */
+
+
+void 
+getnextoutput (lrs_dic * P, lrs_dat * Q, long i, long col, lrs_mp out)
+      /* get A[B[i][col] and copy to out */
+{
+  long row;
+  long m = P->m;
+  long d = P->d;
+  long lastdv = Q->lastdv;
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *Row = P->Row;
+  long j;
+
+  if (i == d && Q->voronoi)
+    return;			/* skip last column if voronoi set */
+
+  row = Row[i];
+
+  if (Q->nonnegative) 	/* if m+i basic get correct value from dictionary          */
+                        /* the slack for the inequality m-d+i contains decision    */
+                        /* variable x_i. We first see if this is in the basis      */
+                        /* otherwise the value of x_i is zero, except for a ray    */
+                        /* when it is one (det/det) for the actual column it is in */
+    {
+	for (j = lastdv+ 1; j <= m; j++)
+           {
+             if ( Q->inequality[B[j]-lastdv] == m-d+i )
+	          {
+                    copy (out, A[Row[j]][col]);
+                    return;
+                  }
+           }
+/* did not find inequality m-d+i in basis */
+      if ( i == col )
+            copy(out,P->det);
+      else
+            itomp(ZERO,out);
+	
+    }
+  else
+    copy (out, A[row][col]);
+
+}				/* end of getnextoutput */
+
+void 
+lrs_printcobasis (lrs_dic * P, lrs_dat * Q, long col)
+/* col is output column being printed */
+{
+  long i;
+  long rflag;			/* used to find inequality number for ray column */
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  lrs_mp Nvol, Dvol;		/* hold rescaled det of current basis */
+  long *B = P->B;
+  long *C = P->C;
+  long *Col = P->Col;
+  long *Row = P->Row;
+  long *inequality = Q->inequality;
+  long *temparray = Q->temparray;
+  long *count = Q->count;
+  long hull = Q->hull;
+  long d = P->d;
+  long lastdv = Q->lastdv;
+  long m=P->m;
+  long firstime=TRUE;
+  long nincidence;       /* count number of tight inequalities */
+
+  lrs_alloc_mp(Nvol); lrs_alloc_mp(Dvol);
+
+  if (hull)
+    fprintf (lrs_ofp, "\nF#%ld B#%ld h=%ld vertices/rays ", count[0], count[2], P->depth);
+  else if (Q->voronoi)
+    fprintf (lrs_ofp, "\nV#%ld R#%ld B#%ld h=%ld data points ", count[1], count[0], count[2], P->depth);
+  else
+    fprintf (lrs_ofp, "\nV#%ld R#%ld B#%ld h=%ld facets ", count[1], count[0], count[2], P->depth);
+
+  rflag = (-1);
+  for (i = 0; i < d; i++)
+    {
+      temparray[i] = inequality[C[i] - lastdv];
+      if (Col[i] == col)
+	rflag = temparray[i];	/* look for ray index */
+    }
+  for (i = 0; i < d; i++)
+    reorder (temparray, d);
+  for (i = 0; i < d; i++)
+    {
+      fprintf (lrs_ofp, " %ld", temparray[i]);
+
+      if (!(col == ZERO) && (rflag == temparray[i])) /* missing cobasis element for ray */
+           fprintf (lrs_ofp, "*");
+
+    }
+
+/* get and print incidence information */
+  if ( col == 0 )
+     nincidence = d;
+  else
+     nincidence = d-1;
+
+  for(i=lastdv+1;i<=m;i++)
+    if ( zero (A[Row[i]][0] ))
+       if( ( col == ZERO ) || zero (A[Row[i]] [col]) )
+          { 
+            nincidence++;
+            if( Q->incidence )
+              {
+                if (firstime)
+                  {
+                    fprintf (lrs_ofp," :");
+                    firstime = FALSE;
+                   }
+                fprintf(lrs_ofp," %ld",inequality[B[i] - lastdv ] );
+              }
+           }
+         
+  fprintf(lrs_ofp," I#%ld",nincidence);
+
+  pmp (" det=", P->det);
+      fflush (lrs_ofp);
+  rescaledet (P, Q, Nvol, Dvol); 	/* scales determinant in case input rational */
+  prat(" in_det=",Nvol,Dvol);
+  lrs_clear_mp(Nvol); lrs_clear_mp(Dvol);
+  
+
+}				/* end of lrs_printcobasis */
+
+/*********************/
+/* print final totals */
+/*********************/
+void 
+lrs_printtotals (lrs_dic * P, lrs_dat * Q)
+{
+  long i;
+  double x;
+/* local assignments */
+  double *cest = Q->cest;
+  long *count = Q->count;
+  long *inequality = Q->inequality;
+  long *linearity = Q->linearity;
+  long *temparray = Q->temparray;
+
+  long *C = P->C;
+
+  long hull = Q->hull;
+  long homogeneous = Q->homogeneous;
+  long nlinearity = Q->nlinearity;
+  long nredundcol = Q->nredundcol;
+  long m, d, lastdv;
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+  fprintf (lrs_ofp, "\nend");
+  if (Q->dualdeg)
+    {
+      fprintf (lrs_ofp, "\n*Warning: Starting dictionary is dual degenerate");
+      fprintf (lrs_ofp, "\n*Complete enumeration may not have been produced");
+      if (Q->maximize)
+         fprintf(lrs_ofp,"\n*Recommendation: Add dualperturb option before maximize in input file\n");
+      else
+         fprintf(lrs_ofp,"\n*Recommendation: Add dualperturb option before minimize in input file\n");
+    }
+
+  if (Q->unbounded)
+    {
+      fprintf (lrs_ofp, "\n*Warning: Starting dictionary contains rays");
+      fprintf (lrs_ofp, "\n*Complete enumeration may not have been produced");
+      if (Q->maximize)
+        fprintf(lrs_ofp,"\n*Recommendation: Change or remove maximize option or add bounds\n");
+      else
+        fprintf(lrs_ofp,"\n*Recommendation: Change or remove minimize option or add bounds\n");
+    }
+  if (Q->truncate)
+    fprintf(lrs_ofp,"\n*Tree truncated at each new vertex");
+  if (Q->maxdepth < MAXD)
+    fprintf (lrs_ofp, "\n*Tree truncated at depth %ld", Q->maxdepth);
+  if (Q->maxoutput > 0L)
+    fprintf (lrs_ofp, "\n*Maximum number of output lines = %ld", Q->maxoutput);
+
+
+#ifdef LONG
+  fprintf (lrs_ofp, "\n*Caution: no overflow checking with long integer arithemtic");
+#else
+  if( Q->verbose)
+    {
+      fprintf (lrs_ofp, "\n*Sum of det(B)=");
+      pmp ("", Q->sumdet);
+    }
+#endif
+
+/* next block with volume rescaling must come before estimates are printed */
+
+  if (Q->getvolume)
+    {
+      rescalevolume (P, Q, Q->Nvolume, Q->Dvolume);
+
+      if (Q->polytope)
+	prat ("\n*Volume=", Q->Nvolume, Q->Dvolume);
+      else
+	prat ("\n*Pseudovolume=", Q->Nvolume, Q->Dvolume);
+    }
+
+  if (hull)     /* output things that are specific to hull computation */
+    {
+      fprintf (lrs_ofp, "\n*Totals: facets=%ld bases=%ld", count[0], count[2]);
+
+      if (nredundcol > homogeneous)	/* don't count column 1 as redundant if homogeneous */
+       {
+        fprintf (lrs_ofp, " linearities=%ld", nredundcol - homogeneous);
+        fprintf (lrs_ofp, " facets+linearities=%ld",nredundcol-homogeneous+count[0]);
+       }
+
+
+      if ((cest[2] > 0) || (cest[0] > 0))
+      {
+	fprintf (lrs_ofp, "\n*Estimates: facets=%.0f bases=%.0f", count[0] + cest[0], count[2] + cest[2]);
+        if (Q->getvolume)
+	  {
+	    rattodouble (Q->Nvolume, Q->Dvolume, &x);
+	    for (i = 2; i < d; i++)
+	      cest[3] = cest[3] / i;	/*adjust for dimension */
+	    fprintf (lrs_ofp, " volume=%g", cest[3] + x);
+	  }
+
+      fprintf (lrs_ofp, "\n*Total number of tree nodes evaluated: %ld", Q->totalnodes);
+#ifdef TIMES
+      fprintf (lrs_ofp, "\n*Estimated total running time=%.1f secs ",(count[2]+cest[2])/Q->totalnodes*get_time () );
+#endif
+
+      }
+/*    Should not happen since we homogenize    */
+/*
+      if ( Q-> restart || Q->allbases || (count[0] > 1 && !Q->homogeneous && !Q->polytope))
+	    fprintf (lrs_ofp, "\n*Note! Duplicate facets may be present");
+*/
+
+    }
+  else         /* output things specific to vertex/ray computation */
+    {
+      fprintf (lrs_ofp, "\n*Totals: vertices=%ld rays=%ld bases=%ld", count[1], count[0], count[2]);
+      fprintf (lrs_ofp, " integer_vertices=%ld ",count[4]);
+
+      if (nredundcol > 0)
+        fprintf (lrs_ofp, " linearities=%ld", nredundcol);
+      if ( count[0] + nredundcol > 0 )
+         {
+           fprintf (lrs_ofp, " vertices+rays");
+           if ( nredundcol > 0 )
+              fprintf (lrs_ofp, "+linearities");
+           fprintf (lrs_ofp, "=%ld",nredundcol+count[0]+count[1]);
+         }
+
+      if ((cest[2] > 0) || (cest[0] > 0))
+        {
+	fprintf (lrs_ofp, "\n*Estimates: vertices=%.0f rays=%.0f", count[1]+cest[1], count[0]+cest[0]);
+	fprintf (lrs_ofp, " bases=%.0f integer_vertices=%.0f ",count[2]+cest[2], count[4]+cest[4]);
+
+         if (Q->getvolume)
+	   {
+	     rattodouble (Q->Nvolume, Q->Dvolume, &x);
+	     for (i = 2; i <= d-homogeneous; i++)
+	       cest[3] = cest[3] / i;	/*adjust for dimension */
+	     fprintf (lrs_ofp, " pseudovolume=%g", cest[3] + x);
+	   }
+         fprintf (lrs_ofp, "\n*Total number of tree nodes evaluated: %ld", Q->totalnodes);
+#ifdef TIMES
+         fprintf (lrs_ofp, "\n*Estimated total running time=%.1f secs ",(count[2]+cest[2])/Q->totalnodes*get_time () );
+#endif
+        }
+
+      if (Q->restart || Q->allbases)        /* print warning  */
+          fprintf (lrs_ofp, "\n*Note! Duplicate vertices/rays may be present");
+
+      else if ( (count[0] > 1 && !Q->homogeneous))
+          fprintf (lrs_ofp, "\n*Note! Duplicate rays may be present");
+
+    }				/* end of output for vertices/rays */
+
+
+  if(!Q->verbose)
+     return;
+
+  fprintf (lrs_ofp, "\n*Input size m=%ld rows n=%ld columns", P->m, Q->n);
+  if (hull)
+    fprintf (lrs_ofp, " working dimension=%ld", d - 1 + homogeneous);
+  else
+    fprintf (lrs_ofp, " working dimension=%ld", d);
+
+  fprintf (lrs_ofp, "\n*Starting cobasis defined by input rows");
+  for (i = 0; i < nlinearity; i++)
+    temparray[i] = linearity[i];
+  for (i = nlinearity; i < lastdv; i++)
+    temparray[i] = inequality[C[i - nlinearity] - lastdv];
+  for (i = 0; i < lastdv; i++)
+    reorder (temparray, lastdv);
+  for (i = 0; i < lastdv; i++)
+    fprintf (lrs_ofp, " %ld", temparray[i]);
+
+  fprintf (lrs_ofp, "\n*Dictionary Cache: max size= %ld misses= %ld/%ld   Tree Depth= %ld", dict_count, cache_misses, cache_tries, Q->deepest);
+
+
+}				/* end of lrs_printtotals */
+/************************/
+/*  Estimation function */
+/************************/
+void 
+lrs_estimate (lrs_dic * P, lrs_dat * Q)
+		   /*get estimate of tree size from current node    */
+		   /*current node is not counted.                   */
+		   /*cest[0]rays [1]vertices [2]bases [3]volume     */
+                   /*    [4] integer vertices                       */
+{
+
+  lrs_mp_vector output;		/* holds one line of output; ray,vertex,facet,linearity */
+  lrs_mp Nvol, Dvol;		/* hold volume of current basis */
+  long estdepth = 0;		/* depth of basis/vertex in subtree for estimate */
+  long i = 0, j = 0, k, nchild, runcount, col;
+  double prod = 0.0;
+  double cave[] =
+  {0.0, 0.0, 0.0, 0.0, 0.0};
+  double nvertices, nbases, nrays, nvol, nivertices;
+  long rays = 0;
+  double newvol = 0.0;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *isave = Q->isave;
+  long *jsave = Q->jsave;
+  double *cest = Q->cest;
+  long d = P->d;
+  lrs_alloc_mp(Nvol); lrs_alloc_mp(Dvol);
+/* Main Loop of Estimator */
+
+  output = lrs_alloc_mp_vector (Q->n);	/* output holds one line of output from dictionary     */
+
+  for (runcount = 1; runcount <= Q->runs; runcount++)
+    {				/* runcount counts number of random probes */
+      j = 0;
+      nchild = 1;
+      prod = 1;
+      nvertices = 0.0;
+      nbases = 0.0;
+      nrays = 0.0;
+      nvol = 0.0;
+      nivertices =0.0;
+      while (nchild != 0)	/* while not finished yet */
+	{
+
+	  nchild = 0;
+	  while (j < d)
+	    {
+	      if (reverse (P, Q, &i, j))
+		{
+		  isave[nchild] = i;
+		  jsave[nchild] = j;
+		  nchild++;
+		}
+	      j++;
+	    }
+
+	  if (estdepth == 0 && nchild == 0)
+	    {
+	      cest[0] = cest[0] + rays;		/* may be some rays here */
+              lrs_clear_mp(Nvol); lrs_clear_mp(Dvol);
+	      return;		/*subtree is a leaf */
+	    }
+
+	  prod = prod * nchild;
+	  nbases = nbases + prod;
+	  if (Q->debug)
+	    {
+	      fprintf (lrs_ofp, "   degree= %ld ", nchild);
+	      fprintf (lrs_ofp, "\nPossible reverse pivots: i,j=");
+	      for (k = 0; k < nchild; k++)
+		fprintf (lrs_ofp, "%ld,%ld ", isave[k], jsave[k]);
+	    }
+
+	  if (nchild > 0)	/*reverse pivot found choose random child */
+	    {
+	      k = myrandom (Q->seed, nchild);
+	      Q->seed = myrandom (Q->seed, 977L);
+	      i = isave[k];
+	      j = jsave[k];
+	      if (Q->debug)
+		fprintf (lrs_ofp, "  selected pivot k=%ld seed=%ld ", k, Q->seed);
+	      estdepth++;
+	      Q->totalnodes++;	/* calculate total number of nodes evaluated */
+	      pivot (P, Q, i, j);
+	      update (P, Q, &i, &j);	/*Update B,C,i,j */
+	      if (lexmin (P, Q, ZERO))	/* see if lexmin basis for vertex */
+                {
+		  nvertices = nvertices + prod;
+                                                    /* integer vertex estimate */
+                  if( lrs_getvertex(P,Q,output))
+                      { --Q->count[1];
+                       if  (one(output[0] ))
+                         { --Q->count[4];
+                           nivertices = nivertices + prod;
+                         }
+                      }
+                }
+
+	      rays = 0;
+	      for (col = 1; col <= d; col++)
+		if (negative (A[0][col]) && (ratio (P, Q, col) == 0) && lexmin (P, Q, col))
+		  rays++;
+	      nrays = nrays + prod * rays;	/* update ray info */
+
+	      if (Q->getvolume)
+		{
+		  rescaledet (P, Q, Nvol, Dvol);	/* scales determinant in case input rational */
+		  rattodouble (Nvol, Dvol, &newvol);
+		  nvol = nvol + newvol * prod;	/* adjusts volume for degree              */
+		}
+	      j = 0;
+	    }
+	}
+      cave[0] = cave[0] + nrays;
+      cave[1] = cave[1] + nvertices;
+      cave[2] = cave[2] + nbases;
+      cave[3] = cave[3] + nvol;
+      cave[4] = cave[4] + nivertices;
+
+/*  backtrack to root and do it again */
+
+      while (estdepth > 0)
+	{
+	  estdepth = estdepth - 1;
+	  selectpivot (P, Q, &i, &j);
+	  pivot (P, Q, i, j);
+	  update (P, Q, &i, &j);	/*Update B,C,i,j */
+	  /*fprintf(lrs_ofp,"\n0  +++"); */
+	  if (Q->debug)
+	    {
+	      fprintf (lrs_ofp, "\n Backtrack Pivot: indices i,j %ld %ld ", i, j);
+	      printA (P, Q);
+	    }
+	  j++;
+	}
+
+    }				/* end of for loop on runcount */
+  for (i = 0; i < 5; i++)
+    cest[i] = cave[i] / Q->runs + cest[i];
+  
+  lrs_clear_mp(Nvol); lrs_clear_mp(Dvol);
+  lrs_clear_mp_vector(output, Q->n);
+}				/* end of lrs_estimate  */
+
+
+/*********************************/
+/* Internal functions            */
+/*********************************/
+/* Basic Dictionary functions    */
+/******************************* */
+
+long 
+reverse (lrs_dic * P, lrs_dat * Q, long *r, long s)
+/*  find reverse indices  */
+/* TRUE if B[*r] C[s] is a reverse lexicographic pivot */
+{
+  long i, j, enter, row, col;
+
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long d = P->d;
+
+  enter = C[s];
+  col = Col[s];
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\n+reverse: col index %ld C %ld Col %ld ", s, enter, col);
+      fflush (lrs_ofp);
+    }
+  if (!negative (A[0][col]))
+    {
+      if (Q->debug)
+	fprintf (lrs_ofp, " Pos/Zero Cost Coeff");
+      Q->minratio[P->m]=0;  /* 2011.7.14 */
+      return (FALSE);
+    }
+
+  *r = ratio (P, Q, col);
+  if (*r == 0)			/* we have a ray */
+    {
+      if (Q->debug)
+	fprintf (lrs_ofp, " Pivot col non-negative:  ray found");
+      Q->minratio[P->m]=0;  /* 2011.7.14 */
+      return (FALSE);
+    }
+
+  row = Row[*r];
+
+/* check cost row after "pivot" for smaller leaving index    */
+/* ie. j s.t.  A[0][j]*A[row][col] < A[0][col]*A[row][j]     */
+/* note both A[row][col] and A[0][col] are negative          */
+
+  for (i = 0; i < d && C[i] < B[*r]; i++)
+    if (i != s)
+      {
+	j = Col[i];
+	if (positive (A[0][j]) || negative (A[row][j]))		/*or else sign test fails trivially */
+	  if ((!negative (A[0][j]) && !positive (A[row][j])) ||
+	      comprod (A[0][j], A[row][col], A[0][col], A[row][j]) == -1)
+	    {			/*+ve cost found */
+	      if (Q->debug)
+               {
+		fprintf (lrs_ofp, "\nPositive cost found: index %ld C %ld Col %ld", i, C[i], j);
+                fflush(lrs_ofp);
+               }
+              Q->minratio[P->m]=0;  /* 2011.7.14 */
+
+	      return (FALSE);
+	    }
+      }
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\n+end of reverse : indices r %ld s %ld \n", *r, s);
+      fflush (stdout);
+    }
+  return (TRUE);
+}				/* end of reverse */
+
+long 
+selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s)
+/* select pivot indices using lexicographic rule   */
+/* returns TRUE if pivot found else FALSE          */
+/* pivot variables are B[*r] C[*s] in locations Row[*r] Col[*s] */
+{
+  long j, col;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *Col = P->Col;
+  long d = P->d;
+
+  *r = 0;
+  *s = d;
+  j = 0;
+
+/*find positive cost coef */
+  while ((j < d) && (!positive (A[0][Col[j]])))
+    j++;
+
+  if (j < d)			/* pivot column found! */
+    {
+      *s = j;
+      col = Col[j];
+
+      /*find min index ratio */
+      *r = ratio (P, Q, col);
+      if (*r != 0)
+	return (TRUE);		/* unbounded */
+    }
+  return (FALSE);
+}				/* end of selectpivot        */
+/******************************************************* */
+
+void 
+pivot (lrs_dic * P, lrs_dat * Q, long bas, long cob)
+		     /* Qpivot routine for array A              */
+		     /* indices bas, cob are for Basis B and CoBasis C    */
+		     /* corresponding to row Row[bas] and column       */
+		     /* Col[cob]   respectively                       */
+{
+  long r, s;
+  long i, j;
+  lrs_mp Ns, Nt, Ars;
+/* assign local variables to structures */
+
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m, d, m_A;
+
+  lrs_alloc_mp(Ns); lrs_alloc_mp(Nt); lrs_alloc_mp(Ars);
+
+  m = P->m;
+  d = P->d;
+  m_A = P->m_A;
+  Q->count[3]++;    /* count the pivot */
+
+  r = Row[bas];
+  s = Col[cob];
+
+/* Ars=A[r][s]    */
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\n pivot  B[%ld]=%ld  C[%ld]=%ld ", bas, B[bas], cob, C[cob]);
+      printA(P,Q);
+      fflush (stdout);
+    }
+  copy (Ars, A[r][s]);
+  storesign (P->det, sign (Ars));	/*adjust determinant to new sign */
+
+
+  for (i = 0; i <= m_A; i++)
+    if (i != r)
+      for (j = 0; j <= d; j++)
+	if (j != s)
+	  {
+/*          A[i][j]=(A[i][j]*Ars-A[i][s]*A[r][j])/P->det; */
+
+	    mulint (A[i][j], Ars, Nt);
+	    mulint (A[i][s], A[r][j], Ns);
+	    decint (Nt, Ns);
+	    exactdivint (Nt, P->det, A[i][j]);
+	  }			/* end if j ....  */
+
+  if (sign (Ars) == POS)
+    {
+      for (j = 0; j <= d; j++)	/* no need to change sign if Ars neg */
+	/*   A[r][j]=-A[r][j];              */
+	if (!zero (A[r][j]))
+	  changesign (A[r][j]);
+    }				/* watch out for above "if" when removing this "}" ! */
+  else
+    for (i = 0; i <= m_A; i++)
+      if (!zero (A[i][s]))
+	changesign (A[i][s]);
+
+  /*  A[r][s]=P->det;                  */
+
+  copy (A[r][s], P->det);		/* restore old determinant */
+  copy (P->det, Ars);
+  storesign (P->det, POS);		/* always keep positive determinant */
+
+
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, " depth=%ld ", P->depth);
+      pmp ("det=", P->det);
+      fflush(stdout);
+    }
+/* set the new rescaled objective function value */
+
+  mulint (P->det, Q->Lcm[0], P->objden);
+  mulint (Q->Gcd[0], A[0][0], P->objnum);
+
+  if (!Q->maximize)
+        changesign (P->objnum);
+  if (zero (P->objnum))
+        storesign (P->objnum, POS);
+  else
+	reduce (P->objnum,P->objden);
+
+
+  lrs_clear_mp(Ns); lrs_clear_mp(Nt); lrs_clear_mp(Ars);
+}				/* end of pivot */
+
+long 
+primalfeasible (lrs_dic * P, lrs_dat * Q)
+/* Do dual pivots to get primal feasibility */
+/* Note that cost row is all zero, so no ratio test needed for Dual Bland's rule */
+{
+  long primalinfeasible = TRUE;
+  long i, j;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m, d, lastdv;
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+/*temporary: try to get new start after linearity */
+
+  while (primalinfeasible)
+    {
+      i=lastdv+1;
+      while (i <= m && !negative (A[Row[i]][0]) )
+        i++;
+      if (i <= m )
+	{
+	      j = 0;		/*find a positive entry for in row */
+	      while (j < d && !positive (A[Row[i]][Col[j]]))
+		j++;
+	      if (j >= d)
+		return (FALSE);	/* no positive entry */
+	      pivot (P, Q, i, j);
+	      update (P, Q, &i, &j);
+        }
+      else
+         primalinfeasible = FALSE;
+    }				/* end of while primalinfeasibile */
+  return (TRUE);
+}				/* end of primalfeasible */
+
+
+long 
+lrs_solvelp (lrs_dic * P, lrs_dat * Q, long maximize)
+/* Solve primal feasible lp by Dantzig`s rule and lexicographic ratio test */
+/* return TRUE if bounded, FALSE if unbounded                              */
+{
+  long i, j;
+/* assign local variables to structures */
+  long d = P->d;
+
+  while (dan_selectpivot (P, Q, &i, &j))
+    {
+      Q->count[3]++;
+      pivot (P, Q, i, j);
+      update (P, Q, &i, &j);	/*Update B,C,i,j */
+    }
+  if (Q->debug)
+    printA (P, Q);
+
+  if (j < d && i == 0)		/* selectpivot gives information on unbounded solution */
+    {
+#ifndef LRS_QUIET
+      if (Q->lponly)
+	fprintf (lrs_ofp, "\n*Unbounded solution");
+#endif
+      return FALSE;
+    }
+  return TRUE;
+}				/* end of lrs_solvelp  */
+
+long 
+getabasis (lrs_dic * P, lrs_dat * Q, long order[])
+
+/* Pivot Ax<=b to standard form */
+/*Try to find a starting basis by pivoting in the variables x[1]..x[d]        */
+/*If there are any input linearities, these appear first in order[]           */
+/* Steps: (a) Try to pivot out basic variables using order                    */
+/*            Stop if some linearity cannot be made to leave basis            */
+/*        (b) Permanently remove the cobasic indices of linearities           */
+/*        (c) If some decision variable cobasic, it is a linearity,           */
+/*            and will be removed.                                            */
+
+{
+  long i, j, k;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long *linearity = Q->linearity;
+  long *redundcol = Q->redundcol;
+  long m, d, nlinearity;
+  long nredundcol = 0L;		/* will be calculated here */
+  m = P->m;
+  d = P->d;
+  nlinearity = Q->nlinearity;
+
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\ngetabasis from inequalities given in order");
+      for (i = 0; i < m; i++)
+	fprintf (lrs_ofp, " %ld", order[i]);
+    }
+  for (j = 0; j < m; j++)
+    {
+      i = 0;
+      while (i <= m && B[i] != d + order[j])
+	i++;			/* find leaving basis index i */
+      if (j < nlinearity && i > m)	/* cannot pivot linearity to cobasis */
+	{
+	  if (Q->debug)
+	    printA (P, Q);
+#ifndef LRS_QUIET
+	  fprintf (lrs_ofp, "\nCannot find linearity in the basis");
+#endif
+	  return FALSE;
+	}
+      if (i <= m)
+	{			/* try to do a pivot */
+	  k = 0;
+	  while (C[k] <= d && zero (A[Row[i]][Col[k]]))
+	    k++;
+
+	  if (C[k] <= d)
+	    {
+	      pivot (P, Q, i, k);
+	      update (P, Q, &i, &k);
+	    }
+	  else if (j < nlinearity)
+	    {			/* cannot pivot linearity to cobasis */
+	      if (zero (A[Row[i]][0]))
+		{
+#ifndef LRS_QUIET
+		  fprintf (lrs_ofp, "\n*Input linearity in row %ld is redundant--converted to inequality", order[j]);
+#endif
+                  linearity[j]=0;
+		}
+	      else
+		{
+		  if (Q->debug)
+		    printA (P, Q);
+#ifndef LRS_QUIET
+		  fprintf (lrs_ofp, "\n*Input linearity in row %ld is inconsistent with earlier linearities", order[j]);
+		  fprintf (lrs_ofp, "\n*No feasible solution");
+#endif
+		  return FALSE;
+		}
+	    }			/* end if j < nlinearity */
+
+	}			/* end of if i <= m .... */
+    }				/* end of for   */
+
+/* update linearity array to get rid of redundancies */
+  i = 0;
+  k = 0;			/* counters for linearities         */
+  while (k < nlinearity)
+    {
+      while (k < nlinearity && linearity[k] == 0)
+	k++;
+      if (k < nlinearity)
+	linearity[i++] = linearity[k++];
+    }
+
+  nlinearity = i;
+/* bug fix, 2009.6.27 */    Q->nlinearity = i;
+
+/* column dependencies now can be recorded  */
+/* redundcol contains input column number 0..n-1 where redundancy is */
+  k = 0;
+  while (k < d && C[k] <= d)
+    {
+      if (C[k] <= d)		/* decision variable still in cobasis */
+	redundcol[nredundcol++] = C[k] - Q->hull;	/* adjust for hull indices */
+      k++;
+    }
+
+/* now we know how many decision variables remain in problem */
+  Q->nredundcol = nredundcol;
+  Q->lastdv = d - nredundcol;
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\nend of first phase of getabasis: ");
+      fprintf (lrs_ofp, "lastdv=%ld nredundcol=%ld", Q->lastdv, Q->nredundcol);
+      fprintf (lrs_ofp, "\nredundant cobases:");
+      for (i = 0; i < nredundcol; i++)
+	fprintf (lrs_ofp, " %ld", redundcol[i]);
+      printA (P, Q);
+    }
+
+/* Remove linearities from cobasis for rest of computation */
+/* This is done in order so indexing is not screwed up */
+
+  for (i = 0; i < nlinearity; i++)
+    {				/* find cobasic index */
+      k = 0;
+      while (k < d && C[k] != linearity[i] + d)
+	k++;
+      if (k >= d)
+	{
+	  fprintf (lrs_ofp, "\nError removing linearity");
+	  return FALSE;
+	}
+      if (!removecobasicindex (P, Q, k))
+	return FALSE;
+      d = P->d;
+    }
+  if (Q->debug && nlinearity > 0)
+    printA (P, Q);
+/* set index value for first slack variable */
+
+/* Check feasability */
+  if (Q->givenstart)
+    {
+      i = Q->lastdv + 1;
+      while (i <= m && !negative (A[Row[i]][0]))
+	i++;
+      if (i <= m)
+	fprintf (lrs_ofp, "\n*Infeasible startingcobasis - will be modified");
+    }
+  return TRUE;
+}				/*  end of getabasis */
+
+long 
+removecobasicindex (lrs_dic * P, lrs_dat * Q, long k)
+/* remove the variable C[k] from the problem */
+/* used after detecting column dependency    */
+{
+  long i, j, cindex, deloc;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Col = P->Col;
+  long m, d;
+  m = P->m;
+  d = P->d;
+
+  if (Q->debug)
+    fprintf (lrs_ofp, "\nremoving cobasic index k=%ld C[k]=%ld", k, C[k]);
+  cindex = C[k];		/* cobasic index to remove              */
+  deloc = Col[k];		/* matrix column location to remove     */
+
+  for (i = 1; i <= m; i++)	/* reduce basic indices by 1 after index */
+    if (B[i] > cindex)
+      B[i]--;
+  
+  for (j = k; j < d; j++)	/* move down other cobasic variables    */
+    {
+      C[j] = C[j + 1] - 1;	/* cobasic index reduced by 1           */
+      Col[j] = Col[j + 1];
+    }
+
+  if (deloc != d)               
+    {
+  /* copy col d to deloc */
+      for (i = 0; i <= m; i++)
+        copy (A[i][deloc], A[i][d]);
+
+  /* reassign location for moved column */
+      j = 0;
+      while (Col[j] != d)
+        j++;
+      
+    Col[j] = deloc;
+  }
+
+  P->d--;
+  if (Q->debug)
+    printA (P, Q);
+  return TRUE;
+}				/* end of removecobasicindex */
+
+lrs_dic *
+resize (lrs_dic * P, lrs_dat * Q)
+	/* resize the dictionary after some columns are deleted, ie. inputd>d */
+	/* a new lrs_dic record is created with reduced size, and items copied over */
+{
+  lrs_dic *P1;			/* to hold new dictionary in case of resizing */
+
+  long i, j;
+  long m, d, m_A;
+
+
+  m = P->m;
+  d = P->d;
+  m_A = P->m_A;
+
+/* get new dictionary record */
+
+  P1 = new_lrs_dic (m, d, m_A);
+
+/* copy data from P to P1    */
+  P1->i = P->i;
+  P1->j = P->j;
+  P1->depth = P->depth;
+  P1->m = P->m;
+  P1->d = P1->d_orig = d;
+  P1->lexflag = P->lexflag;
+  P1->m_A = P->m_A;
+  copy (P1->det, P->det);
+  copy (P1->objnum, P->objnum);
+  copy (P1->objden, P->objden);
+
+  for (i = 0; i <= m; i++)
+    {
+      P1->B[i] = P->B[i];
+      P1->Row[i] = P->Row[i];
+    }
+  for (i = 0; i <= m_A; i++)
+    {
+      for (j = 0; j <= d; j++)
+	copy (P1->A[i][j], P->A[i][j]);
+    }
+
+
+  for (j = 0; j <= d; j++)
+    {
+      P1->Col[j] = P->Col[j];
+      P1->C[j] = P->C[j];
+    }
+
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "\nDictionary resized from d=%ld to d=%ld", Q->inputd, P->d);
+      printA (P1, Q);
+    }
+
+  lrs_free_dic (P,Q);
+
+/* Reassign cache pointers */
+
+  Q->Qhead = P1;
+  Q->Qtail = P1;
+  P1->next = P1;
+  P1->prev = P1;
+
+  return P1;
+
+}
+/********* resize                    ***************/
+
+
+long 
+restartpivots (lrs_dic * P, lrs_dat * Q)
+/* facet contains a list of the inequalities in the cobasis for the restart */
+/* inequality contains the relabelled inequalities after initialization     */
+{
+  long i, j, k;
+  long *Cobasic;		/* when restarting, Cobasic[j]=1 if j is in cobasis */
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long *inequality = Q->inequality;
+  long *facet = Q->facet;
+  long nlinearity = Q->nlinearity;
+  long m, d, lastdv;
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+  Cobasic = (long *) CALLOC ((unsigned) m + d + 2, sizeof (long));
+
+  if (Q->debug)
+    fprintf(lrs_ofp,"\nCobasic flags in restartpivots");
+  /* set Cobasic flags */
+  for (i = 0; i < m + d + 1; i++)
+    Cobasic[i] = 0;
+  for (i = 0; i < d; i++)	/* find index corresponding to facet[i] */
+    {
+      j = 1;
+      while (facet[i + nlinearity] != inequality[j])
+	j++;
+      Cobasic[j + lastdv] = 1;
+      if (Q->debug)
+        fprintf(lrs_ofp," %ld %ld;",facet[i+nlinearity],j+lastdv);
+    }
+
+  /* Note that the order of doing the pivots is important, as */
+  /* the B and C vectors are reordered after each pivot       */
+
+/* code below replaced 2006.10.30 */
+/*
+
+  for (i = m; i >= d + 1; i--)	
+    if (Cobasic[B[i]])	
+      {
+	k = d - 1;
+	while ((k >= 0) &&
+	       (zero (A[Row[i]][Col[k]]) || Cobasic[C[k]]))
+	  k--;
+	if (k >= 0)
+	  {
+	    pivot (P, Q, i, k);
+	    update (P, Q, &i, &k);
+	  }
+	else
+	  {
+	    fprintf (lrs_ofp, "\nInvalid Co-basis - does not have correct rank");
+            free(Cobasic);
+	    return FALSE;
+	  }
+      }
+*/     
+/*end of code that was replaced */	
+
+/* Suggested new code from db starts */
+  i=m;
+  while (i>d){
+    while(Cobasic[B[i]]){
+      k = d - 1;
+      while ((k >= 0) && (zero (A[Row[i]][Col[k]]) || Cobasic[C[k]])){
+       k--;
+      }
+      if (k >= 0)  {
+           /*db asks: should i really be modified here? (see old code) */
+           /*da replies: modifying i only makes is larger, and so      */
+           /*the second while loop will put it back where it was       */
+           /*faster (and safer) as done below                          */
+       long  ii=i;
+       pivot (P, Q, ii, k);
+       update (P, Q, &ii, &k);
+      } else {
+       fprintf (lrs_ofp, "\nInvalid Co-basis - does not have correct rank");
+       free(Cobasic);
+       return FALSE;
+      }
+    }
+    i--;
+  }
+/* Suggested new code from db ends */
+
+  if (lexmin (P, Q, ZERO))
+    --Q->count[1];		/* decrement vertex count if lexmin */
+/* check restarting from a primal feasible dictionary               */
+  for (i = lastdv + 1; i <= m; i++)
+    if (negative (A[Row[i]][0]))
+      {
+	fprintf (lrs_ofp, "\nTrying to restart from infeasible dictionary");
+        free(Cobasic);
+	return FALSE;
+      }
+  free(Cobasic);
+  return TRUE;
+
+}				/* end of restartpivots */
+
+
+long 
+ratio (lrs_dic * P, lrs_dat * Q, long col)	/*find lex min. ratio */
+		  /* find min index ratio -aig/ais, ais<0 */
+		  /* if multiple, checks successive basis columns */
+		  /* recoded Dec 1997                     */
+{
+  long i, j, comp, ratiocol, basicindex, start, nstart, cindex, bindex;
+  long firstime;		/*For ratio test, true on first pass,else false */
+  lrs_mp Nmin, Dmin;
+  long degencount, ndegencount;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long *minratio = Q->minratio;
+  long m, d, lastdv;
+
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+
+  nstart=0;
+  ndegencount=0;
+  degencount = 0;
+  minratio[P->m]=1;   /*2011.7.14 non-degenerate pivot flag */
+
+  for (j = lastdv + 1; j <= m; j++)
+    {
+      /* search rows with negative coefficient in dictionary */
+      /*  minratio contains indices of min ratio cols        */
+      if (negative (A[Row[j]][col]))
+       {
+	minratio[degencount++] = j;
+        if(zero (A[Row[j]][0]))
+          minratio[P->m]=0;   /*2011.7.14 degenerate pivot flag */
+       }
+    }				/* end of for loop */
+  if (Q->debug)
+    {
+      fprintf (lrs_ofp, "  Min ratios: ");
+      for (i = 0; i < degencount; i++)
+	fprintf (lrs_ofp, " %ld ", B[minratio[i]]);
+    }
+  if (degencount == 0)
+    return (degencount);	/* non-negative pivot column */
+
+  lrs_alloc_mp(Nmin); lrs_alloc_mp(Dmin);
+  ratiocol = 0;			/* column being checked, initially rhs */
+  start = 0;			/* starting location in minratio array */
+  bindex = d + 1;		/* index of next basic variable to consider */
+  cindex = 0;			/* index of next cobasic variable to consider */
+  basicindex = d;		/* index of basis inverse for current ratio test, except d=rhs test */
+  while (degencount > 1)	/*keep going until unique min ratio found */
+    {
+      if (B[bindex] == basicindex)	/* identity col in basis inverse */
+	{
+	  if (minratio[start] == bindex)
+	    /* remove this index, all others stay */
+	    {
+	      start++;
+	      degencount--;
+	    }
+	  bindex++;
+	}
+      else
+	/* perform ratio test on rhs or column of basis inverse */
+	{
+	  firstime = TRUE;
+	  /*get next ratio column and increment cindex */
+	  if (basicindex != d)
+	    ratiocol = Col[cindex++];
+	  for (j = start; j < start + degencount; j++)
+	    {
+	      i = Row[minratio[j]];	/* i is the row location of the next basic variable */
+	      comp = 1;		/* 1:  lhs>rhs;  0:lhs=rhs; -1: lhs<rhs */
+	      if (firstime)
+		firstime = FALSE;	/*force new min ratio on first time */
+	      else
+		{
+		  if (positive (Nmin) || negative (A[i][ratiocol]))
+		    {
+		      if (negative (Nmin) || positive (A[i][ratiocol]))
+			comp = comprod (Nmin, A[i][col], A[i][ratiocol], Dmin);
+		      else
+			comp = -1;
+		    }
+
+		  else if (zero (Nmin) && zero (A[i][ratiocol]))
+		    comp = 0;
+
+		  if (ratiocol == ZERO)
+		    comp = -comp;	/* all signs reversed for rhs */
+		}
+	      if (comp == 1)
+		{		/*new minimum ratio */
+		  nstart = j;
+		  copy (Nmin, A[i][ratiocol]);
+		  copy (Dmin, A[i][col]);
+		  ndegencount = 1;
+		}
+	      else if (comp == 0)	/* repeated minimum */
+		minratio[nstart + ndegencount++] = minratio[j];
+
+	    }			/* end of  for (j=start.... */
+	  degencount = ndegencount;
+	  start = nstart;
+	}			/* end of else perform ratio test statement */
+      basicindex++;		/* increment column of basis inverse to check next */
+      if (Q->debug)
+	{
+	  fprintf (lrs_ofp, " ratiocol=%ld degencount=%ld ", ratiocol, degencount);
+	  fprintf (lrs_ofp, "  Min ratios: ");
+	  for (i = start; i < start + degencount; i++)
+	    fprintf (lrs_ofp, " %ld ", B[minratio[i]]);
+	}
+    }				/*end of while loop */
+  lrs_clear_mp(Nmin); lrs_clear_mp(Dmin);
+  return (minratio[start]);
+}				/* end of ratio */
+
+
+
+long 
+lexmin (lrs_dic * P, lrs_dat * Q, long col)
+  /*test if basis is lex-min for vertex or ray, if so TRUE */
+  /* FALSE if a_r,g=0, a_rs !=0, r > s          */
+{
+/*do lexmin test for vertex if col=0, otherwise for ray */
+  long r, s, i, j;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m = P->m;
+  long d = P->d;
+
+  for (i = Q->lastdv + 1; i <= m; i++)
+    {
+      r = Row[i];
+      if (zero (A[r][col]))	/* necessary for lexmin to fail */
+	for (j = 0; j < d; j++)
+	  {
+	    s = Col[j];
+	    if (B[i] > C[j])	/* possible pivot to reduce basis */
+	      {
+		if (zero (A[r][0]))	/* no need for ratio test, any pivot feasible */
+		  {
+		    if (!zero (A[r][s]))
+		      return (FALSE);
+		  }
+		else if (negative (A[r][s]) && ismin (P, Q, r, s))
+		  {
+		    return (FALSE);
+		  }
+	      }			/* end of if B[i] ... */
+	  }
+    }
+  if ((col != ZERO) && Q->debug)
+    {
+      fprintf (lrs_ofp, "\n lexmin ray in col=%ld ", col);
+      printA (P, Q);
+    }
+  return (TRUE);
+}				/* end of lexmin */
+
+long 
+ismin (lrs_dic * P, lrs_dat * Q, long r, long s)
+/*test if A[r][s] is a min ratio for col s */
+{
+  long i;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long m_A = P->m_A;
+
+  for (i = 1; i <= m_A; i++)
+    if ((i != r) &&
+	negative (A[i][s]) && comprod (A[i][0], A[r][s], A[i][s], A[r][0]))
+      {
+	return (FALSE);
+      }
+
+  return (TRUE);
+}
+
+void 
+update (lrs_dic * P, lrs_dat * Q, long *i, long *j)
+ /*update the B,C arrays after a pivot */
+ /*   involving B[bas] and C[cob]           */
+{
+
+  long leave, enter;
+/* assign local variables to structures */
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m = P->m;
+  long d = P->d;
+
+  leave = B[*i];
+  enter = C[*j];
+  B[*i] = enter;
+  reorder1 (B, Row, *i, m + 1);
+  C[*j] = leave;
+  reorder1 (C, Col, *j, d);
+/* restore i and j to new positions in basis */
+  for (*i = 1; B[*i] != enter; (*i)++);		/*Find basis index */
+  for (*j = 0; C[*j] != leave; (*j)++);		/*Find co-basis index */
+}				/* end of update */
+
+long 
+lrs_degenerate (lrs_dic * P, lrs_dat * Q)
+/* TRUE if the current dictionary is primal degenerate */
+/* not thoroughly tested   2000/02/15                  */
+{
+  long i;
+  long *B, *Row;
+
+  lrs_mp_matrix A = P->A;
+  long d = P->d;
+  long m = P->m;
+
+  B = P->B;
+  Row = P->Row;
+
+  for (i = d + 1; i <= m; i++)
+    if (zero (A[Row[i]][0]))
+      return TRUE;
+
+  return FALSE;
+}
+
+
+/*********************************************************/
+/*                 Miscellaneous                         */
+/******************************************************* */
+
+void 
+reorder (long a[], long range)
+/*reorder array in increasing order with one misplaced element */
+{
+  long i, temp;
+  for (i = 0; i < range - 1; i++)
+    if (a[i] > a[i + 1])
+      {
+	temp = a[i];
+	a[i] = a[i + 1];
+	a[i + 1] = temp;
+      }
+  for (i = range - 2; i >= 0; i--)
+    if (a[i] > a[i + 1])
+      {
+	temp = a[i];
+	a[i] = a[i + 1];
+	a[i + 1] = temp;
+      }
+
+}				/* end of reorder */
+
+void 
+reorder1 (long a[], long b[], long newone, long range)
+/*reorder array a in increasing order with one misplaced element at index newone */
+/*elements of array b are updated to stay aligned with a */
+{
+  long temp;
+  while (newone > 0 && a[newone] < a[newone - 1])
+    {
+      temp = a[newone];
+      a[newone] = a[newone - 1];
+      a[newone - 1] = temp;
+      temp = b[newone];
+      b[newone] = b[newone - 1];
+      b[--newone] = temp;
+    }
+  while (newone < range - 1 && a[newone] > a[newone + 1])
+    {
+      temp = a[newone];
+      a[newone] = a[newone + 1];
+      a[newone + 1] = temp;
+      temp = b[newone];
+      b[newone] = b[newone + 1];
+      b[++newone] = temp;
+    }
+}				/* end of reorder1 */
+
+
+void 
+rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden)
+  /* rescale determinant to get its volume */
+  /* Vnum/Vden is volume of current basis  */
+{
+  lrs_mp gcdprod;		/* to hold scale factors */
+  long i;
+/* assign local variables to structures */
+  long *B = P->B;
+  long *C = P->C;
+  long m, d, lastdv;
+
+  lrs_alloc_mp(gcdprod);
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+  itomp (ONE, gcdprod);
+  itomp (ONE, Vden);
+  for (i = 0; i < d; i++)
+    if (B[i] <= m)
+      {
+	mulint (Q->Gcd[Q->inequality[C[i] - lastdv]], gcdprod, gcdprod);
+	mulint (Q->Lcm[Q->inequality[C[i] - lastdv]], Vden, Vden);
+      }
+  mulint (P->det, gcdprod, Vnum);
+  reduce (Vnum, Vden);
+  lrs_clear_mp(gcdprod);
+}				/* end rescaledet */
+
+void 
+rescalevolume (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden)
+/* adjust volume for dimension */
+{
+  lrs_mp temp, dfactorial;
+/* assign local variables to structures */
+  long lastdv = Q->lastdv;
+
+  lrs_alloc_mp(temp); lrs_alloc_mp(dfactorial);
+
+  /*reduce Vnum by d factorial  */
+  getfactorial (dfactorial, lastdv);
+  mulint (dfactorial, Vden, Vden);
+  if (Q->hull && !Q->homogeneous)
+    {				/* For hull option multiply by d to correct for lifting */
+      itomp (lastdv, temp);
+      mulint (temp, Vnum, Vnum);
+    }
+
+  reduce (Vnum, Vden);
+  lrs_clear_mp(temp); lrs_clear_mp(dfactorial);
+}
+
+
+void 
+updatevolume (lrs_dic * P, lrs_dat * Q)		/* rescale determinant and update the volume */
+{
+  lrs_mp tN, tD, Vnum, Vden;
+  lrs_alloc_mp(tN); lrs_alloc_mp(tD); lrs_alloc_mp(Vnum); lrs_alloc_mp(Vden);
+  rescaledet (P, Q, Vnum, Vden);
+  copy (tN, Q->Nvolume);
+  copy (tD, Q->Dvolume);
+  linrat (tN, tD, ONE, Vnum, Vden, ONE, Q->Nvolume, Q->Dvolume);
+  if (Q->debug)
+    {
+      prat ("\n*Volume=", Q->Nvolume, Q->Dvolume);
+      pmp (" Vnum=", Vnum);
+      pmp (" Vden=", Vden);
+    }
+  lrs_clear_mp(tN); lrs_clear_mp(tD); lrs_clear_mp(Vnum); lrs_clear_mp(Vden);
+
+}				/* end of updatevolume */
+
+
+
+/***************************************************/
+/* Routines for redundancy checking                */
+/***************************************************/
+
+long 
+checkredund (lrs_dic * P, lrs_dat * Q)
+/* Solve primal feasible lp by least subscript and lex min basis method */
+/* to check redundancy of a row in objective function                   */
+/* returns TRUE if redundant, else FALSE                                */
+{
+  lrs_mp Ns, Nt;
+  long i, j;
+  long r, s;
+
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B, *C, *Row, *Col;
+  long d = P->d;
+
+  lrs_alloc_mp(Ns); lrs_alloc_mp(Nt);
+  B = P->B;
+  C = P->C;
+  Row = P->Row;
+  Col = P->Col;
+
+  while (selectpivot (P, Q, &i, &j))
+    {
+      Q->count[2]++;
+
+/* sign of new value of A[0][0]            */
+/* is      A[0][s]*A[r][0]-A[0][0]*A[r][s] */
+
+      r = Row[i];
+      s = Col[j];
+
+      mulint (A[0][s], A[r][0], Ns);
+      mulint (A[0][0], A[r][s], Nt);
+
+      if (greater (Ns, Nt))
+        {
+          lrs_clear_mp(Ns); lrs_clear_mp(Nt);
+	  return FALSE;		/* non-redundant */
+        }
+
+      pivot (P, Q, i, j);
+      update (P, Q, &i, &j);	/*Update B,C,i,j */
+
+    }
+
+  lrs_clear_mp(Ns); lrs_clear_mp(Nt);
+
+  return !(j < d && i == 0);	/* unbounded is also non-redundant */
+
+
+}				/* end of checkredund  */
+
+long 
+checkcobasic (lrs_dic * P, lrs_dat * Q, long index)
+/* TRUE if index is cobasic and nonredundant                         */
+/* FALSE if basic, or degen. cobasic, where it will get pivoted out  */
+
+{
+
+/* assign local variables to structures */
+
+  lrs_mp_matrix A = P->A;
+  long *B, *C, *Row, *Col;
+  long d = P->d;
+  long m = P->m;
+  long debug = Q->debug;
+  long i = 0;
+  long j = 0;
+  long s;
+
+  B = P->B;
+  C = P->C;
+  Row = P->Row;
+  Col = P->Col;
+
+
+  while ((j < d) && C[j] != index)
+    j++;
+
+  if (j == d)
+    return FALSE;		/* not cobasic index */
+
+
+/* index is cobasic */
+
+  if (debug)
+    fprintf (lrs_ofp, "\nindex=%ld cobasic", index);
+/* not debugged for new LOC 
+   s=LOC[index];
+ */
+  s = Col[j];
+  i = Q->lastdv + 1;
+
+  while ((i <= m) &&
+	 (zero (A[Row[i]][s]) || !zero (A[Row[i]][0])))
+    i++;
+
+  if (i > m)
+    {
+      if (debug)
+	fprintf (lrs_ofp, " is non-redundant");
+      return TRUE;
+    }
+  if (debug)
+    fprintf (lrs_ofp, " is degenerate B[i]=%ld", B[i]);
+
+  pivot (P, Q, i, j);
+  update (P, Q, &i, &j);	/*Update B,C,i,j */
+
+  return FALSE;			/*index is no longer cobasic */
+
+}				/* end of checkcobasic */
+
+long 
+checkindex (lrs_dic * P, lrs_dat * Q, long index)
+/* 0 if index is non-redundant inequality */
+/* 1 if index is redundant     inequality */
+/* 2 if index is input linearity          */
+/*NOTE: row is returned all zero if redundant!! */
+{
+  long i, j;
+
+  lrs_mp_matrix A = P->A;
+  long *Row = P->Row;
+  long *B = P->B;
+  long d = P->d;
+  long m = P->m;
+
+  if (Q->debug)
+    printA (P, Q);
+
+/* each slack index must be checked for redundancy */
+/* if in cobasis, it is pivoted out if degenerate */
+/* else it is non-redundant                       */
+
+  if (checkcobasic (P, Q, index))
+    return ZERO;
+
+/* index is basic   */
+/* not debugged for new LOC 
+   i=LOC[index];
+ */
+  j = 1;
+  while ((j <= m) && (B[j] != index))
+    j++;
+
+  i = Row[j];
+
+  /* copy row i to cost row, and set it to zero */
+
+  for (j = 0; j <= d; j++)
+    {
+      copy (A[0][j], A[i][j]);
+      changesign (A[0][j]);
+      itomp (ZERO, A[i][j]);
+    }
+
+
+  if (checkredund (P, Q))
+    return ONE;
+
+/* non-redundant, copy back and change sign */
+
+  for (j = 0; j <= d; j++)
+    {
+      copy (A[i][j], A[0][j]);
+      changesign (A[i][j]);
+    }
+
+  return ZERO;
+
+}				/* end of checkindex */
+
+/***************************************************************/
+/*                                                             */
+/*            Package of I/O routines                          */
+/*                                                             */
+/***************************************************************/
+
+void
+lprat (const char *name, long Nt, long Dt)
+/*print the long precision rational Nt/Dt without reducing  */
+{
+  if ( Nt > 0 ) 
+    fprintf (lrs_ofp, " ");
+  fprintf (lrs_ofp, "%s%ld", name, Nt);
+  if (Dt != 1)   
+    fprintf (lrs_ofp, "/%ld", Dt);
+  fprintf (lrs_ofp, " ");
+}                               /* lprat */
+
+long
+lreadrat (long *Num, long *Den)
+ /* read a rational string and convert to long    */
+ /* returns true if denominator is not one        */
+{
+  char in[MAXINPUT], num[MAXINPUT], den[MAXINPUT];
+  if(fscanf (lrs_ifp, "%s", in) == EOF)
+     return(FALSE);
+  atoaa (in, num, den);         /*convert rational to num/dem strings */
+  *Num = atol (num);
+  if (den[0] == '\0')
+    {
+      *Den = 1L;
+      return (FALSE);
+    }
+  *Den = atol (den);
+  return (TRUE);
+}
+
+void
+lrs_getinput(lrs_dic *P,lrs_dat *Q,long *num,long *den, long m, long d)
+/* code for reading data matrix in lrs/cdd format */
+{
+  long j,row;
+
+  printf("\nEnter each row: b_i  a_ij j=1..%ld",d);
+  for (row=1;row<=m;row++)
+    {
+      printf("\nEnter row %ld: ",row );
+      for(j=0;j<=d;j++)
+       {
+         lreadrat(&num[j],&den[j]);
+         lprat(" ",num[j],den[j]);
+       }
+
+       lrs_set_row(P,Q,row,num,den,GE);
+     }
+
+ printf("\nEnter objective row c_j j=1..%ld: ",d);
+ num[0]=0; den[0]=1;
+ for(j=1;j<=d;j++)
+       {
+         lreadrat(&num[j],&den[j]);
+         lprat(" ",num[j],den[j]);
+       }
+
+ lrs_set_obj(P,Q,num,den,MAXIMIZE);
+}
+
+
+long 
+readlinearity (lrs_dat * Q)	/* read in and check linearity list */
+{
+  long i, j;
+  long nlinearity;
+  if(fscanf (lrs_ifp, "%ld", &nlinearity)==EOF )
+    {
+      fprintf (lrs_ofp, "\nLinearity option invalid, no indices ");
+      return (FALSE);
+    } 
+  if (nlinearity < 1)
+    {
+      fprintf (lrs_ofp, "\nLinearity option invalid, indices must be positive");
+      return (FALSE);
+    } 
+
+  Q->linearity  = CALLOC ((nlinearity + 1), sizeof (long));
+
+  for (i = 0; i < nlinearity; i++)
+    {
+      if(fscanf (lrs_ifp, "%ld", &j)==EOF)
+      {
+      fprintf (lrs_ofp, "\nLinearity option invalid, missing indices");
+      return (FALSE);
+      } 
+      Q->linearity[i] = j;	
+
+    }
+  for (i = 1; i < nlinearity; i++)	/*sort in order */
+    reorder (Q->linearity, nlinearity);
+
+  Q->nlinearity = nlinearity;
+  Q->polytope = FALSE;
+  return TRUE;
+}				/* end readlinearity */
+
+
+long 
+readfacets (lrs_dat * Q, long facet[])
+/* read and check facet list for obvious errors during start/restart */
+/* this must be done after linearity option is processed!! */
+{
+  long i, j;
+/* assign local variables to structures */
+  long m, d;
+  long *linearity = Q->linearity;
+  m = Q->m;
+  d = Q->inputd;
+
+  for (j = Q->nlinearity; j < d; j++)	/* note we place these after the linearity indices */
+    {
+      if(fscanf (lrs_ifp, "%ld", &facet[j])==EOF)
+        {
+      fprintf (lrs_ofp, "\nrestart: facet list missing indices");                 
+      return (FALSE);
+      }
+
+
+      fprintf (lrs_ofp, " %ld", facet[j]);
+/* 2010.4.26 nonnegative option needs larger range of indices */
+      if(Q->nonnegative)
+         if (facet[j] < 1 || facet[j] > m+d)
+	  {
+	  fprintf (lrs_ofp, "\n Start/Restart cobasic indices must be in range 1 .. %ld ", m+d);
+	  return FALSE;
+	  }
+      if(!Q->nonnegative)
+         if (facet[j] < 1 || facet[j] > m)
+	  {
+	  fprintf (lrs_ofp, "\n Start/Restart cobasic indices must be in range 1 .. %ld ", m);
+	  return FALSE;
+	  }
+      for (i = 0; i < Q->nlinearity; i++)
+	if (linearity[i] == facet[j])
+	  {
+	    fprintf (lrs_ofp, "\n Start/Restart cobasic indices should not include linearities");
+	    return FALSE;
+	  }
+/* bug fix 2011.8.1  reported by Steven Wu*/
+      for (i = Q->nlinearity; i < j; i++)
+/* end bug fix 2011.8.1 */
+
+	if (facet[i] == facet[j])
+	  {
+	    fprintf (lrs_ofp, "\n  Start/Restart cobasic indices must be distinct");
+	    return FALSE;
+	  }
+    }
+  return TRUE;
+}				/* end of readfacets */
+
+void 
+printA (lrs_dic * P, lrs_dat * Q)	/* print the integer m by n array A 
+					   with B,C,Row,Col vectors         */
+{
+  long i, j;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *B = P->B;
+  long *C = P->C;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m, d, lastdv;
+  m = P->m;
+  d = P->d;
+  lastdv = Q->lastdv;
+
+  fprintf (lrs_ofp, "\n Basis    ");
+  for (i = 0; i <= m; i++)
+    fprintf (lrs_ofp, "%ld ", B[i]);
+  fprintf (lrs_ofp, " Row ");
+  for (i = 0; i <= m; i++)
+    fprintf (lrs_ofp, "%ld ", Row[i]);
+  fprintf (lrs_ofp, "\n Co-Basis ");
+  for (i = 0; i <= d; i++)
+    fprintf (lrs_ofp, "%ld ", C[i]);
+  fprintf (lrs_ofp, " Column ");
+  for (i = 0; i <= d; i++)
+    fprintf (lrs_ofp, "%ld ", Col[i]);
+  pmp (" det=", P->det);
+  fprintf (lrs_ofp, "\n");
+  i=0;
+  while ( i<= m )
+    {
+      for (j = 0; j <= d; j++)
+	pimat (P, i, j, A[Row[i]][Col[j]], "A");
+      fprintf (lrs_ofp, "\n");
+      if (i==0 && Q->nonnegative)  /* skip basic rows - don't exist! */
+          i=d;
+      i++;
+  fflush (stdout);
+    }
+  fflush (stdout);
+}
+
+
+void 
+pimat (lrs_dic * P, long r, long s, lrs_mp Nt, char name[])
+ /*print the long precision integer in row r col s of matrix A */
+{
+  long *B = P->B;
+  long *C = P->C;
+  if (s == 0)
+    fprintf (lrs_ofp, "%s[%ld][%ld]=", name, B[r], C[s]);
+  else
+    fprintf (lrs_ofp, "[%ld]=", C[s]);
+  pmp ("", Nt);
+
+}
+
+/***************************************************************/
+/*                                                             */
+/*     Routines for caching, allocating etc.                   */
+/*                                                             */
+/***************************************************************/
+
+/* From here mostly Bremner's handiwork */
+
+void 
+cache_dict (lrs_dic ** D_p, lrs_dat * global, long i, long j)
+{
+
+  if (dict_limit > 1)
+    {
+      /* save row, column indicies */
+      (*D_p)->i = i;
+      (*D_p)->j = j;
+
+/* Make a new, blank spot at the end of the queue to copy into */ 
+
+      pushQ (global, (*D_p)->m, (*D_p)->d, (*D_p)->m_A);
+
+      copy_dict (global, global->Qtail, *D_p);	/* Copy current dictionary */
+    }
+  *D_p = global->Qtail;
+
+}
+
+void 
+copy_dict (lrs_dat * global, lrs_dic * dest, lrs_dic * src)
+{
+  long m = src->m;
+  long m_A = src->m_A;        /* number of rows in A */
+  long d = src->d;
+  long r,s;
+
+#ifdef GMP 
+  for ( r=0;r<=m_A;r++)
+    for( s=0;s<=d;s++)
+       copy(dest->A[r][s],src->A[r][s]);
+
+#else            /* fast copy for MP and LONG arithmetic */
+  /* Note that the "A" pointer trees need not be copied, since they
+     always point to the same places within the corresponding space
+*/
+/* I wish I understood the above remark. For the time being, do it the easy way for Nash */
+  if(global->nash)
+  {
+  for ( r=0;r<=m_A;r++)
+    for( s=0;s<=d;s++)
+       copy(dest->A[r][s],src->A[r][s]);
+  }
+  else
+  memcpy (dest->A[0][0], (global->Qtail->prev)->A[0][0],
+          (d + 1) * (lrs_digits + 1) * (m_A + 1) * sizeof (long));
+
+#endif
+
+  dest->i = src->i;
+  dest->j = src->j;
+  dest->m = m;
+  dest->d = d;
+  dest->m_A  = src->m_A;
+
+  dest->depth = src->depth;
+  dest->lexflag = src->lexflag;
+
+  copy (dest->det, src->det);
+  copy (dest->objnum, src->objnum);
+  copy (dest->objden, src->objden);
+
+  if (global->debug)
+    fprintf (lrs_ofp, "\nSaving dict at depth %ld\n", src->depth);
+
+  memcpy (dest->B, src->B, (m + 1) * sizeof (long));
+  memcpy (dest->C, src->C, (d + 1) * sizeof (long));
+  memcpy (dest->Row, src->Row, (m + 1) * sizeof (long));
+  memcpy (dest->Col, src->Col, (d + 1) * sizeof (long));
+}
+
+/* 
+ * pushQ(lrs_dat *globals,m,d):
+ * this routine ensures that Qtail points to a record that 
+ * may be copied into.
+ *
+ * It may create a new record, or it may just move the head pointer
+ * forward so that know that the old record has been overwritten.
+ */
+#if 0
+#define TRACE(s) fprintf(stderr,"\n%s %p %p\n",s,global->Qhead,global->Qtail);
+#else
+#define TRACE(s)
+#endif
+
+void 
+pushQ (lrs_dat * global, long m, long d ,long m_A)
+{
+
+  if ((global->Qtail->next) == global->Qhead)
+    {
+      /* the Queue is full */
+      if (dict_count < dict_limit)
+	{
+	  /* but we are allowed to create more */
+	  lrs_dic *p;
+
+	  p = new_lrs_dic (m, d, m_A);
+
+	  if (p)
+	    {
+
+	      /* we successfully created another record */
+
+	      p->next = global->Qtail->next;
+	      (global->Qtail->next)->prev = p;
+	      (global->Qtail->next) = p;
+	      p->prev = global->Qtail;
+
+	      dict_count++;
+	      global->Qtail = p;
+
+	      TRACE ("Added new record to Q");
+
+	    }
+	  else
+	    {
+	      /* virtual memory exhausted. bummer */
+	      global->Qhead = global->Qhead->next;
+	      global->Qtail = global->Qtail->next;
+
+	      TRACE ("VM exhausted");
+	    }
+	}
+      else
+	{
+	  /*
+	   * user defined limit reached. start overwriting the
+	   * beginning of Q 
+	   */
+	  global->Qhead = global->Qhead->next;
+	  global->Qtail = global->Qtail->next;
+	  TRACE ("User  limit");
+
+	}
+    }
+
+  else
+    {
+      global->Qtail = global->Qtail->next;
+      TRACE ("Reusing");
+    }
+}
+
+lrs_dic *
+lrs_getdic(lrs_dat *Q)
+/* create another dictionary for Q without copying any values */
+/* derived from lrs_alloc_dic,  used by nash.c                */
+{
+lrs_dic *p;
+
+  long m;
+
+  m = Q->m;
+
+/* nonnegative flag set means that problem is d rows "bigger"     */
+/* since nonnegative constraints are not kept explicitly          */
+
+
+  if(Q->nonnegative)
+    m = m+Q->inputd;
+
+  p = new_lrs_dic (m, Q->inputd, Q->m);
+  if (!p)
+    return NULL;
+
+  p->next = p;
+  p->prev = p;
+  Q->Qhead = p;
+  Q->Qtail = p;
+
+  return p;
+}
+
+
+#define NULLRETURN(e) if (!(e)) return NULL;
+
+lrs_dic *
+new_lrs_dic (long m, long d, long m_A)
+{
+  lrs_dic *p;
+
+  NULLRETURN (p = (lrs_dic *) malloc (sizeof (lrs_dic)));
+
+
+  NULLRETURN (p->B = calloc ((m + 1), sizeof (long)));
+  NULLRETURN (p->Row = calloc ((m + 1), sizeof (long)));
+
+  NULLRETURN (p->C = calloc ((d + 1), sizeof (long)));
+  NULLRETURN (p->Col = calloc ((d + 1), sizeof (long)));
+
+#ifdef GMP
+  lrs_alloc_mp(p->det);
+  lrs_alloc_mp(p->objnum);
+  lrs_alloc_mp(p->objden);
+#endif
+
+  p->d_orig=d;
+
+  p->A=lrs_alloc_mp_matrix(m_A,d);
+
+
+  return p;
+}
+
+void 
+lrs_free_dic (lrs_dic * P, lrs_dat *Q)
+{
+/* do the same steps as for allocation, but backwards */
+/* gmp variables cannot be cleared using free: use lrs_clear_mp* */
+  lrs_dic *P1;
+
+/* repeat until cache is empty */
+
+  do
+  {
+    /* I moved these here because I'm not certain the cached dictionaries
+       need to be the same size. Well, it doesn't cost anything to be safe. db */
+
+  long d = P->d_orig;
+  long m_A = P->m_A;
+
+  lrs_clear_mp_matrix (P->A,m_A,d);
+
+/* "it is a ghastly error to free something not assigned my malloc" KR167 */
+/* so don't try: free (P->det);                                           */
+
+  lrs_clear_mp (P->det);      
+  lrs_clear_mp (P->objnum);      
+  lrs_clear_mp (P->objden);      
+
+  free (P->Row);
+  free (P->Col);
+  free (P->C);
+  free (P->B);
+
+/* go to next record in cache if any */
+  P1 =P->next;
+  free (P);
+  P=P1;
+
+  }  while (Q->Qhead != P );
+
+
+}
+
+void
+lrs_free_dat ( lrs_dat *Q )
+{
+   long m=Q->m;
+
+/* most of these items were allocated in lrs_alloc_dic */
+
+  lrs_clear_mp_vector (Q->Gcd,m);
+  lrs_clear_mp_vector (Q->Lcm,m);
+
+  lrs_clear_mp (Q->sumdet);
+  lrs_clear_mp (Q->Nvolume);
+  lrs_clear_mp (Q->Dvolume);
+  lrs_clear_mp (Q->saved_det);
+  lrs_clear_mp (Q->boundd);
+  lrs_clear_mp (Q->boundn);
+
+  free (Q->inequality);
+  free (Q->facet);
+  free (Q->redundcol);
+  free (Q->linearity);
+  free (Q->minratio);
+  free (Q->temparray);
+
+  free (Q->name);  
+  free (Q->saved_C);
+
+  lrs_global_count--;
+
+  free(Q);
+}
+
+
+long 
+check_cache (lrs_dic ** D_p, lrs_dat * global, long *i_p, long *j_p)
+{
+/* assign local variables to structures */
+
+
+
+  cache_tries++;
+
+  if (global->Qtail == global->Qhead)
+    {
+      TRACE ("cache miss");
+      /* Q has only one element */
+      cache_misses++;
+      return 0;
+
+    }
+  else
+    {
+      global->Qtail = global->Qtail->prev;
+
+      *D_p = global->Qtail;
+
+      *i_p = global->Qtail->i;
+      *j_p = global->Qtail->j;
+
+      TRACE ("restoring dict");
+      return 1;
+    }
+}
+
+
+lrs_dic *
+lrs_alloc_dic (lrs_dat * Q)
+/* allocate and initialize lrs_dic */
+{
+
+  lrs_dic *p;
+  long i, j;
+  long m, d, m_A;
+
+  if (Q->hull)                       /* d=col dimension of A */
+    Q->inputd = Q->n;                /* extra column for hull */
+  else
+    Q->inputd = Q->n - 1;
+
+  m = Q->m;
+  d = Q->inputd;
+  m_A = m;   /* number of rows in A */
+
+/* nonnegative flag set means that problem is d rows "bigger"     */
+/* since nonnegative constraints are not kept explicitly          */
+
+  if(Q->nonnegative)
+    m = m+d;
+
+  p = new_lrs_dic (m, d, m_A);
+  if (!p)
+    return NULL;
+
+  p->next = p;
+  p->prev = p;
+  Q->Qhead = p;
+  Q->Qtail = p;
+
+
+  dict_count = 1;
+  dict_limit = 10;
+  cache_tries = 0;
+  cache_misses = 0;
+
+/* Initializations */
+
+  p->d = p->d_orig = d;
+  p->m = m;
+  p->m_A  = m_A;
+  p->depth = 0L;
+  p->lexflag = TRUE;
+  itomp (ONE, p->det);
+  itomp (ZERO, p->objnum);
+  itomp (ONE, p->objden);
+
+/*m+d+1 is the number of variables, labelled 0,1,2,...,m+d  */
+/*  initialize array to zero   */
+  for (i = 0; i <= m_A; i++)
+    for (j = 0; j <= d; j++)
+      itomp (ZERO, p->A[i][j]);
+
+  Q->inequality = CALLOC ((m + 1), sizeof (long));
+  if (Q->nlinearity == ZERO)   /* linearity may already be allocated */
+      Q->linearity  = CALLOC ((m + 1), sizeof (long));
+
+  Q->facet = (long *) CALLOC ((unsigned) d + 1, sizeof (long));
+  Q->redundcol = CALLOC ((d + 1), sizeof (long));
+  Q->minratio = CALLOC ((m + 1), sizeof (long));
+                         /*  2011.7.14  minratio[m]=0 for degen =1 for nondegen pivot*/
+  Q->temparray = CALLOC ((unsigned) d + 1, sizeof (long));
+
+  Q->inequality[0] = 2L;
+  Q->Gcd = lrs_alloc_mp_vector(m);
+  Q->Lcm = lrs_alloc_mp_vector(m);
+  Q->saved_C = CALLOC (d + 1, sizeof (long));
+
+  Q->lastdv = d;      /* last decision variable may be decreased */
+                      /* if there are redundant columns          */
+
+/*initialize basis and co-basis indices, and row col locations */
+/*if nonnegative, we label differently to avoid initial pivots */
+/* set basic indices and rows */
+ if(Q->nonnegative)
+  for (i = 0; i <= m; i++)
+    {
+      p->B[i] = i;
+      if (i <= d )
+          p->Row[i]=0; /* no row for decision variables */
+      else 
+          p->Row[i]=i-d;
+    }
+ else
+   for (i = 0; i <= m; i++)
+    {
+      if (i == 0 )
+          p->B[0]=0;
+      else
+          p->B[i] = d + i;
+      p->Row[i] = i;
+    }
+
+  for (j = 0; j < d; j++)
+    {
+      if(Q->nonnegative)
+          p->C[j] = m+j+1;
+      else
+          p->C[j] = j + 1;
+      p->Col[j] = j + 1;
+    }
+  p->C[d] = m + d + 1;
+  p->Col[d] = 0;
+  return p;
+}				/* end of lrs_alloc_dic */
+
+
+/* 
+   this routine makes a copy of the information needed to restart, 
+   so that we can guarantee that if a signal is received, we 
+   can guarantee that nobody is messing with it.
+   This as opposed to adding all kinds of critical regions in 
+   the main line code.
+
+   It is also used to make sure that in case of overflow, we
+   have a valid cobasis to restart from.
+ */
+void 
+save_basis (lrs_dic * P, lrs_dat * Q)
+{
+  int i;
+/* assign local variables to structures */
+  long *C = P->C;
+  long d;
+
+#ifdef SIGNALS
+  sigset_t oset, blockset;
+  sigemptyset (&blockset);
+  sigaddset (&blockset, SIGTERM);
+  sigaddset (&blockset, SIGHUP);
+  sigaddset (&blockset, SIGUSR1);
+
+  errcheck ("sigprocmask", sigprocmask (SIG_BLOCK, &blockset, &oset));
+#endif
+  d = P->d;
+
+  Q->saved_flag = 1;
+
+  for (i = 0; i < 3; i++)
+    Q->saved_count[i] = Q->count[i];
+
+  for (i = 0; i < d + 1; i++)
+    Q->saved_C[i] = C[i];
+
+  copy (Q->saved_det, P->det);
+
+  Q->saved_d = P->d;
+  Q->saved_depth = P->depth;
+
+#ifdef SIGNALS
+  errcheck ("sigprocmask", sigprocmask (SIG_SETMASK, &oset, 0));
+#endif
+}
+
+/* digits overflow is a call from lrs_mp package */
+
+void 
+digits_overflow ()
+{
+  fprintf (lrs_ofp, "\nOverflow at digits=%ld", DIG2DEC (lrs_digits));
+  fprintf (lrs_ofp, "\nRerun with option: digits n, where n > %ld\n", DIG2DEC (lrs_digits));
+  lrs_dump_state ();
+
+  notimpl("");
+}
+
+static void 
+lrs_dump_state ()
+{
+  long i;
+
+  fprintf (stderr, "\n\nlrs_lib: checkpointing:\n");
+
+  fprintf (stderr, "lrs_lib: Current digits at %ld out of %ld\n",
+	   DIG2DEC (lrs_record_digits),
+	   DIG2DEC (lrs_digits));
+
+  for (i = 0; i < lrs_global_count; i++)
+    {
+      print_basis (stderr, lrs_global_list[i]);
+    }
+  fprintf (stderr, "lrs_lib: checkpoint finished\n");
+}
+
+
+/* print out the saved copy of the basis */
+void 
+print_basis (FILE * fp, lrs_dat * global)
+{
+  int i;
+/* assign local variables to structures */
+  fprintf (fp, "lrs_lib: State #%ld: (%s)\t", global->id, global->name);
+
+  if (global->saved_flag)
+    {
+
+      fprintf (fp, "V#%ld R#%ld B#%ld h=%ld facets ",
+	       global->saved_count[1],
+	       global->saved_count[0],
+	       global->saved_count[2],
+	       global->saved_depth);
+      for (i = 0; i < global->saved_d; i++)
+	fprintf (fp, "%ld ",
+		 global->inequality[global->saved_C[i] - global->lastdv]);
+      pmp (" det=", global->saved_det);
+      fprintf (fp, "\n");
+
+    }
+  else
+    {
+      fprintf (fp, "lrs_lib: Computing initial basis\n");
+    }
+
+
+  fflush (fp);
+}
+
+#ifdef SIGNALS
+
+/*
+   If given a signal
+   USR1            print current cobasis and continue
+   TERM            print current cobasis and terminate
+   INT (ctrl-C) ditto
+   HUP                     ditto
+ */
+void 
+setup_signals ()
+{
+  errcheck ("signal", signal (SIGTERM, die_gracefully));
+  errcheck ("signal", signal (SIGALRM, timecheck));
+  errcheck ("signal", signal (SIGHUP, die_gracefully));
+  errcheck ("signal", signal (SIGINT, die_gracefully));
+  errcheck ("signal", signal (SIGUSR1, checkpoint));
+}
+
+void 
+timecheck ()
+{
+  lrs_dump_state ();
+  errcheck ("signal", signal (SIGALRM, timecheck));
+  alarm (lrs_checkpoint_seconds);
+}
+
+void 
+checkpoint ()
+{
+  lrs_dump_state ();
+  errcheck ("signal", signal (SIGUSR1, checkpoint));
+}
+
+void 
+die_gracefully ()
+{
+  lrs_dump_state ();
+
+  exit (1);
+}
+
+#endif
+
+#ifdef TIMES
+/* 
+ * Not sure about the portability of this yet, 
+ *              - db
+ */
+#include <sys/resource.h>
+#define double_time(t) ((double)(t.tv_sec)+(double)(t.tv_usec)/1000000)
+
+void 
+ptimes ()
+{
+  struct rusage rusage;
+  getrusage (RUSAGE_SELF, &rusage);
+  fprintf (lrs_ofp, "\n*%0.3fu %0.3fs %ldKb %ld flts %ld swaps %ld blks-in %ld blks-out \n",
+	   double_time (rusage.ru_utime),
+	   double_time (rusage.ru_stime),
+	   rusage.ru_maxrss, rusage.ru_majflt, rusage.ru_nswap,
+	   rusage.ru_inblock, rusage.ru_oublock);
+
+}
+
+double get_time()
+{
+  struct rusage rusage;
+  getrusage (RUSAGE_SELF, &rusage);
+  return   ( double_time (rusage.ru_utime));
+
+}
+
+#endif
+
+/* Routines based on lp_solve */
+
+void
+lrs_set_row(lrs_dic *P, lrs_dat *Q, long row, long num[], long den[], long ineq)
+/* convert to lrs_mp then call lrs_set_row */
+{
+ lrs_mp_vector Num, Den;
+ long m,d;
+ long j;
+ 
+  m = P->m;
+  d = P->d;
+
+  Num=lrs_alloc_mp_vector(d+1);
+  Den=lrs_alloc_mp_vector(d+1);
+
+  for (j=0;j<=d;j++)
+  {
+  itomp(num[j],Num[j]);
+  itomp(den[j],Den[j]);
+  }
+ 
+  lrs_set_row_mp(P,Q,row,Num,Den,ineq);
+
+  lrs_clear_mp_vector(Num,d+1);
+  lrs_clear_mp_vector(Den,d+1);
+
+}
+
+void
+lrs_set_row_mp(lrs_dic *P, lrs_dat *Q, long row, lrs_mp_vector num, lrs_mp_vector den, long ineq)
+/* set row of dictionary using num and den arrays for rational input */
+/* ineq = 1 (GE)   - ordinary row  */
+/*      = 0 (EQ)   - linearity     */
+{
+  lrs_mp Temp, mpone;
+  lrs_mp_vector oD;             /* denominator for row  */
+
+  long i, j;
+
+/* assign local variables to structures */
+
+  lrs_mp_matrix A;
+  lrs_mp_vector Gcd, Lcm;
+  long hull;
+  long m, d;
+  lrs_alloc_mp(Temp); lrs_alloc_mp(mpone);
+  hull = Q->hull;
+  A = P->A;
+  m = P->m;
+  d = P->d;
+  Gcd = Q->Gcd;
+  Lcm = Q->Lcm;
+
+  oD = lrs_alloc_mp_vector (d);
+  itomp (ONE, mpone);
+  itomp (ONE, oD[0]);
+
+  i=row;
+  itomp (ONE, Lcm[i]);      /* Lcm of denominators */
+  itomp (ZERO, Gcd[i]);     /* Gcd of numerators */
+  for (j = hull; j <= d; j++)       /* hull data copied to cols 1..d */
+        {
+          copy( A[i][j],num[j-hull]);
+          copy(oD[j],den[j-hull]);
+          if (!one(oD[j]))
+            lcm (Lcm[i], oD[j]);      /* update lcm of denominators */
+          copy (Temp, A[i][j]);
+          gcd (Gcd[i], Temp);   /* update gcd of numerators   */
+        }
+
+  if (hull)
+        {
+          itomp (ZERO, A[i][0]);        /*for hull, we have to append an extra column of zeroes */
+          if (!one (A[i][1]) || !one (oD[1]))         /* all rows must have a one in column one */
+            Q->polytope = FALSE;
+        }
+  if (!zero (A[i][hull]))   /* for H-rep, are zero in column 0     */
+        Q->homogeneous = FALSE; /* for V-rep, all zero in column 1     */
+
+  storesign (Gcd[i], POS);
+  storesign (Lcm[i], POS);
+  if (greater (Gcd[i], mpone) || greater (Lcm[i], mpone))
+        for (j = 0; j <= d; j++)
+          {
+            exactdivint (A[i][j], Gcd[i], Temp);        /*reduce numerators by Gcd  */
+            mulint (Lcm[i], Temp, Temp);        /*remove denominators */
+            exactdivint (Temp, oD[j], A[i][j]);       /*reduce by former denominator */
+          }
+
+  if ( ineq == EQ )        /* input is linearity */
+     {
+      Q->linearity[Q->nlinearity]=row;
+      Q->nlinearity++;
+     }
+
+/* 2010.4.26   Set Gcd and Lcm for the non-existant rows when nonnegative set */
+
+
+  if(Q->nonnegative && row==m)
+      for(j=1;j<=d;j++)
+         { itomp (ONE, Lcm[m+j]);
+           itomp (ONE, Gcd[m+j]);
+         }
+
+
+  lrs_clear_mp_vector (oD,d);
+  lrs_clear_mp(Temp); lrs_clear_mp(mpone);
+}          /* end of lrs_set_row_mp */
+
+void 
+lrs_set_obj(lrs_dic *P, lrs_dat *Q, long num[], long den[], long max)
+{
+  long i;
+
+  if (max == MAXIMIZE)
+       Q->maximize=TRUE;
+  else
+       {
+       Q->minimize=TRUE;
+       for(i=0;i<=P->d;i++)
+         num[i]=-num[i];
+       }
+
+  lrs_set_row(P,Q,0L,num,den,GE);
+}
+
+void
+lrs_set_obj_mp(lrs_dic *P, lrs_dat *Q, lrs_mp_vector num, lrs_mp_vector den, long max)
+{
+  long i;
+
+  if (max == MAXIMIZE)
+       Q->maximize=TRUE;
+  else
+       {
+       Q->minimize=TRUE;
+       for(i=0;i<=P->d;i++)
+         changesign(num[i]);
+       }
+
+  lrs_set_row_mp(P,Q,0L,num,den,GE);
+}
+
+
+long
+lrs_solve_lp(lrs_dic *P, lrs_dat *Q)
+/* user callable function to solve lp only */
+{
+  lrs_mp_matrix Lin;		/* holds input linearities if any are found             */
+  long col;
+
+  Q->lponly = TRUE;
+
+  if (!lrs_getfirstbasis (&P, Q, &Lin, FALSE))
+    return FALSE;
+
+/* There may have been column redundancy                */
+/* If so the linearity space is obtained and redundant  */
+/* columns are removed. User can access linearity space */
+/* from lrs_mp_matrix Lin dimensions nredundcol x d+1   */
+
+  for (col = 0; col < Q->nredundcol; col++)	/* print linearity space               */
+    lrs_printoutput (Q, Lin[col]);   	        /* Array Lin[][] holds the coeffs.     */
+
+  return TRUE;
+} /* end of lrs_solve_lp */
+
+
+long 
+dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s)
+/* select pivot indices using dantzig simplex method             */
+/* largest coefficient with lexicographic rule to avoid cycling  */
+/* Bohdan Kaluzny's handiwork                                    */
+/* returns TRUE if pivot found else FALSE                        */
+/* pivot variables are B[*r] C[*s] in locations Row[*r] Col[*s]  */
+{
+  long j,k,col;
+  lrs_mp coeff;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *Col = P->Col;
+  long d = P->d;
+
+  lrs_alloc_mp (coeff);
+  *r = 0;
+  *s = d;
+  j = 0;
+  k = 0;
+ 
+  itomp(0,coeff);
+/*find positive cost coef */
+  while (k < d) 
+     {
+       if(greater(A[0][Col[k]],coeff))
+        {
+          j = k;
+          copy(coeff,A[0][Col[j]]);
+	}
+      k++;
+     }
+
+  if (positive(coeff))			/* pivot column found! */
+    {
+      *s = j;
+      col = Col[j];
+
+      /*find min index ratio */
+      *r = ratio (P, Q, col);
+      if (*r != 0)
+        {
+        lrs_clear_mp(coeff);
+	return (TRUE);		/* unbounded */
+        }
+    }
+  lrs_clear_mp(coeff);
+  return (FALSE);
+}				/* end of dan_selectpivot        */
+
+
+long
+phaseone (lrs_dic * P, lrs_dat * Q)
+/* Do a dual pivot to get primal feasibility (pivot in X_0)*/
+/* Bohdan Kaluzny's handiwork                                    */
+{
+  long i, j, k;
+/* assign local variables to structures */
+  lrs_mp_matrix A = P->A;
+  long *Row = P->Row;
+  long *Col = P->Col;
+  long m, d;
+  lrs_mp b_vector;
+  lrs_alloc_mp (b_vector);
+  m = P->m;
+  d = P->d;
+  i = 0;
+  k = d+1;
+
+  itomp(0,b_vector);
+
+  fprintf (lrs_ofp, "\nLP: Phase One: Dual pivot on artificial variable");
+
+/*find most negative b vector */
+  while (k <= m)
+     {
+       if(greater(b_vector,A[Row[k]][0]))
+        {
+          i = k;
+          copy(b_vector,A[Row[i]][0]);
+        }
+      k++;
+     }
+
+  if (negative(b_vector))                       /* pivot row found! */
+    {
+      j = 0;            /*find a positive entry for in row */
+      while (j < d && !positive (A[Row[i]][Col[j]]))
+        j++;
+      if (j >= d)
+        {
+          lrs_clear_mp (b_vector);
+          return (FALSE);       /* no positive entry */
+        }
+      pivot (P, Q, i, j);
+      update (P, Q, &i, &j);
+    }
+  lrs_clear_mp (b_vector);
+  return (TRUE);
+}
+
+
+long
+lrs_set_digits(long dec_digits)
+{
+/* convert user specified decimal digits to mp digits */
+
+  fprintf (lrs_ofp, "\n*digits %ld", dec_digits);
+  if (dec_digits > 0)
+    lrs_digits = DEC2DIG (dec_digits);
+  if (lrs_digits > MAX_DIGITS)
+    {
+      fprintf (lrs_ofp, "\nDigits must be at most %ld\nChange MAX_DIGITS and recompile",
+	       DIG2DEC (MAX_DIGITS));
+      fflush(stdout);
+      return (FALSE);
+    }
+  return (TRUE);
+}
+
+long
+lrs_checkbound(lrs_dic *P, lrs_dat *Q)
+{
+/* check bound on objective and return TRUE if exceeded */
+
+  if(!Q->bound)
+     return FALSE;
+
+  if( Q->maximize && comprod(Q->boundn,P->objden,P->objnum,Q->boundd) == 1 )
+       {
+        if(Q->verbose)
+             {
+              prat(" \nObj value: ",P->objnum,P->objden);
+              fprintf(lrs_ofp," Pruning ");
+              }
+         return TRUE;
+       }
+  if( Q->minimize && comprod(Q->boundn,P->objden,P->objnum,Q->boundd) == -1 )
+       {
+        if(Q->verbose)
+             {
+              prat(" \nObj value: ",P->objnum,P->objden);
+              fprintf(lrs_ofp," Pruning ");
+              }
+         return TRUE;
+       }
+  return FALSE;
+}
+
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.h
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.h	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrslib.h	(revision 10198)
@@ -0,0 +1,368 @@
+/* lrslib.h (vertex enumeration using lexicographic reverse search) */
+
+#define TITLE "lrslib "
+#define VERSION "v.4.3 2012.6.1"
+#define AUTHOR "\n*Copyright (C) 1995,2011, David Avis   avis@cs.mcgill.ca "
+
+/* This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*Ver 4.2*  library version                                      */
+/******************************************************************************/
+/*  See http://cgm.cs.mcgill.ca/~avis/C/lrs.html for usage instructions         */
+/******************************************************************************/
+/*  Selection of arithmetic package  */
+/*************************************/
+#ifdef LONG
+#define ARITH "lrslong.h"    /* lrs long integer arithmetic package */
+#else
+#ifdef GMP
+#define ARITH "lrsgmp.h"     /* lrs wrapper for gmp multiple precsion arithmetic    */
+#else
+#define ARITH "lrsmp.h"      /* lrs multiple precsion arithmetic    */
+#define MP
+#endif
+#endif
+
+#include ARITH
+
+#ifdef SIGNALS
+#include <signal.h>
+#include <unistd.h>
+#define errcheck(s,e) if ((long)(e)==-1L){  perror(s);exit(1);}
+#endif
+
+#ifdef TIMES
+void ptimes ();
+double get_time();
+#endif
+
+
+#define CALLOC(n,s) xcalloc(n,s,__LINE__,__FILE__)
+
+/* make this include file includable in a C++ file
+   Note that lrsgmp.h should not be inside an extern "C" {} block
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*************/
+/* typedefs  */
+/*************/
+
+
+/******************************************************************************/
+/*                   Indexing after initialization                            */
+/*               Basis                                    Cobasis             */
+/*   ---------------------------------------    ----------------------------- */
+/*  |  i  |0|1| .... |lastdv|lastdv+1|...|m|   | j  | 0 | 1 | ... |d-1|  d  | */
+/*  |-----|+|+|++++++|++++++|--------|---|-|   |----|---|---|-----|---|+++++| */
+/*  |B[i] |0|1| .... |lastdv|lastdv+1|...|m|   |C[j]|m+1|m+2| ... |m+d|m+d+1| */
+/*   -----|+|+|++++++|++++++|????????|???|?|    ----|???|???|-----|???|+++++| */
+/*                                                                            */
+/* Row[i] is row location for B[i]         Col[j] is column location for C[j] */
+/*  -----------------------------              -----------------------------  */
+/* |   i   |0|1| ..........|m-1|m|            | j    | 0 | 1 | ... |d-1| d  | */
+/* |-------|+|-|-----------|---|-|            |------|---|---|---  |---|++++| */
+/* |Row[i] |0|1|...........|m-1|m|            |Col[j]| 1 | 2 | ... | d |  0 | */
+/* --------|+|*|***********|***|*|             ------|***|***|*****|***|++++| */
+/*                                                                            */
+/*  + = remains invariant   * = indices may be permuted ? = swapped by pivot  */
+/*                                                                            */
+/*  m = number of input rows   n= number of input columns                     */
+/*  input dimension inputd = n-1 (H-rep) or n (V-rep)                         */
+/*  lastdv = inputd-nredundcol  (each redundant column removes a dec. var)    */
+/*  working dimension d=lastdv-nlinearity (an input linearity removes a slack) */
+/*  obj function in row 0, index 0=B[0]  col 0 has index m+d+1=C[d]           */
+/*  H-rep: b-vector in col 0, A matrix in columns 1..n-1                      */
+/*  V-rep: col 0 all zero, b-vector in col 1, A matrix in columns 1..n        */
+/******************************************************************************/
+
+typedef struct lrs_dic_struct	/* dynamic dictionary data */
+  {
+    lrs_mp_matrix A;
+    long m;			/* A has m+1 rows, row 0 is cost row            */
+    long m_A;           	/* =m or m-d if nonnegative flag set            */
+    long d;			/* A has d+1 columns, col 0 is b-vector         */
+    long d_orig;		/* value of d as A was allocated  (E.G.)        */
+    long lexflag;		/* true if lexmin basis for this vertex         */
+    long depth;			/* depth of basis/vertex in reverse search tree */
+    long i, j;			/* last pivot row and column pivot indices      */
+    lrs_mp det;                 /* current determinant of basis                 */
+    lrs_mp objnum;		/* objective numerator value                    */
+    lrs_mp objden;		/* objective denominator value                  */
+    long *B, *Row;		/* basis, row location indices                  */
+    long *C, *Col;		/* cobasis, column location indices             */
+    struct lrs_dic_struct *prev, *next;
+  }
+lrs_dic;
+
+typedef struct lrs_dat		/* global problem data   */
+  {
+    lrs_mp_vector Gcd;		/* Gcd of each row of numerators               */
+    lrs_mp_vector Lcm;		/* Lcm for each row of input denominators      */
+
+    lrs_mp sumdet;		/* sum of determinants                          */
+    lrs_mp Nvolume;		/* volume numerator                             */
+    lrs_mp Dvolume;		/* volume denominator                           */
+    lrs_mp boundn;		/* objective bound numerator                    */
+    lrs_mp boundd;		/* objective bound denominator                  */
+    long unbounded;		/* lp unbounded */
+    char fname[100];		/* input file name from line 1 of input         */
+
+    long *inequality;		/* indices of inequalities corr. to cobasic ind */
+    /* initially holds order used to find starting  */
+    /* basis, default: m,m-1,...,2,1                */
+    long *facet;		/* cobasic indices for restart in needed        */
+    long *redundcol;		/* holds columns which are redundant            */
+    long *linearity;		/* holds cobasic indices of input linearities   */
+    long *minratio;		/* used for lexicographic ratio test            */
+    long *temparray;		/* for sorting indices, dimensioned to d        */
+    long *isave, *jsave;	/* arrays for estimator, malloc'ed at start     */
+    long inputd;		/* input dimension: n-1 for H-rep, n for V-rep  */
+
+    long m;      		/* number of rows in input file                 */
+    long n;			/* number of columns in input file              */
+    long lastdv;		/* index of last dec. variable after preproc    */
+    /* given by inputd-nredundcol                   */
+    long count[10];		/* count[0]=rays [1]=verts. [2]=base [3]=pivots */
+                                /* count[4]=integer vertices                    */
+    long deepest;		/* max depth ever reached in search             */
+    long nredundcol;		/* number of redundant columns                  */
+    long nlinearity;		/* number of input linearities                  */
+    long totalnodes;		/* count total number of tree nodes evaluated   */
+    long runs;			/* probes for estimate function                 */
+    long seed;			/* seed for random number generator             */
+    double cest[10];		/* ests: 0=rays,1=vert,2=bases,3=vol,4=int vert */
+/**** flags  **********                         */
+    long allbases;		/* TRUE if all bases should be printed          */
+    long bound;                 /* TRUE if upper/lower bound on objective given */
+    long debug;
+    long dualdeg;		/* TRUE if start dictionary is dual degenerate  */
+    long etrace;		/* turn off debug at basis # strace             */
+    long frequency;		/* frequency to print cobasis indices           */
+    long geometric;		/* TRUE if incident vertex prints after each ray */
+    long getvolume;		/* do volume calculation                        */
+    long givenstart;		/* TRUE if a starting cobasis is given          */
+    long homogeneous;		/* TRUE if all entries in column one are zero   */
+    long hull;			/* do convex hull computation if TRUE           */
+    long incidence;             /* print all tight inequalities (vertices/rays) */
+    long lponly;		/* true if only lp solution wanted              */
+    long maxdepth;		/* max depth to search to in treee              */
+    long maximize;		/* flag for LP maximization                     */
+    long maxoutput;     	/* if positive, maximum number of output lines  */
+    long minimize;		/* flag for LP minimization                     */
+    long mindepth;		/* do not backtrack above mindepth              */
+    long nash;                  /* TRUE for computing nash equilibria           */
+    long nonnegative;		/* TRUE if last d constraints are nonnegativity */
+    long polytope;		/* TRUE for facet computation of a polytope     */
+    long printcobasis;		/* TRUE if all cobasis should be printed        */
+    long printslack;		/* TRUE if indices of slack inequal. printed    */
+    long truncate;              /* TRUE: truncate tree when moving from opt vert*/
+    long verbose;               /* FALSE for minimalist output                  */
+    long restart;		/* TRUE if restarting from some cobasis         */
+    long strace;		/* turn on  debug at basis # strace             */
+    long voronoi;		/* compute voronoi vertices by transformation   */
+
+    /* Variables for saving/restoring cobasis,  db */
+
+    long id;			/* numbered sequentially */
+    char *name;			/* passed by user */
+
+    long saved_count[3];	/* How often to print out current cobasis */
+    long *saved_C;
+    lrs_mp saved_det;
+    long saved_depth;
+    long saved_d;
+
+    long saved_flag;		/* There is something in the saved cobasis */
+
+    /* Variables for cacheing dictionaries, db */
+    lrs_dic *Qhead, *Qtail;
+
+  }
+lrs_dat, lrs_dat_p;
+
+/*********************/
+/*global variables   */
+/*********************/
+#define MAX_LRS_GLOBALS 100L
+#define MAXIMIZE 1L         /* maximize the lp  */
+#define MINIMIZE 0L         /* maximize the lp  */
+#define GE 1L               /* constraint is >= */
+#define EQ 0L               /* constraint is linearity */
+
+
+extern FILE *lrs_cfp;			/* output file for checkpoint information       */
+
+extern unsigned long dict_count, dict_limit, cache_tries, cache_misses;
+extern lrs_dic *PBnew;    /* we will save Bob's dictionary in getabasis */
+
+
+/*******************************/
+/* functions  for external use */
+/*******************************/
+long lrs_main (int argc, char *argv[]);    /* lrs driver, argv[1]=input file, [argc-1]=output file */
+long redund_main (int argc, char *argv[]); /* redund driver, argv[1]=input file, [2]=output file */
+
+lrs_dat *lrs_alloc_dat (char *name);	/* allocate for lrs_dat structure "name"       */
+lrs_dic *lrs_alloc_dic (lrs_dat * Q);	/* allocate for lrs_dic structure corr. to Q   */
+
+void lrs_estimate (lrs_dic * P, lrs_dat * Q);	/* get estimates only                          */
+
+long lrs_read_dat (lrs_dat * Q, int argc, char *argv[]);	/* read header and set up lrs_dat               */
+long lrs_read_dic (lrs_dic * P, lrs_dat * Q);	/* read input and set up problem and lrs_dic    */
+
+long lrs_checkbound (lrs_dic *P, lrs_dat * Q);  /* TRUE if current objective value exceeds specified bound */
+
+long lrs_getfirstbasis (lrs_dic ** P_p, lrs_dat * Q, lrs_mp_matrix * Lin,long no_output);
+	  /* gets first basis, FALSE if none,P may get changed if lin. space Lin found */
+          /* no_output is TRUE supresses output headers   */
+
+								   /* P may get changed if lin. space Lin found    */
+void lrs_getinput(lrs_dic *P,lrs_dat *Q,long *num,long *den, long m, long d);
+          /* reads input matrix b A in lrs/cdd format */
+long lrs_getnextbasis (lrs_dic ** dict_p, lrs_dat * Q, long prune);	/* gets next lrs tree basis, FALSE if none      */
+								   /* backtrack if prune is TRUE                   */
+
+long lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col);
+long lrs_getray (lrs_dic * P, lrs_dat * Q, long col, long comment, lrs_mp_vector output);
+long lrs_getvertex (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output);
+
+void lrs_close (char *name);	/* close lrs lib program "name"                 */
+long lrs_init (char *name);	/* initialize lrslib and arithmetic package for prog "name" */
+
+
+void lrs_lpoutput(lrs_dic * P,lrs_dat * Q, lrs_mp_vector output); /* print LP primal and dual solutions */
+void lrs_printcobasis (lrs_dic * P, lrs_dat * Q, long col);	/* print cobasis for column col(verted or ray)  */
+void lrs_printoutput (lrs_dat * Q, lrs_mp_vector output);	/* print output array                           */
+void lrs_printrow (char name[], lrs_dat * Q, lrs_mp_vector output, long rowd);
+								   /*print row of A matrix in output[0..rowd]      */
+void lrs_printsol (lrs_dic * P, lrs_dat * Q, long col, long comment);	/* print out solution from col, comment=        */
+								   /* 0=normal,-1=geometric ray,1..inputd=linearity */
+void lrs_printtotals (lrs_dic * P, lrs_dat * Q);	/* print final totals for lrs                   */
+long lrs_set_digits (long dec_digits );                 /* set lrsmp digits to equiv. of decimal dec_digits */
+long lrs_solvelp (lrs_dic * P, lrs_dat * Q, long maximize);	/* solve primal feas LP:TRUE bounded else FALSE */
+
+
+/*******************************/
+/* functions  for internal use */
+/*******************************/
+/* basic dictionary functions  */
+/*******************************/
+
+long getabasis (lrs_dic * P, lrs_dat * Q, long order[]);	/* Try to find a starting basis                   */
+void getnextoutput (lrs_dic * P, lrs_dat * Q, long i, long col, lrs_mp out);	/* get A[B[i][col] and copy to out */
+long ismin (lrs_dic * P, lrs_dat * Q, long r, long s);	/* test if A[r][s] is a min ratio for col s       */
+long lexmin (lrs_dic * P, lrs_dat * Q, long col);	/* test A to see if current basis is lexmin       */
+void pivot (lrs_dic * P, lrs_dat * Q, long bas, long cob);	/* Qpivot routine for array A                     */
+long primalfeasible (lrs_dic * P, lrs_dat * Q);		/* Do dual pivots to get primal feasibility       */
+long ratio (lrs_dic * P, lrs_dat * Q, long col);	/* find lex min. ratio                            */
+long removecobasicindex (lrs_dic * P, lrs_dat * Q, long k);	/* remove C[k] from problem                       */
+long restartpivots (lrs_dic * P, lrs_dat * Q);	/* restart problem from given cobasis             */
+long reverse (lrs_dic * P, lrs_dat * Q, long *r, long s);	/* TRUE if B[*r] C[s] is a reverse lex-pos pivot  */
+long selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s);	/* select pivot indices using lexicographic rule  */
+long dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s);	/* select pivot indices using dantzig-lex rule    */
+void update (lrs_dic * P, lrs_dat * Q, long *i, long *j);	/* update the B,C, LOC arrays after a pivot       */
+void updatevolume (lrs_dic * P, lrs_dat * Q);	/* rescale determinant and update the volume      */
+
+/*******************************/
+/* other functions using P,Q   */
+/*******************************/
+
+long lrs_degenerate (lrs_dic * P, lrs_dat * Q);		/* TRUE if the dictionary is primal degenerate    */
+
+void print_basis (FILE * fp, lrs_dat * Q);
+void printA (lrs_dic * P, lrs_dat * Q);		/* raw print of dictionary, bases for debugging   */
+void pimat (lrs_dic * P, long r, long s, lrs_mp Nt, char name[]);	/* print the row r col s of A                     */
+
+long readfacets (lrs_dat * Q, long facet[]);	/* read and check facet list                      */
+long readlinearity (lrs_dat * Q);	/* read and check linearity list                  */
+void rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden);	/* rescale determinant to get its volume */
+void rescalevolume (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden);	/* adjust volume for dimension          */
+
+/***************************************************/
+/* Routines for redundancy checking                */
+/***************************************************/
+
+
+long checkredund (lrs_dic * P, lrs_dat * Q);	/* solve primal lp to check redund of obj fun.    */
+							     /* returns TRUE if redundant, else FALSE          */
+
+long checkcobasic (lrs_dic * P, lrs_dat * Q, long index);	/* TRUE if index is cobasic and nondegenerate     */
+					  /* FALSE if basic, or degen. cobasic, where it will get pivoted out  */
+
+long checkindex (lrs_dic * P, lrs_dat * Q, long index);		/* index=0 non-red.,1 red., 2 input linearity     */
+							     /* NOTE: row is returned all zero if redundant!!  */
+
+/***************************************************/
+/* Routines for caching and restoring dictionaries */
+/***************************************************/
+
+void lrs_free_dic ( lrs_dic *P, lrs_dat *Q);
+void lrs_free_dat ( lrs_dat *Q);
+void cache_dict (lrs_dic ** D_p, lrs_dat * global, long i, long j);
+long check_cache (lrs_dic ** D_p, lrs_dat * global, long *i_p, long *j_p);
+void copy_dict (lrs_dat * global, lrs_dic * dest, lrs_dic * src);
+void pushQ (lrs_dat * global, long m, long d, long m_A);
+
+void save_basis (lrs_dic * D, lrs_dat * Q);
+lrs_dic *alloc_memory (lrs_dat * Q);
+lrs_dic * lrs_getdic(lrs_dat *Q);
+lrs_dic *new_lrs_dic (long m, long d, long m_A);
+lrs_dic *resize (lrs_dic * P, lrs_dat * Q);
+
+
+/*******************************/
+/* signals handling            */
+/*******************************/
+
+void checkpoint ();
+void die_gracefully ();
+void setup_signals ();
+void timecheck ();
+
+/*******************************/
+/* utilities                   */
+/*******************************/
+void lprat (const char *name, long Num, long Den);   /* Print Num/Den without reducing  */
+long lreadrat (long *Num, long *Den);   /* read a rational string and convert to long integers            */
+void reorder (long a[], long range);	/* reorder array in increasing order with one misplaced element   */
+void reorder1 (long a[], long b[], long newone, long range);
+			  /* reorder array a in increasing order with misplaced element newone */
+			  /* elements of b go along for the ride */
+
+/***************************/
+/* lp_solve like functions */
+/***************************/
+long lrs_solve_lp(lrs_dic *P, lrs_dat *Q);                 /* solve lp only for given dictionary */
+
+void lrs_set_row(lrs_dic *P, lrs_dat *Q, long row, long num[], long den[], long ineq);
+                                      /* load row i of dictionary from num[]/den[] ineq=GE       */ 
+void lrs_set_row_mp(lrs_dic *P, lrs_dat *Q, long row, lrs_mp_vector num, lrs_mp_vector den, long ineq);
+                                      /* same as lrs_set_row except num/den is lrs_mp type       */
+
+void lrs_set_obj(lrs_dic *P, lrs_dat *Q, long num[], long den[], long max);
+                  /* set up objective function with coeffs num[]/den[] max=MAXIMIZE or MINIMIZE  */
+void lrs_set_obj_mp(lrs_dic *P, lrs_dat *Q, lrs_mp_vector num, lrs_mp_vector den, long max);
+                                              /* same as lrs_set_obj but num/den has lrs_mp type */
+
+
+
+/* end of  lrslib.h (vertex enumeration using lexicographic reverse search) */
+#ifdef __cplusplus
+}
+#endif
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.c
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.c	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.c	(revision 10198)
@@ -0,0 +1,994 @@
+/* lrsmp.c     library code for lrs extended precision arithmetic */
+/* Version 4.0c, August 26, 2009                          */
+/* minor change to check result of fscanf */
+/* Copyright: David Avis 1999, avis@cs.mcgill.ca          */
+
+/* This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/******************************************************************/
+/* digit overflow is caught by digits_overflow at the end of this */
+/* file, make sure it is either user supplied or uncomment        */
+/*  the define below                                              */
+/******************************************************************/
+
+#define digits_overflow() lrs_default_digits_overflow()
+
+#include <stdio.h>
+#include <string.h>
+#include "lrsmp.h"
+
+
+/*********************************************************/
+/* Initialization and allocation procedures - must use!  */
+/******************************************************* */
+
+long 
+lrs_mp_init (long dec_digits, FILE * fpin, FILE * fpout)
+/* max number of decimal digits for the computation */
+{
+/* global variables lrs_ifp and lrs_ofp are file pointers for input and output   */
+
+  lrs_ifp = fpin;
+  lrs_ofp = fpout;
+  lrs_record_digits = 0;
+
+  if (dec_digits <= 0)
+    dec_digits = DEFAULT_DIGITS;
+
+  lrs_digits = DEC2DIG (dec_digits);	/* max permitted no. of digits   */
+
+  if (lrs_digits > MAX_DIGITS)
+    {
+      fprintf (lrs_ofp, "\nDigits must be at most %ld\nChange MAX_DIGITS and recompile\n",
+	       DIG2DEC (MAX_DIGITS));
+      lrs_digits = MAX_DIGITS;
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+lrs_mp_t
+lrs_alloc_mp_t ()
+ /* dynamic allocation of lrs_mp number */
+{
+  lrs_mp_t p;
+  p=(long *)calloc (lrs_digits+1, sizeof (long));
+  return p;
+}
+
+lrs_mp_vector 
+lrs_alloc_mp_vector (long n)
+ /* allocate lrs_mp_vector for n+1 lrs_mp numbers */
+{
+  lrs_mp_vector p;
+  long i;
+
+  p = CALLOC ((n + 1), sizeof (lrs_mp *));
+  for (i = 0; i <= n; i++)
+    p[i] = CALLOC (1, sizeof (lrs_mp));
+
+  return p;
+}
+
+void
+lrs_clear_mp_vector (lrs_mp_vector p, long n)
+/* free space allocated to p */
+{
+  long i;
+  for (i=0; i<=n; i++)
+     free (p[i] );
+  free (p);
+}
+
+lrs_mp_matrix 
+lrs_alloc_mp_matrix (long m, long n)
+/* allocate lrs_mp_matrix for m+1 x n+1 lrs_mp numbers */
+{
+  lrs_mp_matrix a;
+  long *araw;
+  int mp_width, row_width;
+  int i, j;
+
+  mp_width = lrs_digits + 1;
+  row_width = (n + 1) * mp_width;
+
+  araw = calloc ((m + 1) * row_width, sizeof (long));
+  a = calloc ((m + 1), sizeof (lrs_mp_vector));
+
+  for (i = 0; i < m + 1; i++)
+    {
+      a[i] = calloc ((n + 1), sizeof (lrs_mp *));
+
+      for (j = 0; j < n + 1; j++)
+	a[i][j] = (araw + i * row_width + j * mp_width);
+    }
+  return a;
+}
+
+void 
+lrs_clear_mp_matrix (lrs_mp_matrix p, long m, long n)
+/* free space allocated to lrs_mp_matrix p */
+{
+  long i;
+
+/* p[0][0] is araw, the actual matrix storage address */
+
+ free(p[0][0]);
+
+ for (i = 0; i < m + 1; i++)
+      free (p[i]);
+ free(p);
+}
+
+/*********************************************************/
+/* Core library functions - depend on mp implementation  */
+/******************************************************* */
+
+void 
+copy (lrs_mp a, lrs_mp b)	/* assigns a=b  */
+{
+  long i;
+  for (i = 0; i <= length (b); i++)
+    a[i] = b[i];
+}
+
+/********************************************************/
+/* Divide two multiple precision integers (c=a/b).      */
+/* a is destroyed and contains the remainder on return. */
+/* From Knuth Vol.2 SemiNumerical Algorithms            */
+/* coded by J. Quinn                                    */
+/********************************************************/
+void 
+divint (lrs_mp a, lrs_mp b, lrs_mp c)	/* c=a/b, a contains remainder on return */
+{
+  long cy, la, lb, lc, d1, s, t, sig;
+  long i, j, qh;
+
+/*  figure out and save sign, do everything with positive numbers */
+  sig = sign (a) * sign (b);
+
+  la = length (a);
+  lb = length (b);
+  lc = la - lb + 2;
+  if (la < lb)
+    {
+      storelength (c, TWO);
+      storesign (c, POS);
+      c[1] = 0;
+      normalize (c);
+      return;
+    }
+  for (i = 1; i < lc; i++)
+    c[i] = 0;
+  storelength (c, lc);
+  storesign (c, (sign (a) == sign (b)) ? POS : NEG);
+
+/******************************/
+  /* division by a single word: */
+  /*  do it directly            */
+/******************************/
+
+  if (lb == 2)
+    {
+      cy = 0;
+      t = b[1];
+      for (i = la - 1; i > 0; i--)
+	{
+	  cy = cy * BASE + a[i];
+	  a[i] = 0;
+	  cy -= (c[i] = cy / t) * t;
+	}
+      a[1] = cy;
+      storesign (a, (cy == 0) ? POS : sign (a));
+      storelength (a, TWO);
+      /*      set sign of c to sig  (**mod**)            */
+      storesign (c, sig);
+      normalize (c);
+      return;
+    }
+  else
+    {
+      /* mp's are actually DIGITS+1 in length, so if length of a or b = */
+      /* DIGITS, there will still be room after normalization. */
+/****************************************************/
+      /* Step D1 - normalize numbers so b > floor(BASE/2) */
+      d1 = BASE / (b[lb - 1] + 1);
+      if (d1 > 1)
+	{
+	  cy = 0;
+	  for (i = 1; i < la; i++)
+	    {
+	      cy = (a[i] = a[i] * d1 + cy) / BASE;
+	      a[i] %= BASE;
+	    }
+	  a[i] = cy;
+	  cy = 0;
+	  for (i = 1; i < lb; i++)
+	    {
+	      cy = (b[i] = b[i] * d1 + cy) / BASE;
+	      b[i] %= BASE;
+	    }
+	  b[i] = cy;
+	}
+      else
+	{
+	  a[la] = 0;		/* if la or lb = DIGITS this won't work */
+	  b[lb] = 0;
+	}
+/*********************************************/
+      /* Steps D2 & D7 - start and end of the loop */
+      for (j = 0; j <= la - lb; j++)
+	{
+/*************************************/
+	  /* Step D3 - determine trial divisor */
+	  if (a[la - j] == b[lb - 1])
+	    qh = BASE - 1;
+	  else
+	    {
+	      s = (a[la - j] * BASE + a[la - j - 1]);
+	      qh = s / b[lb - 1];
+	      while (qh * b[lb - 2] > (s - qh * b[lb - 1]) * BASE + a[la - j - 2])
+		qh--;
+	    }
+/*******************************************************/
+	  /* Step D4 - divide through using qh as quotient digit */
+	  cy = 0;
+	  for (i = 1; i <= lb; i++)
+	    {
+	      s = qh * b[i] + cy;
+	      a[la - j - lb + i] -= s % BASE;
+	      cy = s / BASE;
+	      if (a[la - j - lb + i] < 0)
+		{
+		  a[la - j - lb + i] += BASE;
+		  cy++;
+		}
+	    }
+/*****************************************************/
+	  /* Step D6 - adjust previous step if qh is 1 too big */
+	  if (cy)
+	    {
+	      qh--;
+	      cy = 0;
+	      for (i = 1; i <= lb; i++)		/* add a back in */
+		{
+		  a[la - j - lb + i] += b[i] + cy;
+		  cy = a[la - j - lb + i] / BASE;
+		  a[la - j - lb + i] %= BASE;
+		}
+	    }
+/***********************************************************************/
+	  /* Step D5 - write final value of qh.  Saves calculating array indices */
+	  /* to do it here instead of before D6 */
+
+	  c[la - lb - j + 1] = qh;
+
+	}
+/**********************************************************************/
+      /* Step D8 - unnormalize a and b to get correct remainder and divisor */
+
+      for (i = lc; c[i - 1] == 0 && i > 2; i--);	/* strip excess 0's from quotient */
+      storelength (c, i);
+      if (i == 2 && c[1] == 0)
+	storesign (c, POS);
+      cy = 0;
+      for (i = lb - 1; i >= 1; i--)
+	{
+	  cy = (a[i] += cy * BASE) % d1;
+	  a[i] /= d1;
+	}
+      for (i = la; a[i - 1] == 0 && i > 2; i--);	/* strip excess 0's from quotient */
+      storelength (a, i);
+      if (i == 2 && a[1] == 0)
+	storesign (a, POS);
+      if (cy)
+	fprintf (lrs_ofp, "divide error");
+      for (i = lb - 1; i >= 1; i--)
+	{
+	  cy = (b[i] += cy * BASE) % d1;
+	  b[i] /= d1;
+	}
+    }
+}
+/* end of divint */
+
+void 
+gcd (lrs_mp u, lrs_mp v)	/*returns u=gcd(u,v) destroying v */
+	     /*Euclid's algorithm.  Knuth, II, p.320  
+	        modified to avoid copies r=u,u=v,v=r
+	        Switches to single precision when possible for greater speed */
+{
+  lrs_mp r;
+  unsigned long ul, vl;
+  long i;
+  static unsigned long maxspval = MAXD;		/* Max value for the last digit to guarantee */
+  /* fitting into a single long integer. */
+
+  static long maxsplen;		/* Maximum digits for a number that will fit */
+  /* into a single long integer. */
+
+  static long firstime = TRUE;
+
+  if (firstime)			/* initialize constants */
+    {
+      for (maxsplen = 2; maxspval >= BASE; maxsplen++)
+	maxspval /= BASE;
+      firstime = FALSE;
+    }
+  if (greater (v, u))
+    goto bigv;
+bigu:
+  if (zero (v))
+    return;
+  if ((i = length (u)) < maxsplen || (i == maxsplen && u[maxsplen - 1] < maxspval))
+    goto quickfinish;
+  divint (u, v, r);
+  normalize (u);
+
+bigv:
+  if (zero (u))
+    {
+      copy (u, v);
+      return;
+    }
+  if ((i = length (v)) < maxsplen || (i == maxsplen && v[maxsplen - 1] < maxspval))
+    goto quickfinish;
+  divint (v, u, r);
+  normalize (v);
+  goto bigu;
+  /* Base 10000 only at the moment */
+  /* when u and v are small enough, transfer to single precision integers */
+  /* and finish with euclid's algorithm, then transfer back to lrs_mp */
+quickfinish:
+  ul = vl = 0;
+  for (i = length (u) - 1; i > 0; i--)
+    ul = BASE * ul + u[i];
+  for (i = length (v) - 1; i > 0; i--)
+    vl = BASE * vl + v[i];
+  if (ul > vl)
+    goto qv;
+qu:
+  if (!vl)
+    {
+      for (i = 1; ul; i++)
+	{
+	  u[i] = ul % BASE;
+	  ul = ul / BASE;
+	}
+      storelength (u, i);
+      return;
+    }
+  ul %= vl;
+qv:
+  if (!ul)
+    {
+      for (i = 1; vl; i++)
+	{
+	  u[i] = vl % BASE;
+	  vl = vl / BASE;
+	}
+      storelength (u, i);
+      return;
+    }
+  vl %= ul;
+  goto qu;
+}
+
+long 
+compare (lrs_mp a, lrs_mp b)	/* a ? b and returns -1,0,1 for <,=,> */
+{
+  long i;
+
+  if (a[0] > b[0])
+    return 1L;
+  if (a[0] < b[0])
+    return -1L;
+
+  for (i = length (a) - 1; i >= 1; i--)
+    {
+      if (a[i] < b[i])
+	{
+	  if (sign (a) == POS)
+	    return -1L;
+	  else
+	    return 1L;
+	}
+      if (a[i] > b[i])
+	{
+	  if (sign (a) == NEG)
+	    return -1L;
+	  else
+	    return 1L;
+	}
+    }
+  return 0L;
+}
+
+
+long 
+greater (lrs_mp a, lrs_mp b)	/* tests if a > b and returns (TRUE=POS) */
+{
+  long i;
+
+  if (a[0] > b[0])
+    return (TRUE);
+  if (a[0] < b[0])
+    return (FALSE);
+
+  for (i = length (a) - 1; i >= 1; i--)
+    {
+      if (a[i] < b[i])
+	{
+	  if (sign (a) == POS)
+	    return (0);
+	  else
+	    return (1);
+	}
+      if (a[i] > b[i])
+	{
+	  if (sign (a) == NEG)
+	    return (0);
+	  else
+	    return (1);
+	}
+    }
+  return (0);
+}
+void 
+itomp (long in, lrs_mp a)
+    /* convert integer i to multiple precision with base BASE */
+{
+  long i;
+  a[0] = 2;			/* initialize to zero */
+  for (i = 1; i < lrs_digits; i++)
+    a[i] = 0;
+  if (in < 0)
+    {
+      storesign (a, NEG);
+      in = in * (-1);
+    }
+  i = 0;
+  while (in != 0)
+    {
+      i++;
+      a[i] = in - BASE * (in / BASE);
+      in = in / BASE;
+      storelength (a, i + 1);
+    }
+}				/* end of itomp */
+
+
+void 
+linint (lrs_mp a, long ka, lrs_mp b, long kb)	/*compute a*ka+b*kb --> a */
+/***Handbook of Algorithms and Data Structures P.239 ***/
+{
+  long i, la, lb;
+  la = length (a);
+  lb = length (b);
+  for (i = 1; i < la; i++)
+    a[i] *= ka;
+  if (sign (a) != sign (b))
+    kb = (-kb);
+  if (lb > la)
+    {
+      storelength (a, lb);
+      for (i = la; i < lb; i++)
+	a[i] = 0;
+    }
+  for (i = 1; i < lb; i++)
+    a[i] += kb * b[i];
+  normalize (a);
+}
+/***end of linint***/
+
+
+void 
+mptodouble (lrs_mp a, double *x)	/* convert lrs_mp to double */
+{
+  long i, la;
+  double y = 1.0;
+
+  (*x) = 0;
+  la = length (a);
+  for (i = 1; i < la; i++)
+    {
+      (*x) = (*x) + y * a[i];
+      y = y * BASE;
+    }
+  if (negative (a))
+    (*x)= -(*x);
+}
+
+void 
+mulint (lrs_mp a, lrs_mp b, lrs_mp c)	/* multiply two integers a*b --> c */
+
+/***Handbook of Algorithms and Data Structures, p239  ***/
+{
+  long nlength, i, j, la, lb;
+/*** b and c may coincide ***/
+  la = length (a);
+  lb = length (b);
+  nlength = la + lb - 2;
+  if (nlength > lrs_digits)
+    digits_overflow ();
+
+  for (i = 0; i < la - 2; i++)
+    c[lb + i] = 0;
+  for (i = lb - 1; i > 0; i--)
+    {
+      for (j = 2; j < la; j++)
+	if ((c[i + j - 1] += b[i] * a[j]) >
+	    MAXD - (BASE - 1) * (BASE - 1) - MAXD / BASE)
+	  {
+	    c[i + j - 1] -= (MAXD / BASE) * BASE;
+	    c[i + j] += MAXD / BASE;
+	  }
+      c[i] = b[i] * a[1];
+    }
+  storelength (c, nlength);
+  storesign (c, sign (a) == sign (b) ? POS : NEG);
+  normalize (c);
+}
+/***end of mulint ***/
+
+void 
+normalize (lrs_mp a)
+{
+  long cy, i, la;
+  la = length (a);
+start:
+  cy = 0;
+  for (i = 1; i < la; i++)
+    {
+      cy = (a[i] += cy) / BASE;
+      a[i] -= cy * BASE;
+      if (a[i] < 0)
+	{
+	  a[i] += BASE;
+	  cy--;
+	}
+    }
+  while (cy > 0)
+    {
+      a[i++] = cy % BASE;
+      cy /= BASE;
+    }
+  if (cy < 0)
+    {
+      a[la - 1] += cy * BASE;
+      for (i = 1; i < la; i++)
+	a[i] = (-a[i]);
+      storesign (a, sign (a) == POS ? NEG : POS);
+      goto start;
+    }
+  while (a[i - 1] == 0 && i > 2)
+    i--;
+  if (i > lrs_record_digits)
+    {
+      if ((lrs_record_digits = i) > lrs_digits)
+	digits_overflow ();
+    };
+  storelength (a, i);
+  if (i == 2 && a[1] == 0)
+    storesign (a, POS);
+}				/* end of normalize */
+
+
+long 
+mptoi (lrs_mp a)		/* convert lrs_mp to long integer */
+{
+  long len = length (a);
+  if (len == 2)
+    return sign (a) * a[1];
+  if (len == 3)
+    return sign (a) * (a[1] + BASE * a[2]);
+  notimpl ("mp to large for conversion to long");
+  return 0;			/* never executed */
+}
+
+void 
+pmp (char name[], lrs_mp a)	/*print the long precision integer a */
+{
+  long i;
+  fprintf (lrs_ofp, "%s", name);
+  if (sign (a) == NEG)
+    fprintf (lrs_ofp, "-");
+  else
+    fprintf (lrs_ofp, " ");
+  fprintf (lrs_ofp, "%lu", a[length (a) - 1]);
+  for (i = length (a) - 2; i >= 1; i--)
+    fprintf (lrs_ofp, FORMAT, a[i]);
+  fprintf (lrs_ofp, " ");
+}
+
+
+void 
+prat (char name[], lrs_mp Nin, lrs_mp Din)	/*reduce and print Nin/Din  */
+{
+  lrs_mp Nt, Dt;
+  long i;
+  fprintf (lrs_ofp, "%s", name);
+/* reduce fraction */
+  copy (Nt, Nin);
+  copy (Dt, Din);
+  reduce (Nt, Dt);
+/* print out       */
+  if (sign (Nin) * sign (Din) == NEG)
+    fprintf (lrs_ofp, "-");
+  else
+    fprintf (lrs_ofp, " ");
+  fprintf (lrs_ofp, "%lu", Nt[length (Nt) - 1]);
+  for (i = length (Nt) - 2; i >= 1; i--)
+    fprintf (lrs_ofp, FORMAT, Nt[i]);
+  if (!(Dt[0] == 2 && Dt[1] == 1))	/* rational */
+    {
+      fprintf (lrs_ofp, "/");
+      fprintf (lrs_ofp, "%lu", Dt[length (Dt) - 1]);
+      for (i = length (Dt) - 2; i >= 1; i--)
+	fprintf (lrs_ofp, FORMAT, Dt[i]);
+    }
+  fprintf (lrs_ofp, " ");
+}
+
+void 
+readmp (lrs_mp a)
+      /* read an integer and convert to lrs_mp with base BASE */
+{
+  char in[MAXINPUT];
+  if(fscanf (lrs_ifp, "%s", in)==EOF)
+                 {
+                   fprintf (lrs_ofp, "\nInvalid integer input"); 
+                   exit(1);
+                 }
+  atomp (in, a);
+}
+
+long 
+readrat (lrs_mp Na, lrs_mp Da)
+ /* read a rational or integer and convert to lrs_mp with base BASE */
+ /* returns true if denominator is not one                      */
+ /* returns 999 if premature end of file                        */
+{
+  char in[MAXINPUT], num[MAXINPUT], den[MAXINPUT];
+  if(fscanf (lrs_ifp, "%s", in)==EOF)
+                 {
+                   fprintf (lrs_ofp, "\nInvalid rational input"); 
+                   exit(1);
+                 }
+  if(!strcmp(in,"end"))          /*premature end of input file */
+    {
+     return (999L);
+    }
+  atoaa (in, num, den);		/*convert rational to num/dem strings */
+  atomp (num, Na);
+  if (den[0] == '\0')
+    {
+      itomp (1L, Da);
+      return (FALSE);
+    }
+  atomp (den, Da);
+  return (TRUE);
+}
+
+
+void 
+addint (lrs_mp a, lrs_mp b, lrs_mp c)	/* compute c=a+b */
+{
+  copy (c, a);
+  linint (c, 1, b, 1);
+}
+
+void 
+atomp (char s[], lrs_mp a)	/*convert string to lrs_mp integer */
+{
+  lrs_mp mpone;
+  long diff, ten, i, sig;
+  itomp (1L, mpone);
+  ten = 10L;
+  for (i = 0; s[i] == ' ' || s[i] == '\n' || s[i] == '\t'; i++);
+  /*skip white space */
+  sig = POS;
+  if (s[i] == '+' || s[i] == '-')	/* sign */
+    sig = (s[i++] == '+') ? POS : NEG;
+  itomp (0L, a);
+  while (s[i] >= '0' && s[i] <= '9')
+    {
+      diff = s[i] - '0';
+      linint (a, ten, mpone, diff);
+      i++;
+    }
+  storesign (a, sig);
+  if (s[i])
+    {
+      fprintf (stderr, "\nIllegal character in number: '%s'\n", s + i);
+      exit (1);
+    }
+
+}				/* end of atomp */
+
+void 
+subint (lrs_mp a, lrs_mp b, lrs_mp c)	/* compute c=a-b */
+
+{
+  copy (c, a);
+  linint (a, 1, b, -1);
+}
+
+void 
+decint (lrs_mp a, lrs_mp b)	/* compute a=a-b */
+
+{
+  linint (a, 1, b, -1);
+}
+
+
+long 
+myrandom (long num, long nrange)
+/* return a random number in range 0..nrange-1 */
+
+{
+  long i;
+  i = (num * 401 + 673) % nrange;
+  return (i);
+}
+
+
+long 
+atos (char s[])			/* convert s to integer */
+{
+  long i, j;
+  j = 0;
+  for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
+    j = 10 * j + s[i] - '0';
+  return (j);
+}
+
+void 
+stringcpy (char *s, char *t)	/*copy t to s pointer version */
+{
+  while (((*s++) = (*t++)) != '\0');
+}
+
+
+void 
+rattodouble (lrs_mp a, lrs_mp b, double *x)	/* convert lrs_mp rational to double */
+
+{
+  double y;
+  mptodouble (a, &y);
+  mptodouble (b, x);
+  *x = y / (*x);
+}
+
+
+void 
+atoaa (char in[], char num[], char den[])
+/* convert rational string in to num/den strings */
+{
+  long i, j;
+  for (i = 0; in[i] != '\0' && in[i] != '/'; i++)
+    num[i] = in[i];
+  num[i] = '\0';
+  den[0] = '\0';
+  if (in[i] == '/')
+    {
+      for (j = 0; in[j + i + 1] != '\0'; j++)
+	den[j] = in[i + j + 1];
+      den[j] = '\0';
+    }
+}				/* end of atoaa */
+
+
+void 
+lcm (lrs_mp a, lrs_mp b)
+/* a = least common multiple of a, b; b is preserved */
+{
+  lrs_mp u, v;
+  copy (u, a);
+  copy (v, b);
+  gcd (u, v);
+  exactdivint (a, u, v);		/* v=a/u   no remainder*/
+  mulint (v, b, a);
+}				/* end of lcm */
+
+void 
+reducearray (lrs_mp_vector p, long n)
+/* find largest gcd of p[0]..p[n-1] and divide through */
+{
+  lrs_mp divisor;
+  lrs_mp Temp;
+  long i = 0L;
+
+  while ((i < n) && zero (p[i]))
+    i++;
+  if (i == n)
+    return;
+
+  copy (divisor, p[i]);
+  storesign (divisor, POS);
+  i++;
+
+  while (i < n)
+    {
+      if (!zero (p[i]))
+	{
+	  copy (Temp, p[i]);
+	  storesign (Temp, POS);
+	  gcd (divisor, Temp);
+	}
+      i++;
+    }
+
+/* reduce by divisor */
+  for (i = 0; i < n; i++)
+    if (!zero (p[i]))
+      reduceint (p[i], divisor);
+}				/* end of reducearray */
+
+
+void 
+reduceint (lrs_mp Na, lrs_mp Da)	/* divide Na by Da and return */
+{
+  lrs_mp Temp;
+  copy (Temp, Na);
+  exactdivint (Temp, Da, Na);
+}
+
+void 
+reduce (lrs_mp Na, lrs_mp Da)	/* reduces Na Da by gcd(Na,Da) */
+{
+  lrs_mp Nb, Db, Nc, Dc;
+  copy (Nb, Na);
+  copy (Db, Da);
+  storesign (Nb, POS);
+  storesign (Db, POS);
+  copy (Nc, Na);
+  copy (Dc, Da);
+  gcd (Nb, Db);			/* Nb is the gcd(Na,Da) */
+  exactdivint (Nc, Nb, Na);
+  exactdivint (Dc, Nb, Da);
+}
+
+
+long 
+comprod (lrs_mp Na, lrs_mp Nb, lrs_mp Nc, lrs_mp Nd)	/* +1 if Na*Nb > Nc*Nd  */
+			  /* -1 if Na*Nb < Nc*Nd  */
+			  /*  0 if Na*Nb = Nc*Nd  */
+{
+  lrs_mp mc, md;
+  mulint (Na, Nb, mc);
+  mulint (Nc, Nd, md);
+  linint (mc, ONE, md, -ONE);
+  if (positive (mc))
+    return (1);
+  if (negative (mc))
+    return (-1);
+  return (0);
+}
+
+
+void 
+notimpl (char s[])
+{
+  fflush (stdout);
+  fprintf (stderr, "\nAbnormal Termination  %s\n", s);
+  exit (1);
+}
+
+void 
+getfactorial (lrs_mp factorial, long k)		/* compute k factorial in lrs_mp */
+{
+  lrs_mp temp;
+  long i;
+  itomp (ONE, factorial);
+  for (i = 2; i <= k; i++)
+    {
+      itomp (i, temp);
+      mulint (temp, factorial, factorial);
+    }
+}				/* end of getfactorial */
+/***************************************************************/
+/*     Package of routines for rational arithmetic             */
+/***************************************************************/
+
+void 
+scalerat (lrs_mp Na, lrs_mp Da, long ka)	/* scales rational by ka */
+{
+  lrs_mp Nt;
+  copy (Nt, Na);
+  itomp (ZERO, Na);
+  linint (Na, ZERO, Nt, ka);
+  reduce (Na, Da);
+}
+
+void 
+linrat (lrs_mp Na, lrs_mp Da, long ka, lrs_mp Nb, lrs_mp Db, long kb, lrs_mp Nc, lrs_mp Dc)
+/* computes Nc/Dc = ka*Na/Da  +kb* Nb/Db
+   and reduces answer by gcd(Nc,Dc) */
+{
+  lrs_mp c;
+  mulint (Na, Db, Nc);
+  mulint (Da, Nb, c);
+  linint (Nc, ka, c, kb);	/* Nc = (ka*Na*Db)+(kb*Da*Nb)  */
+  mulint (Da, Db, Dc);		/* Dc =  Da*Db           */
+  reduce (Nc, Dc);
+}
+
+void 
+divrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc)
+ /* computes Nc/Dc = (Na/Da)  / ( Nb/Db )
+    and reduces answer by gcd(Nc,Dc) */
+{
+  mulint (Na, Db, Nc);
+  mulint (Da, Nb, Dc);
+  reduce (Nc, Dc);
+}
+
+void 
+mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc)
+/* computes Nc/Dc = Na/Da  * Nb/Db and reduces by gcd(Nc,Dc) */
+{
+  mulint (Na, Nb, Nc);
+  mulint (Da, Db, Dc);
+  reduce (Nc, Dc);
+}
+
+/*     End package of routines for rational arithmetic         */
+
+/***************************************************************/
+/*                                                             */
+/*  End of package for multiple precision arithmetic           */
+/*                                                             */
+/***************************************************************/
+
+
+void *
+xcalloc (long n, long s, long l, char *f)
+{
+  void *tmp;
+
+  tmp = calloc (n, s);
+  if (tmp == 0)
+    {
+      char buf[200];
+
+      sprintf (buf, "\n\nFatal error on line %ld of %s", l, f);
+      perror (buf);
+      exit (1);
+    }
+  return tmp;
+}
+
+void 
+lrs_getdigits (long *a, long *b)
+{
+/* send digit information to user */
+  *a = DIG2DEC (lrs_digits);
+  *b = DIG2DEC (lrs_record_digits);
+  return;
+}
+
+void 
+lrs_default_digits_overflow ()
+{
+  fprintf (lrs_ofp, "\nOverflow at digits=%ld", DIG2DEC (lrs_digits));
+  fprintf (lrs_ofp, "\nInitialize lrs_mp_init with  n > %ldL\n", DIG2DEC (lrs_digits));
+
+  exit (1);
+}
+
+/* end of lrsmp.c */
Index: /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.h
===================================================================
--- /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.h	(revision 10198)
+++ /branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/lrsmp.h	(revision 10198)
@@ -0,0 +1,227 @@
+/* lrsmp.h (lrs extended precision arithmetic library)              */
+/* Copyright: David Avis 2000, avis@cs.mcgill.ca                    */
+/* Version 4.0, February 17, 2000                                   */
+
+/* This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/******************************************************************************/
+/*  See http://cgm.cs.mcgill.ca/~avis/C/lrs.html for lrs usage instructions   */
+/******************************************************************************/
+/* This package contains the extended precision routines used by lrs
+   and some other miscellaneous routines. The maximum precision depends on
+   the parameter MAX_DIGITS defined below, with usual default of 255L. This
+   gives a maximum of 1020 decimal digits on 32 bit machines. The procedure
+   lrs_mp_init(dec_digits) may set a smaller number of dec_digits, and this
+   is useful if arrays or matrices will be used.
+ */
+
+/***********/
+/* defines */
+/***********/
+/*
+   this is number of longwords. Increasing this won't cost you that much
+   since only variables other than the A matrix are allocated this size.
+   Changing affects running time in small but not very predictable ways.
+ */
+
+#define MAX_DIGITS 255L
+
+/*
+   this is in decimal digits, you pay in memory if you increase this,
+   unless you override by a line with
+   digits n
+   before the begin line of your file.
+ */
+#define DEFAULT_DIGITS 100L
+
+
+
+/**********MACHINE DEPENDENT CONSTANTS***********/
+/* MAXD is 2^(k-1)-1 where k=16,32,64 word size */
+/* MAXD must be at least 2*BASE^2               */
+/* If BASE is 10^k, use "%k.ku" for FORMAT      */
+/* INTSIZE is number of bytes for integer       */
+/* 32/64 bit machines                           */
+/***********************************************/
+#ifndef B64
+/*32 bit machines */
+#define FORMAT "%4.4lu"
+#define MAXD 2147483647L
+#define BASE 10000L
+#define BASE_DIG 4
+#define INTSIZE 8L
+#define BIT "32bit"
+#else
+/* 64 bit machines */
+#define MAXD 9223372036854775807L
+#define BASE 1000000000L
+#define FORMAT "%9.9lu"
+#define BASE_DIG 9
+#define INTSIZE 16L
+#define BIT "64bit"
+#endif
+
+#define MAXINPUT 1000		/*max length of any input rational */
+
+#define POS 1L
+#define NEG -1L
+#ifndef TRUE
+#define TRUE 1L
+#endif
+#ifndef FALSE
+#define FALSE 0L
+#endif
+#define ONE 1L
+#define TWO 2L
+#define ZERO 0L
+
+/**********************************/
+/*         MACROS                 */
+/* dependent on mp implementation */
+/**********************************/
+
+#define exactdivint(a,b,c)	divint((a),(b),(c)) /*should use special code here */
+#define positive(a)     (((a)[0] < 2 || ((a)[0]==2 && (a)[1]==0))?FALSE:TRUE)
+#define negative(a)     (((a)[0] > -2 || ((a)[0]==-2 && (a)[1]==0))?FALSE:TRUE)
+#define zero(a)         ((((a)[0]==2 || (a)[0]==-2) && (a)[1]==0)?TRUE:FALSE)
+#define one(a)          (((a)[0]==2 && (a)[1]==1)?TRUE:FALSE)
+#define length(a)       (((a)[0] > 0) ? (a)[0] : -(a)[0])
+#define sign(a)         (((a)[0] < 0) ? NEG : POS)
+#define storesign(a,sa) a[0]=((a)[0] > 0) ? (sa)*((a)[0]) : -(sa)*((a)[0])
+#define changesign(a)   a[0]= -(a)[0]
+#define storelength(a,la) a[0]=((a)[0] > 0) ? (la) : -(la)
+
+
+/*
+ *  convert between decimal and machine (longword digits). Notice lovely
+ *  implementation of ceiling function :-)
+ */
+#define DEC2DIG(d) ( (d) % BASE_DIG ? (d)/BASE_DIG+1 : (d)/BASE_DIG)
+#define DIG2DEC(d) ((d)*BASE_DIG)
+
+#include <stdlib.h>
+
+#ifdef SIGNALS
+#include <signal.h>
+#include <unistd.h>
+#define errcheck(s,e) if ((long)(e)==-1L){  perror(s);exit(1);}
+#endif
+
+#ifdef TIMES
+void ptimes ();
+#endif
+
+
+#define CALLOC(n,s) xcalloc(n,s,__LINE__,__FILE__)
+
+/*************/
+/* typedefs  */
+/*************/
+
+typedef long lrs_mp[MAX_DIGITS + 1];	/* type lrs_mp holds one multi-precision integer */
+typedef long *lrs_mp_t;
+typedef long **lrs_mp_vector;
+typedef long ***lrs_mp_matrix;
+
+/*********************/
+/*global variables   */
+/*********************/
+
+long lrs_digits;		/* max permitted no. of digits   */
+long lrs_record_digits;		/* this is the biggest acheived so far.     */
+
+FILE *lrs_ifp;			/* input file pointer       */
+FILE *lrs_ofp;			/* output file pointer      */
+
+/*********************************************************/
+/* Initialization and allocation procedures - must use!  */
+/******************************************************* */
+
+/* next two functions are not used by lrsmp, but are for lrsgmp compatability */
+#define lrs_alloc_mp(a)    
+#define lrs_clear_mp(a)  
+lrs_mp_t lrs_alloc_mp_t();                      /* dynamic allocation of lrs_mp                  */
+lrs_mp_vector lrs_alloc_mp_vector (long n);	/* allocate lrs_mp_vector for n+1 lrs_mp numbers */
+lrs_mp_matrix lrs_alloc_mp_matrix (long m, long n);	/* allocate lrs_mp_matrix for m+1 x n+1 lrs_mp   */
+
+void lrs_clear_mp_vector (lrs_mp_vector a, long n);
+void lrs_clear_mp_matrix (lrs_mp_matrix a, long m, long n);
+
+long lrs_mp_init (long dec_digits, FILE * lrs_ifp, FILE * lrs_ofp);	/* max number of decimal digits, fps   */
+
+/*********************************************************/
+/* Core library functions - depend on mp implementation  */
+/******************************************************* */
+void atomp (char s[], lrs_mp a);	/* convert string to lrs_mp integer               */
+long compare (lrs_mp a, lrs_mp b);	/* a ? b and returns -1,0,1 for <,=,> */
+void copy (lrs_mp a, lrs_mp b);	/* assigns a=b                                    */
+void divint (lrs_mp a, lrs_mp b, lrs_mp c);	/* c=a/b, a contains remainder on return          */
+void gcd (lrs_mp u, lrs_mp v);	/* returns u=gcd(u,v) destroying v                */
+long greater (lrs_mp a, lrs_mp b);	/* tests if a > b and returns (TRUE=POS)          */
+void itomp (long in, lrs_mp a);	/* convert integer i to lrs_mp                    */
+void linint (lrs_mp a, long ka, lrs_mp b, long kb);	/* compute a*ka+b*kb --> a                        */
+void mptodouble (lrs_mp a, double *x);	/* convert lrs_mp to double                       */
+long mptoi (lrs_mp a);		/* convert lrs_mp to long integer */
+void mulint (lrs_mp a, lrs_mp b, lrs_mp c);	/* multiply two integers a*b --> c                */
+void normalize (lrs_mp a);	/* normalize lrs_mp after computation             */
+void pmp (char name[], lrs_mp a);	/* print the long precision integer a             */
+void prat (char name[], lrs_mp Nt, lrs_mp Dt);	/* reduce and print  Nt/Dt                        */
+void readmp (lrs_mp a);		/* read an integer and convert to lrs_mp          */
+long readrat (lrs_mp Na, lrs_mp Da);	/* read a rational or int and convert to lrs_mp   */
+void reduce (lrs_mp Na, lrs_mp Da);	/* reduces Na Da by gcd(Na,Da)                    */
+
+/*********************************************************/
+/* Standard arithmetic & misc. functions                 */
+/* should be independent of mp implementation            */
+/******************************************************* */
+
+void atoaa (char in[], char num[], char den[]);		/* convert rational string in to num/den strings  */
+void addint (lrs_mp a, lrs_mp b, lrs_mp c);	/* compute c=a+b                                  */
+long atos (char s[]);		/* convert s to integer                           */
+long comprod (lrs_mp Na, lrs_mp Nb, lrs_mp Nc, lrs_mp Nd);	/* +1 if Na*Nb > Nc*Nd,-1 if Na*Nb > Nc*Nd else 0 */
+void decint (lrs_mp a, lrs_mp b);	/* compute a=a-b                                  */
+void divrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
+						       /* computes Nc/Dc = (Na/Da) /( Nb/Db ) and reduce */
+void getfactorial (lrs_mp factorial, long k);	/* compute k factorial in lrs_mp                  */
+void linrat (lrs_mp Na, lrs_mp Da, long ka, lrs_mp Nb, lrs_mp Db, long kb, lrs_mp Nc, lrs_mp Dc);
+void lcm (lrs_mp a, lrs_mp b);	/* a = least common multiple of a, b; b is saved  */
+void mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc);
+						       /* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce      */
+long myrandom (long num, long nrange);	/* return a random number in range 0..nrange-1    */
+void notimpl (char s[]);	/* bail out - help!                               */
+void rattodouble (lrs_mp a, lrs_mp b, double *x);	/* convert lrs_mp rational to double              */
+void reduceint (lrs_mp Na, lrs_mp Da);	/* divide Na by Da and return it                  */
+void reducearray (lrs_mp_vector p, long n);	/* find gcd of p[0]..p[n-1] and divide through by */
+void scalerat (lrs_mp Na, lrs_mp Da, long ka);	/* scales rational by ka                          */
+void subint (lrs_mp a, lrs_mp b, lrs_mp c);	/* compute c=a-b                                  */
+
+/**********************************/
+/* Miscellaneous functions        */
+/******************************** */
+
+void free (void *);
+
+void lrs_getdigits (long *a, long *b);	/* send digit information to user                         */
+
+void stringcpy (char *s, char *t);	/* copy t to s pointer version                            */
+
+void *calloc ();
+void *malloc ();
+void *xcalloc (long n, long s, long l, char *f);
+
+void lrs_default_digits_overflow ();
+void digits_overflow ();
+
+/* end of  lrsmp.h (vertex enumeration using lexicographic reverse search) */
