    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Polynomial Classes</title>
        <link>https://members.accu.org/index.php/journals/292</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #69 - Oct 2005 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c143/">69</a>
                    (6)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c143-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c143+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Polynomial Classes</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 October 2005 05:00:00 +01:00 or Sun, 02 October 2005 05:00:00 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>A multivariate polynomial in several variables, for example, 7 +
4x<sup>2</sup>y<sup>3</sup> - 5yz<sup>6</sup>, may be thought of as
a polynomial in z with coefficients that are themselves polynomials
in x and y. These coefficients, in turn, are polynomials in y with
coefficients that are polynomials in x. How can we implement this
recursive definition in C++? In this installment and the next we
will explore two distinct solutions. In the first solution the
number of variables is built into the definition of the class. In
the second, the number of variables may vary at runtime. Before
proceeding, note that similar issues arise if we define a
multi-dimensional array as an array of arrays (which is useful if
the number of non-zero entries is relatively small).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e31" id="d0e31"></a>The
Straightforward Approach</h2>
</div>
<p>If we know the number of variables at compile time, then the
overall structure of a possible solution is straightforward.
Suppose we define a template class</p>
<pre class="programlisting">
template &lt;typename C&gt; class polynomial {...};
</pre>
<p>where C is the type of the coefficients. This class is a
container of pairs of the form [power, coefficient]. For the
polynomial above, we have two pairs, [0, 7 +
4x<sup>2</sup>y<sup>3</sup>] and [6, -5y]. A polynomial in three
variables with numerical coefficients of type <tt class=
"type">double</tt> has type</p>
<pre class="programlisting">
typedef class polynomial&lt;polynomial&lt;polynomial
   &lt;double&gt; &gt; &gt; poly3_type;
</pre>
<p>A useful way to define <tt class="type">poly3_type</tt> is:</p>
<pre class="programlisting">
typedef class polynomial&lt;double&gt; poly1_type;
typedef class polynomial&lt;poly1_type&gt; 
   poly2_type;
typedef class polynomial&lt;poly2_type&gt; 
   poly3_type;
</pre>
<p>We can write</p>
<pre class="programlisting">
variable_list&lt;char&gt; vars3(&quot;xyz&quot;);
poly3_type p(vars3), q(vars3);
p.read(&quot;5-3x^2y^4+x^3z^3&quot;);
std::cin &gt;&gt; q;
std::cout &lt;&lt; &quot;p has &quot; &lt;&lt; p.number_terms() 
   &lt;&lt; &quot;terms.\n&quot;;
std::cout &lt;&lt; &quot;p+q=&quot; &lt;&lt; p + q &lt;&lt; '\n';
</pre>
<p>Note that the caret (^) means exponentiation, so y^3 means
y*y*y. The role of <tt class="literal">class variable_list</tt>
will be explained below.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e67" id="d0e67"></a>Problems With
This Approach</h2>
</div>
<p>This approach works well, but there are a few problems to
overcome. First, suppose we want our polynomial class to have a
method that returns the number of terms. In our example polynomial
there are three terms. This is easy to compute - just sum the
number of terms in each coefficient:</p>
<pre class="programlisting">
template &lt;typename C&gt;
int polynomial&lt;C&gt;::number_terms() const
{
  int count = 0;
  for (const_iterator it(begin());
   it != end(); ++it)
    count += it-&gt;coefficient().number_terms();
  return count;
}
</pre>
<p>Here, the method <tt class="methodname">coefficient()</tt>
returns a <tt class="literal">const</tt> reference to the second
element of a pair in our container. The problem is that this code
will not compile. Note that the call to <tt class=
"methodname">number_terms()</tt> inside the <tt class=
"literal">for</tt> loop is not a true recursive call. For example,
if we call this method for a polynomial of type <tt class=
"type">poly3_type</tt>, then <tt class="literal">it
&gt;coefficient()</tt> has type <tt class="type">poly2_type</tt>
and so we are calling <tt class=
"methodname">poly2_type::number_terms</tt>, which in turn calls
<tt class="methodname">poly1_type::number_terms</tt>. It is this
last call that causes the problem, since now <tt class="literal">it
&gt;coefficient()</tt> has type <tt class="type">double</tt>, and
type <tt class="type">double</tt> has no method named <tt class=
"methodname">number_terms</tt>.</p>
<p>There are at least three ways to deal with this problem. First,
we could use partial specialization to handle the end case. Having
defined</p>
<pre class="programlisting">
template &lt;typename C&gt; class polynomial;
</pre>
<p>we can now define, for example,</p>
<pre class="programlisting">
template &lt;&gt; class polynomial&lt;double&gt;;
</pre>
<p>But this requires specializing class polynomial for each
possible numerical type, for example,</p>
<pre class="programlisting">
template &lt;&gt;
   class polynomial&lt;std::complex&lt;double&gt; &gt;;
