]> git.donarmstrong.com Git - lilypond.git/blobdiff - flower/polynomial.cc
Web-ja: update introduction
[lilypond.git] / flower / polynomial.cc
index 2cd0eaf2e07912f566c837413091b56f02c7114f..ec8605058c2bcdb0ce4c1ea5889d1463a882f434 100644 (file)
@@ -1,7 +1,7 @@
 /*
   This file is part of LilyPond, the GNU music typesetter.
 
-  Copyright (C) 1993--2011 Han-Wen Nienhuys <hanwen@xs4all.nl>
+  Copyright (C) 1993--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
 
   LilyPond is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -49,11 +49,11 @@ Polynomial::multiply (const Polynomial &p1, const Polynomial &p2)
 {
   Polynomial dest;
 
-  int deg = p1.degree () + p2.degree ();
-  for (int i = 0; i <= deg; i++)
+  ssize_t deg = p1.degree () + p2.degree ();
+  for (ssize_t i = 0; i <= deg; i++)
     {
       dest.coefs_.push_back (0);
-      for (int j = 0; j <= i; j++)
+      for (ssize_t j = 0; j <= i; j++)
         if (i - j <= p2.degree () && j <= p1.degree ())
           dest.coefs_.back () += p1.coefs_[j] * p2.coefs_[i - j];
     }
@@ -61,6 +61,32 @@ Polynomial::multiply (const Polynomial &p1, const Polynomial &p2)
   return dest;
 }
 
+Real
+Polynomial::minmax (Real l, Real r, bool ret_max) const
+{
+  vector<Real> sols;
+  if (l > r)
+    {
+      programming_error ("left bound greater than right bound for polynomial minmax.  flipping bounds.");
+      l = l + r;
+      r = l - r;
+      l = l - r;
+    }
+
+  sols.push_back (eval (l));
+  sols.push_back (eval (r));
+
+  Polynomial deriv (*this);
+  deriv.differentiate ();
+  vector<Real> maxmins = deriv.solve ();
+  for (vsize i = 0; i < maxmins.size (); i++)
+    if (maxmins[i] >= l && maxmins[i] <= r)
+      sols.push_back (eval (maxmins[i]));
+  vector_sort (sols, less<Real> ());
+
+  return ret_max ? sols.back () : sols[0];
+}
+
 void
 Polynomial::differentiate ()
 {
@@ -151,22 +177,22 @@ Polynomial::set_mod (const Polynomial &u, const Polynomial &v)
 
   if (v.lc () < 0.0)
     {
-      for (int k = u.degree () - v.degree () - 1; k >= 0; k -= 2)
+      for (ssize_t k = u.degree () - v.degree () - 1; k >= 0; k -= 2)
         coefs_[k] = -coefs_[k];
 
-      for (int k = u.degree () - v.degree (); k >= 0; k--)
-        for (int j = v.degree () + k - 1; j >= k; j--)
+      for (ssize_t k = u.degree () - v.degree (); k >= 0; k--)
+        for (ssize_t j = v.degree () + k - 1; j >= k; j--)
           coefs_[j] = -coefs_[j] - coefs_[v.degree () + k] * v.coefs_[j - k];
     }
   else
 
     {
-      for (int k = u.degree () - v.degree (); k >= 0; k--)
-        for (int j = v.degree () + k - 1; j >= k; j--)
+      for (ssize_t k = u.degree () - v.degree (); k >= 0; k--)
+        for (ssize_t j = v.degree () + k - 1; j >= k; j--)
           coefs_[j] -= coefs_[v.degree () + k] * v.coefs_[j - k];
     }
 
-  int k = v.degree () - 1;
+  ssize_t k = v.degree () - 1;
   while (k >= 0 && coefs_[k] == 0.0)
     k--;
 
@@ -302,7 +328,7 @@ Polynomial::lc ()
   return coefs_.back ();
 }
 
-int
+ssize_t
 Polynomial::degree ()const
 {
   return coefs_.size () - 1;