bounds_aux.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef BOUNDS_AUX_H
00033 #define BOUNDS_AUX_H
00034
00035 #include "fastlib/fastlib.h"
00036
00037
00038 namespace bounds_aux {
00039
00040 template<int t_pow>
00041 void MaxDistanceSq(const DHrectBound<t_pow> &bound1,
00042 const DHrectBound<t_pow> &bound2,
00043 Vector &furthest_point_in_bound1,
00044 double &furthest_dsqd) {
00045
00046 int dim = furthest_point_in_bound1.length();
00047 furthest_dsqd = 0;
00048
00049 for (index_t d = 0; d < dim; d++) {
00050
00051 const DRange &bound1_range = bound1.get(d);
00052 const DRange &bound2_range = bound2.get(d);
00053
00054 double v1 = bound2_range.hi - bound1_range.lo;
00055 double v2 = bound1_range.hi - bound2_range.lo;
00056 double v;
00057
00058 if(v1 > v2) {
00059 furthest_point_in_bound1[d] = bound1_range.lo;
00060 v = v1;
00061 }
00062 else {
00063 furthest_point_in_bound1[d] = bound1_range.hi;
00064 v = v2;
00065 }
00066 furthest_dsqd += math::PowAbs<t_pow, 1>(v);
00067 }
00068 furthest_dsqd = math::Pow<2, t_pow>(furthest_dsqd);
00069 }
00070
00071 template<int t_pow>
00072 void MaxDistanceSq(const DHrectBound<t_pow> &bound1,
00073 Vector &bound2_centroid,
00074 Vector &furthest_point_in_bound1,
00075 double &furthest_dsqd) {
00076
00077 int dim = furthest_point_in_bound1.length();
00078 furthest_dsqd = 0;
00079
00080 for (index_t d = 0; d < dim; d++) {
00081
00082 const DRange &bound1_range = bound1.get(d);
00083
00084 double v1 = bound2_centroid[d] - bound1_range.lo;
00085 double v2 = bound1_range.hi - bound2_centroid[d];
00086 double v;
00087
00088 if(v1 > v2) {
00089 furthest_point_in_bound1[d] = bound1_range.lo;
00090 v = v1;
00091 }
00092 else {
00093 furthest_point_in_bound1[d] = bound1_range.hi;
00094 v = v2;
00095 }
00096 furthest_dsqd += math::PowAbs<t_pow, 1>(v);
00097 }
00098 furthest_dsqd = math::Pow<2, t_pow>(furthest_dsqd);
00099 }
00100
00101 template<int t_pow, typename TVector>
00102 void MaxDistanceSq(const DBallBound < LMetric<t_pow>, TVector > &bound1,
00103 Vector &bound2_centroid,
00104 Vector &furthest_point_in_bound1,
00105 double &furthest_dsqd) {
00106
00107 furthest_dsqd = 0;
00108
00109
00110
00111 double distance =
00112 LMetric<t_pow>::Distance(bound1.center(), bound2_centroid);
00113
00114
00115
00116
00117 Vector unit_vector;
00118 la::SubInit(bound2_centroid, bound1.center(), &unit_vector);
00119 la::Scale(1.0 / distance, &unit_vector);
00120
00121 furthest_point_in_bound1.CopyValues(bound1.center());
00122 la::AddExpert(bound1.radius(), unit_vector, &furthest_point_in_bound1);
00123
00124 furthest_dsqd = math::Pow<2, t_pow>
00125 (la::RawLMetric<t_pow>(bound2_centroid.length(),
00126 furthest_point_in_bound1.ptr(),
00127 bound2_centroid.ptr()));
00128 }
00129
00134 template<int t_pow, typename TVector>
00135 double MaxSideLengthOfBoundingBox
00136 (const DBallBound < LMetric<t_pow>, TVector > &ball_bound) {
00137 return ball_bound.radius() * 2;
00138 }
00139
00144 template<int t_pow>
00145 double MaxSideLengthOfBoundingBox(const DHrectBound<t_pow> &bound) {
00146
00147 double max_length = 0;
00148
00149 for(index_t d = 0; d < bound.dim(); d++) {
00150 const DRange &range = bound.get(d);
00151 max_length = std::max(max_length, range.width());
00152 }
00153 return max_length;
00154 }
00155
00159 template<int t_pow, typename TVector>
00160 double MaxL1Distance
00161 (const DBallBound < LMetric<t_pow>, TVector > &ball_bound1,
00162 const DBallBound < LMetric<t_pow>, TVector > &ball_bound2,
00163 int *dimension) {
00164
00165 const Vector ¢er1 = ball_bound1.center();
00166 const Vector ¢er2 = ball_bound2.center();
00167 int dim = ball_bound1.center().length();
00168 double l1_distance = 0;
00169 for(index_t d = 0; d < dim; d++) {
00170 l1_distance += fabs(center1[d] - center2[d]);
00171 }
00172 l1_distance += ball_bound1.radius() + ball_bound2.radius();
00173 *dimension = center1.length();
00174 return l1_distance;
00175 }
00176
00180 template<int t_pow>
00181 double MaxL1Distance(const DHrectBound<t_pow> &bound1,
00182 const DHrectBound<t_pow> &bound2, int *dimension) {
00183
00184 double farthest_distance_manhattan = 0;
00185 for(index_t d = 0; d < bound1.dim(); d++) {
00186 const DRange &range1 = bound1.get(d);
00187 const DRange &range2 = bound2.get(d);
00188 double bound1_centroid_coord = range1.lo + range1.width() / 2;
00189
00190 farthest_distance_manhattan =
00191 max(farthest_distance_manhattan,
00192 max(fabs(bound1_centroid_coord - range2.lo),
00193 fabs(bound1_centroid_coord - range2.hi)));
00194 }
00195 *dimension = bound1.dim();
00196 return farthest_distance_manhattan;
00197 }
00198
00201 static int qsort_compar_(const void *a, const void *b) {
00202
00203 index_t a_dereferenced = *((index_t *) a);
00204 index_t b_dereferenced = *((index_t *) b);
00205
00206 if(a_dereferenced < b_dereferenced) {
00207 return -1;
00208 }
00209 else if(a_dereferenced > b_dereferenced) {
00210 return 1;
00211 }
00212 else {
00213 return 0;
00214 }
00215 }
00216
00217 double RandomizedDistanceSqEuclidean(index_t length, const double *a,
00218 const double *b) {
00219
00220 int num_samples = (int) sqrt(length);
00221 double sample_mean = 0;
00222 ArrayList<index_t> dimension_indices;
00223 dimension_indices.Init(num_samples);
00224 for(index_t i = 0; i < num_samples; i++) {
00225 dimension_indices[i] = math::RandInt(0, length);
00226 }
00227 qsort(dimension_indices.begin(), num_samples, sizeof(index_t),
00228 &qsort_compar_);
00229
00230 for(index_t i = 0; i < num_samples; i++) {
00231 sample_mean += math::Sqr(a[dimension_indices[i]] -
00232 b[dimension_indices[i]]);
00233 }
00234
00235 sample_mean /= ((double) num_samples);
00236 return sample_mean * length;
00237 }
00238
00239 };
00240
00241 #endif