</pre>
<p>A better way is to turn this approach on its head and define the
partial specialization for the case where the coefficients are
themselves polynomials:</p>
<pre class="programlisting">
template &lt;typename C&gt;
   class polynomial&lt;polynomial&lt;C&gt; &gt; 
{ . . . };
</pre>
<p>With this approach, we have</p>
<pre class="programlisting">
template &lt;typename C&gt; class polynomial {
//Coefficients are numeric
public:
  int number_terms() const {
    int count = 0;
    for (const_iterator it(begin());
       it != end(); ++it)
      if (it-&gt;coefficient() != 0)
        ++count;
    return count;
  }
  //other methods . . .
}
</pre>
<p>and the partial specialization</p>
<pre class="programlisting">
template &lt;typename C&gt; 
   class polynomial&lt;polynomial&lt;C&gt; &gt; {
//Coefficients are polynomials
public:
  int number_terms() const {int count = 0;
    for (const_iterator it(begin());
       it != end(); ++it)
      count +=
         it-&gt;coefficient().number_terms();
    return count;
  }
  //other methods . . .
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e139" id="d0e139"></a>Using a
Traits Class</h2>
</div>
<p>The objection to this approach is that we must repeat all of the
code in the definition of the class and in its partial
specialization, even if the code is identical. A variant on this
approach is to use a traits class [<a href=
"#Alexandrescu-">Alexandrescu-</a>]. We define (for numeric
coefficients)</p>
<pre class="programlisting">
template &lt;typename C&gt; class coefficient_traits {
public:
  static int number_terms(C const &amp;c)
  { return c != 0 ? 1 : 0; }
  //other methods . . .
};
</pre>
<p>As above, we need to specialize this for the case of a
multivariate polynomial:</p>
<pre class="programlisting">
template &lt;typename C&gt;
class coefficient_traits&lt;polynomial&lt;C&gt; &gt;
{
public:
  typedef polynomial&lt;C&gt; coef_type;
  static int number_terms(coef_type const &amp;c)
  {
    int count = 0;
    for (coef_type::const_iterator
       it(c.begin()); 
       it != c.end(); ++it) 
      count +=
         it-&gt;coefficient().number_terms(); 
    return count;
  }
  //other methods . . .
};
</pre>
<p>Then we can define <tt class="methodname">number_terms()</tt> in
class polynomial by</p>
<pre class="programlisting">
int number_terms() const {
  int count = 0;
  for (const_iterator it(begin());
     it != end(); ++it)
    count += coefficient_traits&lt;C&gt;::
       number_terms(it-&gt;coefficient());
  return count;
}
</pre>
<p>Of course, the traits class can be used to record other
properties. Suppose we have a template class called <tt class=
"classname">numeric_traits</tt> that includes all the methods
required for <tt class="classname">coefficient_traits</tt> with
definitions that are appropriate for most numeric types. Then we
define <tt class="classname">coefficient_traits</tt> by</p>
<pre class="programlisting">
template &lt;typename T&gt;
class coefficient_traits 
: public numeric_traits&lt;T&gt; { };//Default case
</pre>
<p>Of course, we must provide a partial specialization for
coefficients that are polynomials:</p>
<pre class="programlisting">
template &lt;typename C&gt;
class coefficient_traits&lt;polynomial&lt;C&gt; &gt; {...};
</pre>
<p>We can also specialize as needed for numeric coefficients. For
example, to output the polynomial x - 3y, we need to know that the
coefficient of y is negative. (Otherwise, we would output x + -3y.)
Now for a coefficient c of type double, we can ask if c&lt;0, but
not if c has type complex. Therefore, we include in <tt class=
"classname">coefficient_traits</tt> a method</p>
<pre class="programlisting">
static bool is_negative(C const &amp;c);
</pre>
<p>For C of type <tt class="type">std::complex&lt;T&gt;</tt>, we
can override this method in an appropriate way.</p>
<p>One possibility is:</p>
<pre class="programlisting">
template &lt;typename T&gt;
class coefficient_traits&lt; std::complex&lt;T&gt; &gt;
: public numeric_traits&lt;std::complex&lt;T&gt; &gt;
{
public:
  static bool is_negative(coef_type const &amp; c)
  { return c.imag() == 0 &amp;&amp; c.real() &lt; 0; }
  //other overrides
};
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e193" id="d0e193"></a>Numeric
versus Polynomial Coefficients - a Third Way</h2>
</div>
<p>Let's get back to our original problem, namely how to
differentiate between coefficients that are polynomials and those
that are numeric. Our third approach relies on the fact that in a
template class, a method that is not invoked must not be
instantiated. With this approach the method <tt class=
"methodname">number_terms</tt> calls one of two methods depending
on the coefficient type. For this to work, the choice must be made
at compile time. To this end we use a technique described in
Alexandrescu's book [<a href="#Alexandrescu">Alexandrescu</a>].
First an auxiliary class will be used to distinguish the two
cases:</p>
<pre class="programlisting">
template &lt; bool b &gt; struct Bool2Type { };
</pre>
<p>Now, define in class <tt class=
"classname">polynomial&lt;C&gt;</tt></p>
<pre class="programlisting">
int number_terms() const
{
  return number_terms(
    Bool2Type&lt;(nbr_vars==1)&gt;());
}

int number_terms(Bool2Type&lt;false&gt;) const
{
  int count = 0;
  for (const_iterator it(begin());
      it != end(); ++it)
    count += it-&gt;coefficient().number_terms();
  return count;
}

int number_terms(Bool2Type&lt;true&gt;) const
{
  int count = 0;
  for (const_iterator it(begin());
      it != end(); ++it)
    if (it-&gt;coefficient() != 0)
      ++count;
  return count;
}
</pre>
<p>Depending on the type C, exactly one of the latter two methods
will be invoked; the other will not be instantiated, so there will
be no compile-time error. The compile-time constant <tt class=
"literal">nbr_vars</tt> has other uses as we will see below. It is
defined by</p>
<pre class="programlisting">
namespace detail
{
  //Count the number of variables in a poly
  template &lt;typename C&gt;//Base case
  struct var_count
  {
    static const int nbr_vars = 0;
  };
  template &lt;typename C&gt;
  struct var_count&lt;polynomial&lt;C&gt; &gt;
  {
    static const int nbr_vars =
       1 + var_count&lt;C&gt;::nbr_vars;
  };
}
</pre>
<p>and then in class <tt class=
"classname">polynomial&lt;C&gt;</tt>:</p>
<pre class="programlisting">
static const int nbr_vars =
  detail::var_count&lt;polynomial&lt;C&gt; &gt;::nbr_vars;
</pre>
<p>In class <tt class="classname">polynomial</tt> most of the
methods do not depend on the coefficient type; for the few that do,
I have used both the traits class and method pairs using <tt class=
"classname">Bool2Type</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e234" id=
"d0e234"></a>Variables</h2>
</div>
<p>Before proceeding with how class <tt class=
"classname">polynomial</tt> is constructed, we need to consider
variable names and polynomials with different numbers of variables.
The representation of polynomials we are examining here implies an
ordering of the variables. For example, we may think of p as a
polynomial in y with coefficients that are polynomials in x. Of
course, we could just as well think of p as a polynomial in x with
coefficients in y. What is essential, of course, is consistency. To
compute p + q , for example, we want p and q to have variables in
the same order. Furthermore, to simplify input it is useful to know
in advance what the variable names are.</p>
<p>Let's put the responsibility for maintaining a collection of
variable names with order in a separate class</p>
<pre class="programlisting">
template &lt;typename NameType&gt; 
   class variable_list;
</pre>
<p>This class is just an ordered container of names of type
<tt class="type">NameType</tt> (e.g. <tt class="type">char</tt>)
[<a href="#var_list">var_list</a>]. Its primary constructor is</p>
<pre class="programlisting">
variable_list(char const * vars);
</pre>
<p>where the character string <tt class="varname">vars</tt> might
be <tt class="literal">&quot;xyz&quot;</tt>. The constructor will transform
<tt class="varname">vars</tt> into an ordered list. (By default,
this is reverse alphabetical order.) So, for example,</p>
<pre class="programlisting">
variable_list&lt;char&gt; vars1(&quot;xyz&quot;);
</pre>
<p>and</p>
<pre class="programlisting">
variable_list&lt;char&gt; vars1(&quot;zyx&quot;);
</pre>
<p>are equivalent.<sup>[<a name="d0e278" href="#ftn.d0e278" id=
"d0e278">1</a>]</sup></p>
<p>Now, to construct polynomials we have</p>
<pre class="programlisting">
typedef variable_list&lt;char&gt; var_list_type;
var_list_type vars3(&quot;xyz&quot;), vars2(&quot;xy&quot;);
poly2_type p(vars2);
poly3_type q(vars3);
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e285" id="d0e285"></a>Polynomial
Arithmetic</h2>
</div>
<p>Suppose we want to compute q -= p. (We use subtraction as an
example since p - q &lt;&gt; q - p , and so it is slightly more
complicated than addition.) Mathematically, q - p makes sense as a
polynomial whatever the variables of p and q. It will have three
variables if the variables of p are also variables of q. For
example, if p = x + z and q = xyz, then q - p is x + z - xyz. On
the other hand, if p = w + x, then we have a problem with q -= p,
since q - p now has four variables while the number of variables of
q is fixed at three. (We'll see how to solve this problem in part
2.)</p>
<p>In any event, I would like to be tolerant and allow p and q to
have different variables, or at least a different number of
variables. This implies that we need to declare the subtraction
operator by</p>
<pre class="programlisting">
template &lt;typename C1, typename C2&gt;
????? operator -(polynomial&lt;C1&gt; const &amp; p,
                 polynomial&lt;C2&gt; const &amp; q);
</pre>
<p>The fun begins with the return type. If C1 and C2 are not the
same, the return type should be the type of the argument that has
more variables. For example, the return type of p - q (of types
<tt class="type">poly2_type</tt> and <tt class=
"type">poly3_type</tt>, as above) should be <tt class=
"type">poly3_type</tt>. Here are two ways to deal with this
problem. Both approaches need to compare the number of variables of
types <tt class="classname">polynomial&lt;C1&gt;</tt> and
<tt class="classname">polynomial&lt;C2&gt;</tt>, so let's
encapsulate this information in a class:</p>
<pre class="programlisting">
namespace detail
{
template
&lt;typename C1, typename C2, bool b&gt;
struct pick_poly //case b is false
  { typedef polynomial&lt;C2&gt; type; };

template &lt;typename C1, typename C2&gt;
struct pick_poly&lt;C1, C2, true&gt; 
  { typedef polynomial &lt;C1&gt; type; };

template &lt;typename C1, typename C2&gt;
struct compare_coefs {
  static const bool use_c1 =
    (polynomial&lt;C1&gt;::nbr_vars &gt;=
     polynomial &lt;C2&gt;::nbr_vars);

  typedef typename
  pick_poly&lt;C1,C2,use_c1&gt;::type return_type;
};
}
</pre>
<p>Here the constant <tt class="constant">use_c1</tt> is true if
<tt class="classname">polynomial&lt;C1&gt;</tt> has at least as
many variables as <tt class="classname">polynomial&lt;C2&gt;</tt>
and <tt class="type">compare_coefs&lt;C1,C2&gt;::return_type</tt>
is either <tt class="classname">polynomial&lt;C1&gt;</tt> or
<tt class="classname">polynomial&lt;C2&gt;</tt>, depending on which
has more variables. Hence this type should be the return type of
<tt class="methodname">operator -</tt>. Our first approach to
defining subtraction uses <tt class="classname">Bool2Type</tt>
defined above:</p>
<pre class="programlisting">
namespace detail {
  template &lt;typename C1, typename C2&gt;
  polynomial&lt;C1&gt; do_subtract(
   polynomial&lt;C1&gt; p,
   polynomial&lt;C2&gt; const &amp; q,
   Bool2Type&lt;true&gt;)
  {
    return p -= q;
  }
  template &lt;typename C1, typename C2&gt;
  polynomial&lt;C2&gt; do_subtract(
   polynomial&lt;C1&gt; const &amp; p,
   polynomial&lt;C2&gt; const &amp; q,
   Bool2Type&lt;false&gt;)
  {
//create a polynomial of type polynomial&lt;C2&gt;:
    return -q += p;
  }
}
template &lt;typename C1, typename C2&gt;
typename detail::compare_coefs&lt;C1,C2&gt;
               ::return_type
operator-(polynomial&lt;C1&gt; const &amp;p,
          polynomial&lt;C2&gt; const &amp;q)
{
  return detail::do_subtract(p, q,
    Bool2Type&lt;detail::compare_coefs&lt;C1,C2&gt;
                    ::use_c1&gt;());
}
</pre>
<p>The third argument to <i class=
"parameter"><tt>do_subtract</tt></i> ensures that we return a
polynomial of the correct type. Note that if p and q always have
the same number of variables, then the second version of
do_subtract will not be instantiated. Also note that the types of
the first argument in the two versions of <i class=
"parameter"><tt>do_subtract</tt></i> are slightly different: the
first takes a polynomial by value, the second by <tt class=
"literal">const</tt> reference. To see why, examine the bodies of
the two versions.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e352" id="d0e352"></a>Using
<tt class="classname">enable_if</tt></h2>
</div>
<p>The second approach uses <tt class=
"classname">boost::enable_if</tt>, which is based on the SFINAE
[<a href="#enable_if">enable_if</a>] principle. Two versions of
operator - are defined, but only one version is valid:</p>
<pre class="programlisting">
template &lt;typename C1, typename C2&gt;
typename
boost::enable_if_c&lt;detail::compare_coefs
   &lt;C1,C2&gt;::use_c1, polynomial&lt;C1&gt; &gt;::type
operator -(polynomial&lt;C1&gt; p,
  polynomial&lt;C2&gt; const &amp; q)
{
  return p -= q;
}
template &lt;typename C1, typename C2&gt;
typename
boost::disable_if_c&lt;detail::compare_coefs
      &lt;C1,C2&gt;::use_c1, polynomial&lt;C2&gt; &gt;::type
operator-(polynomial&lt;C1&gt; const &amp;p, 
          polynomial&lt;C2&gt; const &amp;q)
{
  return -q += p;
}
</pre>
<p>Suppose <tt class="constant">use_c1</tt> is true. Then in the
second version of <tt class="methodname">operator -</tt>,
<tt class="type">disable_if_c&lt;&hellip;&gt;::type</tt> is
undefined, while in the first version, <tt class=
"type">enable_if_c&lt;&hellip;&gt;::type</tt> is its second
template argument, i.e. <tt class=
"classname">polynomial&lt;C1&gt;</tt>. By SFINAE the second version
is not considered by the compiler when it looks for an appropriate
candidate for <tt class="methodname">operator-=</tt> (because the
return type does not make sense). If <tt class=
"constant">use_c1</tt> is false, then the first version is invalid
and in the second, <tt class=
"type">disable_if_c&lt;&hellip;&gt;::type</tt> is its second
template argument, i.e. <tt class=
"classname">polynomial&lt;C2&gt;</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e396" id="d0e396"></a>Handling
Different Variables</h2>
</div>
<p>We are now ready to consider how to deal with polynomials in
different variables. Before proceeding, note that our
representation of a polynomial implies an ordering of the
variables. The polynomial p= x + y + z, for example, is a
polynomial in z with coefficients that are polynomials in x and y.
These coefficients, in turn, are polynomials in y with coefficients
that are polynomials in x. Of course, we could have used any other
order. (For example, we could represent p as a polynomial in x with
coefficients in y and z.) To the extent possible, our code should
not make assumptions about this order. One assumption we will make,
however, is that if two polynomials p and q appear in an arithmetic
expression, then the ordering of the variables in p and q agree.
For example, suppose p has variables z, x, and w (in this order)
and q has variables z, y and x. The ordering of the variables in q
must have z before x. (The variable y, however, could be first,
second or third.)</p>
<p>Let's look at the implementation of the member function</p>
<pre class="programlisting">
template &lt;typename C&gt;
template &lt;typename C2&gt;
inline polynomial&lt;C&gt; &amp;
polynomial&lt;C&gt;::operator -= 
        (polynomial&lt;C2&gt; const &amp; q) {
  //. . .
  return *this;
}
</pre>
<p>If the variables of q are a subset of the variables of p, then
computing p-=q is straightforward. We can relax this requirement
somewhat: if q is not constant with respect to some variable, then
that variable must be a variable of p. If, as in the last
paragraph, p has variables z, x and w and q has variables z, y and
x, then q must be constant in y (i.e. no term of q contains a
non-zero power of y).</p>
<p>Now, there are two ways to handle the case where p and q have
different variables. In the first case, we assume that what must be
true is true:</p>
<pre class="programlisting">
template &lt;typename C&gt;
template &lt;typename C2&gt;
inline polynomial&lt;C&gt; &amp;
polynomial&lt;C&gt;::operator -= (polynomial&lt;C2&gt; const &amp; q) {
  //Compute p -= q
  if (this-&gt;first_variable() == 
      q.first_variable()) {
    //subtract two polys in same (first) 
    //variable:
    // . . .
  }
  else if (q.is_constant_in_first_variable())
    *this -= q[0];
  else {
    (*this)[0] -= q;
  }
  return *this;
}
</pre>
<p>Some explanation is in order. Let's suppose that the first
variable of q is z. The method <tt class=
"methodname">first_variable</tt>, returns a name, so <tt class=
"methodname">q.first_variable()</tt> returns 'z'. The expression
<tt class="literal">q[n]</tt> is the coefficient of the
n<sup>th</sup> power of z (because z is the first variable of q),
so q[0] is the constant part (with respect to z) of q. If q is
constant in z, then q and q[0] are the same polynomial, so
<tt class="literal">*this -= q[0]</tt> makes sense in the middle
branch.</p>
<p>The last branch is more subtle. Since q is not constant in its
first variable z, the variable z must be a variable of p, for
otherwise this subtraction must fail. But p and q do not have the
same first variable, so the first variable of p is not a variable
of q. (It is here that we are using the assumption that the order
of the variables of p and q are compatible, as described above.) In
short, the subtraction will work in this case only if the variables
of q are variables of p[0].</p>
<p>What happens if our assumptions do not hold? That is, what
happens if q is not constant in some variable that is not a
variable of p? The key is to examine the call in the last branch.
If p and q have three variables (e.g. have type <tt class=
"type">poly3_type</tt>), then <tt class="literal">(*this)[0] -=
q</tt> invokes <tt class="methodname">operator -=</tt> with
arguments of types <tt class="type">poly2_type</tt> and <tt class=
"type">poly3_type</tt>, which in turn will invoke <tt class=
"methodname">operator -=</tt> with arguments of types <tt class=
"type">poly1_type</tt> and <tt class="type">poly3_type</tt>. In
this last invocation, <tt class="literal">(*this)[0]</tt> has type
double. In order for this to compile, we need to define something
like the following. (The actual signature is a little more
complicated since the numerical coefficients may have type other
than <tt class="type">double</tt>.)</p>
<pre class="programlisting">
template &lt;typename C&gt; inline
double &amp; operator -= (double &amp; x,
                      const polynomial&lt;C&gt; &amp; q)
{
  if ( ! q.is_constant())
    throw std::domain_error(
        &quot;Different variables in subtraction&quot;);
  x -= q.leading_constant();
  return x;
}
</pre>
<p>Here is where the error is detected. The method <tt class=
"methodname">leading_constant</tt> returns the numerical
coefficient of the first term (i.e. the &quot;leading&quot; term). When q is
constant, this method returns that constant.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e469" id="d0e469"></a>Code
Explosion</h2>
</div>
<p>There is a serious problem with this approach. Even though our
implementation of <tt class="methodname">operator -=</tt> may seem
compact, in fact it forces the instantiation of several versions of
this operator. For example, if p and q both have type <tt class=
"type">poly3_type</tt> (i.e. polynomials in 3 variables), then
fifteen versions of <tt class="methodname">operator -=</tt> are
instantiated. For example, the statement</p>
<pre class="programlisting">
(*this)[0] -= q;
</pre>
<p>means that <tt class="methodname">operator -=</tt> is
instantiated for arguments of types <tt class=
"type">poly2_type</tt> and <tt class="type">poly3_type</tt>. We saw
above that the statement</p>
<pre class="programlisting">
*this -= q[0];
</pre>
<p>invokes <tt class="type">operator -=</tt> with arguments of
types <tt class="type">poly3_type</tt> and <tt class=
"type">poly2_type</tt>. In short, we have every pair of arguments
of polynomial type with 0 to 3 variables (except 0 and 0, i.e.
<tt class="methodname">double operator-=(double,double)</tt>.) All
of this for just one of the basic arithmetic operators to handle
cases that may never arise!</p>
<p>There is a remedy for this combinatorial explosion of code. We
are requiring that the result of p -= q be a polynomial with the
same variables as p. This is possible only if q can be expressed as
a polynomial in the same variables as p. In C++ terms this means
that we can construct a polynomial that equals q mathematically but
has the same type and variables as p:</p>
<pre class="programlisting">
template &lt;typename C&gt;
template &lt;typename C2&gt;
inline polynomial&lt;C&gt; &amp;
polynomial&lt;C&gt;::operator -= (polynomial&lt;C2&gt;
   const &amp; q)
{
  if (first_variable() == q.first_variable())
  {
    //subtract two poly in the same (first)
    //variable: . . .
  }
  else if ( ! q.is_zero()) {
    try {
      polynomial&lt;C&gt; qq(build_variable_list(),
         q);
      //Compute p -= qq . . .
    }
    catch (construction_error const &amp;) {
      throw std::domain_error (
      &quot;Different variables in subtraction&quot;);
    }
  }
  return *this;
}
</pre>
<p>The key element here is in the call to the constructor inside
the try block. The method <tt class=
"methodname">build_variable_list()</tt> returns the variables of
<tt class="literal">*this</tt>. The constructor creates a
polynomial with these variables and then attempts to copy the terms
of q into this polynomial. If q has terms involving nonzero powers
of some other variable, the attempt fails and a <tt class=
"exceptionname">construction_error exception</tt> is thrown. With
this approach we do not get the cascading calls to distinct
versions of <tt class="methodname">operator -=</tt> (assuming that
the user does not try to subtract polynomials of different
types.)</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e530" id=
"d0e530"></a>Conclusion</h2>
</div>
<p>This polynomial class (and two other versions) are available
online at <a href=
"http://www.fordham.edu/mathematics/hastings/polynomialclasses/"
target=
"_top">http://www.fordham.edu/mathematics/hastings/polynomialclasses/</a>.</p>
<p>The class described in this article is called <tt class=
"classname">fixed_poly&lt;C&gt;</tt> to emphasize that the number
of variables is fixed at compile time. It is defined in <tt class=
"filename">FixedPoly.hpp</tt> and is available at this web address.
Also at this address are several other necessary include files and
one source file.</p>
<p>In the next installment, I examine how we can modify the
approach described here to allow the number of variables to vary at
run time.</p>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e548" id="d0e548"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Alexandrescu-" id=
"Alexandrescu-"></a>
<p class="bibliomixed">[Alexandrescu-] Alexandrescu, Andrei and
Herb Sutter <span class="citetitle"><i class="citetitle">C++ Coding
Standards</i></span>, item 65.</p>
</div>
<div class="bibliomixed"><a name="Alexandrescu" id=
"Alexandrescu"></a>
<p class="bibliomixed">[Alexandrescu] Alexandrescu, Andrei
<span class="citetitle"><i class="citetitle">Modern C++
Design</i></span>, pp29ff.</p>
</div>
<div class="bibliomixed"><a name="var_list" id="var_list"></a>
<p class="bibliomixed">[var_list] For details see <span class=
"bibliomisc">http://www.fordham.edu/mathematics/hastings/polynomialclasses/var_list.htm</span></p>
</div>
<div class="bibliomixed"><a name="enable_if" id="enable_if"></a>
<p class="bibliomixed">[enable_if] See <span class=
"bibliomisc">http://www.boost.org/libs/utility/enable_if.html</span></p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e278" href="#d0e278" id=
"ftn.d0e278">1</a>]</sup> This default behaviour is easy to
change.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
