Skip to content

Commit 2fc17d5

Browse files
authored
Merge pull request #22 from dcdillon/feature/more-functions
Added cumsum and friends
2 parents f51899f + f11b403 commit 2fc17d5

5 files changed

Lines changed: 458 additions & 1 deletion

File tree

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@
44
^doxygen.*$
55
^Doxyfile$
66
^README.md$
7+
^src/Makevars\.R_STRIP_LINKER_OPTION\.bak$

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ src/*.o
66
src/*.so
77
src/*.dll
88
src/symbols.rds
9-
src/Makevars
9+
src/Makevars.R_STRIP_LINKER_OPTION.bak

inst/include/RcppHoney/functions.hpp

Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,386 @@ diff(const T &rhs) {
301301
functors::diff< typename hook< T >::const_iterator, hook< T >::NA >());
302302
}
303303

304+
template< typename T, typename T_ITER, typename T_RESULT >
305+
Rcpp::Vector< rtype< T_RESULT >::value > cumsum(
306+
const operand< T, T_ITER, T_RESULT > &val) {
307+
308+
T_RESULT previous = 0;
309+
310+
const dims_t dims = hooks::extract_dims(val);
311+
uint64_t size = 0;
312+
313+
if (dims.second == 0) {
314+
size = dims.first;
315+
} else {
316+
size = dims.first * dims.second;
317+
}
318+
319+
typename Rcpp::Vector< rtype< T_RESULT >::value > vec(size);
320+
321+
typename operand< T, T_ITER, T_RESULT >::const_iterator i = val.begin();
322+
typename operand< T, T_ITER, T_RESULT >::const_iterator iend = val.end();
323+
typename Rcpp::Vector< rtype< T_RESULT >::value >::iterator current
324+
= vec.begin();
325+
326+
for ( ; i != iend; ++i, ++current)
327+
{
328+
const T_RESULT value = *i;
329+
330+
if (na< typename traits::ctype< T_RESULT >::type >::is_na(value)
331+
|| na< typename traits::ctype< T_RESULT >::type >::is_na(
332+
previous)) {
333+
previous = na< T_RESULT >::VALUE();
334+
} else {
335+
previous += value;
336+
}
337+
338+
*current = previous;
339+
}
340+
341+
return vec;
342+
}
343+
344+
template< typename T, typename T_ITER, typename T_RESULT >
345+
Rcpp::Vector< rtype< T_RESULT >::value > cumprod(
346+
const operand< T, T_ITER, T_RESULT > &val) {
347+
348+
T_RESULT previous = 1;
349+
350+
const dims_t dims = hooks::extract_dims(val);
351+
uint64_t size = 0;
352+
353+
if (dims.second == 0) {
354+
size = dims.first;
355+
} else {
356+
size = dims.first * dims.second;
357+
}
358+
359+
typename Rcpp::Vector< rtype< T_RESULT >::value > vec(size);
360+
361+
typename operand< T, T_ITER, T_RESULT >::const_iterator i = val.begin();
362+
typename operand< T, T_ITER, T_RESULT >::const_iterator iend = val.end();
363+
typename Rcpp::Vector< rtype< T_RESULT >::value >::iterator current
364+
= vec.begin();
365+
366+
for ( ; i != iend; ++i, ++current)
367+
{
368+
const T_RESULT value = *i;
369+
370+
if (na< typename traits::ctype< T_RESULT >::type >::is_na(value)
371+
|| na< typename traits::ctype< T_RESULT >::type >::is_na(
372+
previous)) {
373+
previous = na< T_RESULT >::VALUE();
374+
} else {
375+
previous *= value;
376+
}
377+
378+
*current = previous;
379+
}
380+
381+
return vec;
382+
}
383+
384+
template< typename T, typename T_ITER, typename T_RESULT >
385+
Rcpp::Vector< rtype< T_RESULT >::value > cummin(
386+
const operand< T, T_ITER, T_RESULT > &val) {
387+
388+
T_RESULT previous = std::numeric_limits< T_RESULT >::max();
389+
390+
const dims_t dims = hooks::extract_dims(val);
391+
uint64_t size = 0;
392+
393+
if (dims.second == 0) {
394+
size = dims.first;
395+
} else {
396+
size = dims.first * dims.second;
397+
}
398+
399+
typename Rcpp::Vector< rtype< T_RESULT >::value > vec(size);
400+
401+
typename operand< T, T_ITER, T_RESULT >::const_iterator i = val.begin();
402+
typename operand< T, T_ITER, T_RESULT >::const_iterator iend = val.end();
403+
typename Rcpp::Vector< rtype< T_RESULT >::value >::iterator current
404+
= vec.begin();
405+
406+
for ( ; i != iend; ++i, ++current)
407+
{
408+
const T_RESULT value = *i;
409+
410+
if (na< typename traits::ctype< T_RESULT >::type >::is_na(value)
411+
|| na< typename traits::ctype< T_RESULT >::type >::is_na(
412+
previous)) {
413+
previous = na< T_RESULT >::VALUE();
414+
} else {
415+
previous = std::min(previous, value);
416+
}
417+
418+
*current = previous;
419+
}
420+
421+
return vec;
422+
}
423+
424+
template< typename T, typename T_ITER, typename T_RESULT >
425+
Rcpp::Vector< rtype< T_RESULT >::value > cummax(
426+
const operand< T, T_ITER, T_RESULT > &val) {
427+
428+
T_RESULT previous;
429+
430+
if (std::numeric_limits< T_RESULT >::is_integer) {
431+
previous = std::numeric_limits< T_RESULT >::min() + 1;
432+
} else {
433+
previous = -std::numeric_limits< T_RESULT >::max();
434+
}
435+
436+
const dims_t dims = hooks::extract_dims(val);
437+
uint64_t size = 0;
438+
439+
if (dims.second == 0) {
440+
size = dims.first;
441+
} else {
442+
size = dims.first * dims.second;
443+
}
444+
445+
typename Rcpp::Vector< rtype< T_RESULT >::value > vec(size);
446+
447+
typename operand< T, T_ITER, T_RESULT >::const_iterator i = val.begin();
448+
typename operand< T, T_ITER, T_RESULT >::const_iterator iend = val.end();
449+
typename Rcpp::Vector< rtype< T_RESULT >::value >::iterator current
450+
= vec.begin();
451+
452+
for ( ; i != iend; ++i, ++current)
453+
{
454+
const T_RESULT value = *i;
455+
456+
if (na< typename traits::ctype< T_RESULT >::type >::is_na(value)
457+
|| na< typename traits::ctype< T_RESULT >::type >::is_na(
458+
previous)) {
459+
previous = na< T_RESULT >::VALUE();
460+
} else {
461+
previous = std::max(previous, value);
462+
}
463+
464+
*current = previous;
465+
}
466+
467+
return vec;
468+
}
469+
470+
471+
template< typename T >
472+
typename traits::enable_if<
473+
hook< T >::value,
474+
Rcpp::Vector<
475+
rtype<
476+
typename traits::ctype<
477+
typename std::iterator_traits< typename T::iterator >::value_type
478+
>::type
479+
>::value
480+
>
481+
>::type cumsum(const T &val) {
482+
483+
typedef typename traits::ctype<
484+
typename std::iterator_traits< typename T::iterator >::value_type
485+
>::type result_type;
486+
487+
result_type previous = 0;
488+
489+
const dims_t dims = hooks::extract_dims(val);
490+
uint64_t size = 0;
491+
492+
if (dims.second == 0) {
493+
size = dims.first;
494+
} else {
495+
size = dims.first * dims.second;
496+
}
497+
498+
Rcpp::Vector< rtype< result_type >::value > vec(size);
499+
500+
typename T::const_iterator i = val.begin();
501+
typename T::const_iterator iend = val.end();
502+
typename Rcpp::Vector< rtype< result_type >::value >::iterator current
503+
= vec.begin();
504+
505+
for ( ; i != iend; ++i, ++current)
506+
{
507+
const result_type value = *i;
508+
509+
if (na< typename traits::ctype< result_type >::type >::is_na(value)
510+
|| na< typename traits::ctype< result_type >::type >::is_na(
511+
previous)) {
512+
previous = na< result_type >::VALUE();
513+
} else {
514+
previous += value;
515+
}
516+
517+
*current = previous;
518+
}
519+
520+
return vec;
521+
}
522+
523+
template< typename T >
524+
typename traits::enable_if<
525+
hook< T >::value,
526+
Rcpp::Vector<
527+
rtype<
528+
typename traits::ctype<
529+
typename std::iterator_traits< typename T::iterator >::value_type
530+
>::type
531+
>::value
532+
>
533+
>::type cumprod(const T &val) {
534+
535+
typedef typename traits::ctype<
536+
typename std::iterator_traits< typename T::iterator >::value_type
537+
>::type result_type;
538+
539+
result_type previous = 1;
540+
541+
const dims_t dims = hooks::extract_dims(val);
542+
uint64_t size = 0;
543+
544+
if (dims.second == 0) {
545+
size = dims.first;
546+
} else {
547+
size = dims.first * dims.second;
548+
}
549+
550+
Rcpp::Vector< rtype< result_type >::value > vec(size);
551+
552+
typename T::const_iterator i = val.begin();
553+
typename T::const_iterator iend = val.end();
554+
typename Rcpp::Vector< rtype< result_type >::value >::iterator current
555+
= vec.begin();
556+
557+
for ( ; i != iend; ++i, ++current)
558+
{
559+
const result_type value = *i;
560+
561+
if (na< typename traits::ctype< result_type >::type >::is_na(value)
562+
|| na< typename traits::ctype< result_type >::type >::is_na(
563+
previous)) {
564+
previous = na< result_type >::VALUE();
565+
} else {
566+
previous *= value;
567+
}
568+
569+
*current = previous;
570+
}
571+
572+
return vec;
573+
}
574+
575+
template< typename T >
576+
typename traits::enable_if<
577+
hook< T >::value,
578+
Rcpp::Vector<
579+
rtype<
580+
typename traits::ctype<
581+
typename std::iterator_traits< typename T::iterator >::value_type
582+
>::type
583+
>::value
584+
>
585+
>::type cummin(const T &val) {
586+
587+
typedef typename traits::ctype<
588+
typename std::iterator_traits< typename T::iterator >::value_type
589+
>::type result_type;
590+
591+
result_type previous = std::numeric_limits< result_type >::max();
592+
593+
const dims_t dims = hooks::extract_dims(val);
594+
uint64_t size = 0;
595+
596+
if (dims.second == 0) {
597+
size = dims.first;
598+
} else {
599+
size = dims.first * dims.second;
600+
}
601+
602+
Rcpp::Vector< rtype< result_type >::value > vec(size);
603+
604+
typename T::const_iterator i = val.begin();
605+
typename T::const_iterator iend = val.end();
606+
typename Rcpp::Vector< rtype< result_type >::value >::iterator current
607+
= vec.begin();
608+
609+
for ( ; i != iend; ++i, ++current)
610+
{
611+
const result_type value = *i;
612+
613+
if (na< typename traits::ctype< result_type >::type >::is_na(value)
614+
|| na< typename traits::ctype< result_type >::type >::is_na(
615+
previous)) {
616+
previous = na< result_type >::VALUE();
617+
} else {
618+
previous = std::min(previous, value);
619+
}
620+
621+
*current = previous;
622+
}
623+
624+
return vec;
625+
}
626+
627+
template< typename T >
628+
typename traits::enable_if<
629+
hook< T >::value,
630+
Rcpp::Vector<
631+
rtype<
632+
typename traits::ctype<
633+
typename std::iterator_traits< typename T::iterator >::value_type
634+
>::type
635+
>::value
636+
>
637+
>::type cummax(const T &val) {
638+
639+
typedef typename traits::ctype<
640+
typename std::iterator_traits< typename T::iterator >::value_type
641+
>::type result_type;
642+
643+
result_type previous;
644+
645+
if (std::numeric_limits< result_type >::is_integer) {
646+
previous = std::numeric_limits< result_type >::min() + 1;
647+
} else {
648+
previous = -std::numeric_limits< result_type >::max();
649+
}
650+
651+
const dims_t dims = hooks::extract_dims(val);
652+
uint64_t size = 0;
653+
654+
if (dims.second == 0) {
655+
size = dims.first;
656+
} else {
657+
size = dims.first * dims.second;
658+
}
659+
660+
Rcpp::Vector< rtype< result_type >::value > vec(size);
661+
662+
typename T::const_iterator i = val.begin();
663+
typename T::const_iterator iend = val.end();
664+
typename Rcpp::Vector< rtype< result_type >::value >::iterator current
665+
= vec.begin();
666+
667+
for ( ; i != iend; ++i, ++current)
668+
{
669+
const result_type value = *i;
670+
671+
if (na< typename traits::ctype< result_type >::type >::is_na(value)
672+
|| na< typename traits::ctype< result_type >::type >::is_na(
673+
previous)) {
674+
previous = na< result_type >::VALUE();
675+
} else {
676+
previous = std::max(previous, value);
677+
}
678+
679+
*current = previous;
680+
}
681+
682+
return vec;
683+
}
684+
685+
304686
} // namespace RcppHoney

0 commit comments

Comments
 (0)