Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STL/ranges algorithm to calculate weighted average

Assume I have a vector of grades, where the grade is

struct Grade{
   const int grade;
   const int ECTS; // weight
};

Is there a STL/range-v3 algorithm/algorithms that enable me to do this?

I know I could do it with std:: accumulate with some fancy type as an accumulator(that remembers the sum of weights), but I am looking for a simpler alternative if one exists.

like image 928
NoSenseEtAl Avatar asked Aug 29 '19 15:08

NoSenseEtAl


People also ask

What is the formula for calculating a weighted average?

The formula for finding the weighted average is the sum of all the variables multiplied by their weight, then divided by the sum of the weights.

How do you calculate weighted average expected return?

To calculate this number, each asset should be measured in terms of its rate of return and the percentage of the entire portfolio that it encompasses. Multiplying these two percentages for each asset and then adding all of them together will yield the weighted average.


2 Answers

With range-v3, it might be:

auto average = ranges::inner_product(grades, grades, 0, {}, {}, &Grade::grade, &Grade::ECTS)
        / double(ranges::accumulate(grades, 0, {}, &Grade::ECTS));

Demo

like image 60
Jarod42 Avatar answered Oct 18 '22 23:10

Jarod42


The Grade type itself is fancy enough to act as the accumulator type.

auto [grade_sum, ects] = std::accumulate(
    grages.begin(), grades.end(), Grade {0,0}, 
    [] (Grade acc, Grade g) -> Grade {
        return { g.grade*g.ECTS + acc.grade,
                 g.ECTS         + acc.ECTS  };
});
// auto average_grade = grade_sum/ects;

C++17 structured binding can be replaced by std::tie if necessary.

like image 31
Tom Avatar answered Oct 19 '22 00:10

Tom