1 #ifndef _theplu_yat_normalizer_qquantile_normalizer_
2 #define _theplu_yat_normalizer_qquantile_normalizer_
26 #include "yat/regression/CSplineInterpolation.h"
27 #include "yat/utility/concept_check.h"
28 #include "yat/utility/DataIterator.h"
29 #include "yat/utility/DataWeight.h"
30 #include "yat/utility/Exception.h"
31 #include "yat/utility/iterator_traits.h"
32 #include "yat/utility/sort_index.h"
33 #include "yat/utility/Vector.h"
34 #include "yat/utility/WeightIterator.h"
35 #include "yat/utility/yat_assert.h"
37 #include <boost/concept_check.hpp>
52 namespace normalizer {
117 template<
typename ForwardIterator>
143 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
144 void operator()(RandomAccessIterator1 first, RandomAccessIterator1 last,
145 RandomAccessIterator2 result)
const;
164 template<
typename ForwardIterator>
165 Partitioner(ForwardIterator first, ForwardIterator last,
193 size_t size(
void)
const;
197 template<
typename ForwardIterator>
198 void build(ForwardIterator first, ForwardIterator last,
unsigned int N,
201 template<
typename ForwardIterator>
202 void build(ForwardIterator first, ForwardIterator last,
unsigned int N,
205 void init(
const std::vector<utility::DataWeight>&,
unsigned int N);
214 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
215 void normalize(
const Partitioner& source,RandomAccessIterator1 first,
216 RandomAccessIterator1 last, RandomAccessIterator2 result,
220 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
221 void normalize(
const Partitioner& source,RandomAccessIterator1 first,
222 RandomAccessIterator1 last, RandomAccessIterator2 result,
229 template<
typename ForwardIterator>
231 ForwardIterator last,
233 : target_(Partitioner(first, last, Q))
239 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
241 RandomAccessIterator1 last,
242 RandomAccessIterator2 result)
const
245 using boost_concepts::RandomAccessTraversal;
246 BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIterator1>));
248 BOOST_CONCEPT_ASSERT((RandomAccessTraversal<RandomAccessIterator2>));
249 using boost_concepts::WritableIterator;
250 BOOST_CONCEPT_ASSERT((WritableIterator<RandomAccessIterator2>));
252 Partitioner source(first, last, target_.size());
254 normalize(source, first, last, result, tag);
258 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
260 qQuantileNormalizer::normalize(
const qQuantileNormalizer::Partitioner& source,
261 RandomAccessIterator1 first,
262 RandomAccessIterator1 last,
263 RandomAccessIterator2 result,
268 size_t N = last-first;
269 YAT_ASSERT(N >= target_.size());
271 std::vector<size_t> sorted_index(last-first);
275 diff-=target_.averages();
282 size_t end =
static_cast<size_t>(std::ceil(N*idx(0) - 0.5));
287 for (
size_t i=start; i<end; ++i) {
288 size_t si = sorted_index[i];
289 result[si] = first[si] - diff(0);
292 using utility::yat_assert;
297 end =
static_cast<size_t>(std::ceil(N*idx(idx.
size()-1) - 0.5));
300 for (
size_t i=start; i<end; ++i) {
301 size_t si = sorted_index[i];
303 YAT_ASSERT((i+0.5)/N>idx(0));
304 result[si] = first[si] - cspline.evaluate((i+0.5)/N);
309 for (
size_t i=end ; i<N; ++i) {
310 size_t si = sorted_index[i];
311 result[si] = first[si] - diff(diff.size()-1);
316 template<
typename RandomAccessIterator1,
typename RandomAccessIterator2>
317 void qQuantileNormalizer::normalize(
const Partitioner& source,
318 RandomAccessIterator1 first,
319 RandomAccessIterator1 last,
320 RandomAccessIterator2 result,
321 utility::weighted_iterator_tag tag)
const
324 detail::copy_weight_if_weighted(first, last, result);
326 double total_w = std::accumulate(utility::weight_iterator(first),
327 utility::weight_iterator(last), 0.0);
329 std::vector<size_t> sorted_index(last-first);
335 using namespace utility;
336 std::vector<double> vec;
337 vec.reserve(std::distance(first, last));
338 std::copy(utility::data_iterator(first), utility::data_iterator(last),
339 std::back_inserter(vec));
340 for (std::vector<double>::iterator i(vec.begin()); i!=vec.end(); ++i)
342 *i = std::numeric_limits<double>::infinity();
347 utility::Vector diff(source.averages());
348 diff-=target_.averages();
349 const utility::Vector& idx=target_.quantiles();
350 regression::CSplineInterpolation cspline(idx,diff);
353 utility::iterator_traits<RandomAccessIterator1> traits1;
354 utility::iterator_traits<RandomAccessIterator2> traits2;
355 for (
size_t i=0; i<sorted_index.size(); ++i) {
356 size_t si = sorted_index[i];
357 double w = (sum_w + 0.5*traits1.weight(first+si))/total_w;
358 double correction = 0;
362 correction = diff(0);
364 else if (w < idx(idx.size()-1) ) {
367 correction = cspline.evaluate(w);
372 correction = diff(diff.size()-1);
374 traits2.data(result+si) = traits1.data(first+si) - correction;
375 sum_w += traits1.weight(first+si);
380 template<
typename ForwardIterator>
381 qQuantileNormalizer::Partitioner::Partitioner(ForwardIterator first,
382 ForwardIterator last,
384 : average_(utility::Vector(N)), quantiles_(utility::Vector(N))
386 BOOST_CONCEPT_ASSERT((boost_concepts::ForwardTraversal<ForwardIterator>));
387 BOOST_CONCEPT_ASSERT((utility::DataIterator<ForwardIterator>));
388 build(first, last, N,
389 typename utility::weighted_iterator_traits<ForwardIterator>::type());
393 template<
typename ForwardIterator>
394 void qQuantileNormalizer::Partitioner::build(ForwardIterator first,
395 ForwardIterator last,
397 utility::unweighted_iterator_tag)
399 utility::Vector vec(std::distance(first, last));
400 std::copy(first, last, vec.begin());
401 std::sort(vec.begin(), vec.end());
406 template<
typename ForwardIterator>
407 void qQuantileNormalizer::Partitioner::build(ForwardIterator first,
408 ForwardIterator last,
410 utility::weighted_iterator_tag)
412 using namespace utility;
413 std::vector<DataWeight> vec(first, last);
414 std::sort(vec.begin(), vec.end());
Perform Q-quantile normalization.
Definition: qQuantileNormalizer.h:88
Cubic spline with natural boundary conditions.
Definition: CSplineInterpolation.h:47
Definition: iterator_traits.h:47
void operator()(RandomAccessIterator1 first, RandomAccessIterator1 last, RandomAccessIterator2 result) const
Perform the Q-quantile normalization.
Definition: qQuantileNormalizer.h:240
Definition: iterator_traits.h:55
DataIterator.
Definition: DataIterator.h:63
This is the yat interface to GSL vector.
Definition: Vector.h:57
qQuantileNormalizer(ForwardIterator first, ForwardIterator last, unsigned int Q)
Constructor.
Definition: qQuantileNormalizer.h:230
This is the yat interface to GSL vector.
Definition: VectorBase.h:52
void check_iterator_is_unweighted(Iter iter)
check (at compile time) that iterator is unweighted.
Definition: iterator_traits.h:200
void sort_index(InputIterator first, InputIterator last, std::vector< size_t > &sort_index)
Definition: sort_index.h:146
detail::unweighted_type_and< w_type1, w_type2 >::type type
return unweighted if both are unweighted
Definition: iterator_traits.h:165