@@ -2671,8 +2671,8 @@ namespace detail {
2671
2671
XTL_REQUIRES (is_reducer_options<EVS>)>
2672
2672
inline auto nanvar(E&& e, EVS es = EVS())
2673
2673
{
2674
- decltype ( auto ) sc = detail::shared_forward<E >(e);
2675
- return nanmean<T>(square (sc - nanmean<T>(sc )), es);
2674
+ auto cached_mean = nanmean<T >(e, es)( );
2675
+ return nanmean<T>(square (std::forward<E>(e) - std::move (cached_mean )), es);
2676
2676
}
2677
2677
2678
2678
template <class T = void , class E , class EVS = DEFAULT_STRATEGY_REDUCERS,
@@ -2709,7 +2709,8 @@ namespace detail {
2709
2709
// note: forcing copy of first axes argument -- is there a better solution?
2710
2710
auto axes_copy = axes;
2711
2711
using result_type = typename std::conditional_t <std::is_same<T, void >::value, double , T>;
2712
- auto inner_mean = nanmean<result_type>(sc, std::move (axes_copy));
2712
+ // always eval to prevent repeated evaluations in the next calls
2713
+ auto inner_mean = eval (nanmean<result_type>(sc, std::move (axes_copy)));
2713
2714
2714
2715
// fake keep_dims = 1
2715
2716
auto keep_dim_shape = e.shape ();
@@ -2718,7 +2719,9 @@ namespace detail {
2718
2719
keep_dim_shape[el] = 1 ;
2719
2720
}
2720
2721
auto mrv = reshape_view<XTENSOR_DEFAULT_LAYOUT>(std::move (inner_mean), std::move (keep_dim_shape));
2721
- return nanmean<result_type>(square (cast<result_type>(sc) - std::move (mrv)), std::forward<X>(axes), es);
2722
+ // note: otherwise the result is wrong with 'immediate' evaluation strategy
2723
+ auto sc_shifted = eval (cast<result_type>(sc) - std::move (mrv));
2724
+ return nanmean<result_type>(square (sc_shifted), std::forward<X>(axes), es);
2722
2725
}
2723
2726
2724
2727
/* *
0 commit comments