00001 #ifndef INDII_ML_AUX_PNORM_HPP
00002 #define INDII_ML_AUX_PNORM_HPP
00003
00004 #include "Norm.hpp"
00005
00006 namespace indii {
00007 namespace ml {
00008 namespace aux {
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 template <unsigned int P>
00019 class PNorm : public Norm {
00020 public:
00021
00022
00023
00024 virtual ~PNorm();
00025
00026 virtual double operator()(const vector& x) const;
00027
00028 virtual vector sample(const unsigned int N) const;
00029
00030 private:
00031
00032
00033
00034 template<class Archive>
00035 void serialize(Archive& ar, const unsigned int version);
00036
00037
00038
00039
00040 friend class boost::serialization::access;
00041
00042 };
00043
00044 template<>
00045 vector PNorm<2>::sample(const unsigned int N) const;
00046
00047 }
00048 }
00049 }
00050
00051 #include "Random.hpp"
00052 #include "vector.hpp"
00053
00054 #include <set>
00055
00056 using namespace indii::ml::aux;
00057
00058 template<unsigned int P>
00059 indii::ml::aux::PNorm<P>::~PNorm() {
00060
00061 }
00062
00063 template<unsigned int P>
00064 inline double indii::ml::aux::PNorm<P>::operator()(const vector& x)
00065 const {
00066 return norm<P,vector>(x);
00067 }
00068
00069 template<>
00070 indii::ml::aux::vector indii::ml::aux::PNorm<2>::sample(
00071 const unsigned int N) const {
00072 return Random::unitVector(N);
00073 }
00074
00075 template<unsigned int P>
00076 indii::ml::aux::vector indii::ml::aux::PNorm<P>::sample(
00077 const unsigned int N) const {
00078 unsigned int i;
00079 std::multiset<double> u;
00080 std::multiset<double>::iterator iter, end;
00081 vector x(N);
00082
00083
00084 for (i = 0; i < N - 1; i++) {
00085 u.insert(Random::uniform(0.0, 1.0));
00086 }
00087
00088
00089 if (!u.empty()) {
00090 iter = u.begin();
00091 end = u.end();
00092 x(0) = *iter;
00093 iter++;
00094 for (i = 1; iter != end; iter++, i++) {
00095 x(i) = *iter - x(i - 1);
00096 }
00097 x(N - 1) = 1.0 - x(N - 2);
00098 } else {
00099 x(0) = 1.0;
00100 }
00101
00102
00103
00104 for (i = 0; i < N; i++) {
00105 x(i) = pow(x(i), 1.0 / P);
00106 if (Random::bernoulli() == 0) {
00107 x(i) *= -1.0;
00108 }
00109 }
00110
00111 return x;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 }
00136
00137 template<unsigned int P>
00138 template<class Archive>
00139 void indii::ml::aux::PNorm<P>::serialize(Archive& ar,
00140 const unsigned int version) {
00141 ar & boost::serialization::base_object<Norm>(*this);
00142 }
00143
00144 #endif
00145