<?xml version="1.0" encoding="ISO-8859-1"?>
  <chapter id="notsobasic">
  <title>
  Not-Quite-So-Basic Model Classes
  </title>
  <section id="pivotchoices">
  <title>Pivot Choices</title>
  <para>
  In the dual algorithm, any infeasible basic variable may be chosen to leave the
  basis.  Similarly in the primal algorithm, any non-basic variable with a
  &quot;bad&quot; reduced cost may be chosen to enter the basis.  This choice is
  probably the most important factor in determining the number of iterations it
  will take to solve a problem.  Clp provides a abstract base class for each case
  and then instances of each.  It is relatively simple for an advanced user to
  create new instances.
  </para>
  <para>
  For the dual method the base class is <function>ClpDualRowPivot</function>.
  The two existing instances are <function>ClpDualRowDantzig</function> and
  <function>ClpDualRowSteepest</function>.  The Dantzig version implements the
  &quot;standard&quot; pivot rule: choose the  most violated basic variable.  It
  is easily dominated by the Steepest instance which should normally be used.  The
  default is to use un-initialized weights where the initial weight for each basic
  variable is 1.0.  If an all-slack basis is being used then these are the correct
  weights.  To use a version which calculates the weights, create an instance and
  pass it to ClpSimplex model as in the following code fragment:
  </para>
  <programlisting>
  ClpDualRowSteepest steep(1); // 0 uninitialized, 1 compute weights
  model.setDualRowPivotAlgorithm(steep);
  </programlisting>
  <para>Similarly for the primal method the base class is
  <function>ClpPrimalColumnPivot</function>.  The two existing instances are
  <function>ClpPrimalColumnDantzig</function> and
  <function>ClpPrimalColumnSteepest</function>.  The Dantzig version implements
  &quot;standard&quot; pivot rule: choose the most &quot;violated&quot; non-basic
  variable.  It is dominated by the Steepest instance which should normally be
  used.  The default is to use exact Devex where the initial weight for each
  non-basic variable is 1.0.  Unlike for the dual, this is never the same as
  normal steepest edge.  To use a version which does steepest edge create an
  instance and pass it to ClpSimplex model as in the following code fragment:
  </para>
  <programlisting>
  ClpPrimalColumnSteepest steep(1); // 0 devex, 1 steepest
  model.setPrimalColumnPivotAlgorithm(steep);
  </programlisting>
  <para>
  The partial pricing scheme (for long, thin problems) currently does not
  exist.  This could be implemented by anyone who is interested.
  </para>
  </section>
  <section id="matrixclasses">
  <title>Matrix Classes</title>
  <para>
  The next abstract class of interest is <function>ClpMatrixBase</function>.
  CLP encapsulates its knowledge of how a matrix is stored in this class.  The
  default instance of this is the <function>ClpPackedMatrix</function> class.
  This is identical in format to <function>CoinPackedMatrix</function>.  Below
  is a diagram summarizing the hierarchy of the most important matrix classes:
  </para>
  <mediaobject>
    <!-- Caption doesn't line-up nicely in HTML, leave out for now
    <caption align="top">
      <para>
  	CLP Matrix Classes
      </para>
    </caption>
    -->
    <imageobject>
      <imagedata fileref="figures/clpbasicmatrixhier.gif" format="GIF"/>
    </imageobject>
  </mediaobject>
  <para>
  The important new methods implemented are for filling a basis, checking validity
  of elements and faster &quot;times&quot; and &quot;transposeTimes&quot; when
  the input array is sparse and/or we have a row copy of the matrix.  Advanced
  users should note that not all methods have to be implemented.  In particular,
  <function>scaling</function> need not be implemented and
  <function>reverseOrderedCopy</function> can return <parameter>NULL</parameter>
  if a row copy does not make sense.
  </para>
  <para>
  In addition to the default class, there are two others at present:
  <function>ClpPlusMinusOneMatrix</function> and
  <function>ClpNetworkMatrix</function>.  As the name implies, the first one is
  useful when all elements are &plusmn;1.  In this case multiplies are not needed
  and more importantly less memory is used and there are fewer cache misses.  A
  class for a matrix where all elements are +1 would be trivial to create. If
  there were fewer than 64000 rows one could even store row indices as shorts
  etc.
  </para>
  <para>
  The use of <function>ClpPlusMinusOneMatrix</function> involves some work as one
  cannot simply read-in an MPS file.  The key is to use
  <function>loadProblem</function> to pass in a matrix.  So if
  <varname>matrix</varname> was a <function>CoinPackedMatrix</function> one
  could do the following:
  </para>
  <programlisting>
  ClpPlusMinusOneMatrix plusMinus(matrix);
  assert (plusMinus.getIndices()); // would be zero if not +- one
  model.loadProblem(plusMinus,
    lowerColumn,upperColumn,objective,
    lower,upper);
  </programlisting>
  <para>
  <function>ClpNetworkMatrix</function> is similar, but represents a network,
  thus may only have one element per column.  Fortunately, using is is very
  easy.  Given <varname>head</varname> and <varname>tail</varname>, one could
  do the following:
  </para>
  <programlisting>
  ClpNetworkMatrix network(numberColumns,head,tail);
  model.loadProblem(network,
    lowerColumn,upperColumn,objective,
    lower,upper);
  </programlisting>
  <para>
  Actual code is in <filename>COIN/Clp/Test/unitTest.cpp</filename>.  A quick
  glance at the output of this program shows that use of 
  <function>ClpNetworkMatrix</function> gives much faster run times.  This is
  not because of storage issues, but because CLP recognizes the network and uses
  a network basis factorization which is much faster.  However, in this mode CLP
  is not a genuine network code as it does not take full advantage of the
  structure by combining operations but it does have the advantage of
  flexibility.
  </para>
  <para>
  Other instances are possible.  In particular, it should be possible to use the
  abstract class for column generation or for dynamic matrices which change over
  time.  Minor modifications may be needed but it should work quite smoothly
  (there is already a dummy &quot;refresh&quot; method which would be used).
  </para>
  </section>
  <section id="messagehandling">
  <title>Message Handling</title>
  <para>
  Strictly speaking, message handling is a general COIN topic, but it won't hurt
  to repeat a few important things here.
  </para>
  <para>
  A simple user you may wish to turn off some output.  This is done with
  <function>model.setLogLevel(int&nbsp;value)</function>
  where 0 gives nothing and each increase in value switches on more
  messages. See <filename>ClpMessage.cpp</filename>,
  <filename>CoinMessage.cpp</filename> and <xref linkend="messages"/> to see
  which messages are at which level.  A more sophisticated user may wish to
  handle messages in a different way.  This is done using
  <function>passInMessageHandler</function> with a pointer to a handler of the
  user's own design.  The simplest case would be to use the default handler but
  use a constructor which writes to file.  The code would be:
  </para>
  <programlisting>
  FILE * fp; // assumed open
  CoinMessageHandler handler(fp);
  model.passInMessageHandler(&amp;handler);
  </programlisting>
  <para>
  A still more sophisticated use would be to write a class derived from
  <function>CoinMessageHandler</function> and then override the
  <function>print</function> method.  Below follows an example which would
  print only a message for optimality (or infeasibility):
  </para>
  <example>
  <title>Sophisticated message handling</title>
  <programlisting>
  class DerivedHandler :
   public CoinMessageHandler {
   public:
     virtual int print() ;
   };


   int DerivedHandler::print()
   {
     if (currentSource()=="Clp") {
       if (currentMessage().externalNumber()&gt;=0
       &amp;&amp; currentMessage().externalNumber()&lt;4) { 
         // finished
         return CoinMessageHandler::print(); // print
       }
     }
     return 0;
   }
  </programlisting>
  </example>
  </section>
  </chapter>
