Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00057
00058 double s = 0.0;
00059 if ( count > 0 )
00060 {
00061 if ( count >= 2 )
00062 {
00063 ON_SortDoubleArray( ON::quick_sort, a, count );
00064
00065
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 }