opennurbs_sum.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
00013 //
00015 */
00016 
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018 
00019 ON_Sum::ON_Sum()
00020 {
00021   Begin(0.0);
00022 }
00023 
00024 int ON_Sum::SummandCount() const
00025 {
00026   return m_pos_count + m_neg_count + m_zero_count;
00027 }
00028 
00029 void ON_Sum::Begin( double starting_value )
00030 {
00031   m_sum_err = 0.0;
00032   m_pos_sum = 0.0;
00033   m_neg_sum = 0.0;
00034   m_pos_sum1_count = 0;
00035   m_pos_sum2_count = 0;
00036   m_pos_sum3_count = 0;
00037   m_neg_sum1_count = 0;
00038   m_neg_sum2_count = 0;
00039   m_neg_sum3_count = 0;
00040   m_pos_count = 0;
00041   m_neg_count = 0;
00042   m_zero_count = 0;
00043 
00044   if ( starting_value > 0.0 )
00045   {
00046     m_pos_sum = starting_value;
00047   }
00048   else if ( starting_value < 0.0 )
00049   {
00050     m_neg_sum = starting_value;
00051   }
00052 }
00053 
00054 double ON_Sum::SortAndSum( int count, double* a )
00055 {
00056   // note that the arrays passed to ON_Sum::SortAndSum() are all 
00057   // homogeneous in sign
00058   double s = 0.0;
00059   if ( count > 0 )
00060   {
00061     if ( count >= 2 )
00062     {
00063       ON_SortDoubleArray( ON::quick_sort, a, count );
00064       //double a0 = fabs(a[0]);
00065       //double a1 = fabs(a[count-1]);
00066       m_sum_err += ON_EPSILON*( fabs(a[count-1]) + count*fabs(a[0]) );
00067     }
00068     if ( a[count] < 0.0 )
00069     {
00070       a += count-1;
00071       while (count--)
00072         s += *a--;
00073     }
00074     else
00075     {
00076       while (count--)
00077         s += *a++;
00078     }
00079   }
00080   return s;
00081 }
00082 
00083 void ON_Sum::Plus( double x )
00084 {
00085   if (x > 0.0)
00086   {
00087     m_pos_count++;
00088     m_pos_sum1[m_pos_sum1_count++] = x;
00089     if ( m_pos_sum1_count == sum1_max_count )
00090     {
00091       m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
00092       m_pos_sum1_count = 0;
00093       if ( m_pos_sum2_count == sum2_max_count )
00094       {
00095         m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
00096         m_pos_sum2_count = 0;
00097         if ( m_pos_sum3_count == sum3_max_count )
00098         {
00099           x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
00100           m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
00101           m_pos_sum += x;
00102           m_pos_sum3_count = 0;
00103         }
00104       }
00105     }
00106   }
00107   else if ( x < 0.0 )
00108   {
00109     m_neg_count++;
00110     m_neg_sum1[m_neg_sum1_count++] = x;
00111     if ( m_neg_sum1_count == sum1_max_count )
00112     {
00113       m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
00114       m_neg_sum1_count = 0;
00115       if ( m_neg_sum2_count == sum2_max_count )
00116       {
00117         m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
00118         m_neg_sum2_count = 0;
00119         if ( m_neg_sum3_count == sum3_max_count )
00120         {
00121           x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
00122           m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
00123           m_neg_sum += x;
00124           m_neg_sum3_count = 0;
00125         }
00126       }
00127     }
00128   }
00129   else
00130     m_zero_count++;
00131 }
00132 
00133 
00134 
00135 void ON_Sum::operator=(double x)
00136 {
00137   Begin(x);
00138 }
00139 
00140 void ON_Sum::operator+=(double x)
00141 {
00142   Plus(x);
00143 }
00144 
00145 void ON_Sum::operator-=(double x)
00146 {
00147   Plus(-x);
00148 }
00149 
00150 
00151 
00152 double ON_Sum::Total( double* error_estimate )
00153 {
00154   double x;
00155   if ( m_pos_sum1_count > 0 )
00156   {
00157     m_pos_sum2[m_pos_sum2_count++] = SortAndSum( m_pos_sum1_count, m_pos_sum1 );
00158     m_pos_sum1_count = 0;
00159   }
00160   if ( m_pos_sum2_count > 0 )
00161   {
00162     m_pos_sum3[m_pos_sum3_count++] = SortAndSum( m_pos_sum2_count, m_pos_sum2 );
00163     m_pos_sum2_count = 0;
00164   }
00165   if ( m_pos_sum3_count > 0 )
00166   {
00167     x = SortAndSum( m_pos_sum3_count, m_pos_sum3 );
00168     m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_pos_sum) );
00169     m_pos_sum += x;
00170     m_pos_sum3_count = 0;
00171   }
00172 
00173   if ( m_neg_sum1_count > 0 )
00174   {
00175     m_neg_sum2[m_neg_sum2_count++] = SortAndSum( m_neg_sum1_count, m_neg_sum1 );
00176     m_neg_sum1_count = 0;
00177   }
00178   if ( m_neg_sum2_count > 0 )
00179   {
00180     m_neg_sum3[m_neg_sum3_count++] = SortAndSum( m_neg_sum2_count, m_neg_sum2 );
00181     m_neg_sum2_count = 0;
00182   }
00183   if ( m_neg_sum3_count > 0 )
00184   {
00185     x = SortAndSum( m_neg_sum3_count, m_neg_sum3 );
00186     m_sum_err += ON_EPSILON*( fabs(x) + fabs(m_neg_sum) );
00187     m_neg_sum += x;
00188     m_neg_sum3_count = 0;
00189   }
00190 
00191   if ( error_estimate )
00192   {
00193     *error_estimate = m_sum_err + ON_EPSILON*(fabs(m_pos_sum) + fabs(m_neg_sum));
00194   }
00195 
00196   return m_pos_sum + m_neg_sum;
00197 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:03