Optimizing a weight algorithm












2












$begingroup$


I am attempting to optimize a C++ algorithm that calculates a set of values with corresponding weights. There are n values, with the first being the most recent and the last being the least recent. There are n weights which do not change.



The formula is as follows:



let x = values
let w = weights
(x1 * w1) + (x2 * w2) + ... + (xn * wn)


Take, for instance, this set of values and weights:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.40, 2.30, 1.60, 9.10, 1.40
Output: 2.054
Calc: (5.40 * 0.20) + (2.30 * 0.15) + (1.60 * 0.10) + (9.10 * 0.05) + (1.40 * 0.01)


As new values are inserted over time, the older ones are shifted down and eventually removed from the set of values entirely, so if a new value, 5.80, was added, the new data set would be:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.80, 5.40, 2.30, 1.60, 9.10 [1.40 removed]
Output: 2.371


My algorithm currently has to re-calculate the result every time a new value is added. This is still a very quick operation when the set is small, but I would like to scale this up to much larger sets, and doing so can decrease performance.



I am hoping to be able to somehow exploit a mathematical property in the way the calculations are performed so that each time a new value is added I can avoid having to multiply each value by its weight.



I am by no means a mathematician, but I'm under the impression that, since each existing value is shifted to the right, I could somehow calculate a ratio based on the weights and multiply that with the previous output to decrement it before adding the new value multiplied by the first weight. The rationale is treating this as a geometric series, but my test calculations seem to be off, and the n weights are completely arbitrary in production, so I am not certain if that is a viable solution.



In short, my question is: Is there a way in which I can calculate the new value every time a new value is added without having to iterate over the entire set? I need to be able to (at least closely approximate) the new resulting value when the values are shifted.





Edit: I have found an approximate solution, but there is still a margin of error.
enter image description here



The formula is as follows:



Output 2 = (New Value * Weight 1) + ((Sum Weights 2:5)/(Sum Weights 1-5) * Output 1)


Essentially, the values shift over one space, and I take the ratio of the sum of weights 2-5 to the sum of all weights. Then, I multiply the previous output by that ration and add the new value multiplied by the first weight.



If the new value varies too wildly from the mean the error increases though. I'd like to be able to lower that error if possible.










share|cite|improve this question











$endgroup$












  • $begingroup$
    How are the outputs calculated?
    $endgroup$
    – John Douma
    Jan 21 at 22:32










  • $begingroup$
    Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
    $endgroup$
    – Haus
    Jan 21 at 22:48
















2












$begingroup$


I am attempting to optimize a C++ algorithm that calculates a set of values with corresponding weights. There are n values, with the first being the most recent and the last being the least recent. There are n weights which do not change.



The formula is as follows:



let x = values
let w = weights
(x1 * w1) + (x2 * w2) + ... + (xn * wn)


Take, for instance, this set of values and weights:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.40, 2.30, 1.60, 9.10, 1.40
Output: 2.054
Calc: (5.40 * 0.20) + (2.30 * 0.15) + (1.60 * 0.10) + (9.10 * 0.05) + (1.40 * 0.01)


As new values are inserted over time, the older ones are shifted down and eventually removed from the set of values entirely, so if a new value, 5.80, was added, the new data set would be:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.80, 5.40, 2.30, 1.60, 9.10 [1.40 removed]
Output: 2.371


My algorithm currently has to re-calculate the result every time a new value is added. This is still a very quick operation when the set is small, but I would like to scale this up to much larger sets, and doing so can decrease performance.



I am hoping to be able to somehow exploit a mathematical property in the way the calculations are performed so that each time a new value is added I can avoid having to multiply each value by its weight.



I am by no means a mathematician, but I'm under the impression that, since each existing value is shifted to the right, I could somehow calculate a ratio based on the weights and multiply that with the previous output to decrement it before adding the new value multiplied by the first weight. The rationale is treating this as a geometric series, but my test calculations seem to be off, and the n weights are completely arbitrary in production, so I am not certain if that is a viable solution.



In short, my question is: Is there a way in which I can calculate the new value every time a new value is added without having to iterate over the entire set? I need to be able to (at least closely approximate) the new resulting value when the values are shifted.





Edit: I have found an approximate solution, but there is still a margin of error.
enter image description here



The formula is as follows:



Output 2 = (New Value * Weight 1) + ((Sum Weights 2:5)/(Sum Weights 1-5) * Output 1)


Essentially, the values shift over one space, and I take the ratio of the sum of weights 2-5 to the sum of all weights. Then, I multiply the previous output by that ration and add the new value multiplied by the first weight.



If the new value varies too wildly from the mean the error increases though. I'd like to be able to lower that error if possible.










share|cite|improve this question











$endgroup$












  • $begingroup$
    How are the outputs calculated?
    $endgroup$
    – John Douma
    Jan 21 at 22:32










  • $begingroup$
    Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
    $endgroup$
    – Haus
    Jan 21 at 22:48














2












2








2





$begingroup$


I am attempting to optimize a C++ algorithm that calculates a set of values with corresponding weights. There are n values, with the first being the most recent and the last being the least recent. There are n weights which do not change.



The formula is as follows:



let x = values
let w = weights
(x1 * w1) + (x2 * w2) + ... + (xn * wn)


Take, for instance, this set of values and weights:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.40, 2.30, 1.60, 9.10, 1.40
Output: 2.054
Calc: (5.40 * 0.20) + (2.30 * 0.15) + (1.60 * 0.10) + (9.10 * 0.05) + (1.40 * 0.01)


As new values are inserted over time, the older ones are shifted down and eventually removed from the set of values entirely, so if a new value, 5.80, was added, the new data set would be:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.80, 5.40, 2.30, 1.60, 9.10 [1.40 removed]
Output: 2.371


My algorithm currently has to re-calculate the result every time a new value is added. This is still a very quick operation when the set is small, but I would like to scale this up to much larger sets, and doing so can decrease performance.



I am hoping to be able to somehow exploit a mathematical property in the way the calculations are performed so that each time a new value is added I can avoid having to multiply each value by its weight.



I am by no means a mathematician, but I'm under the impression that, since each existing value is shifted to the right, I could somehow calculate a ratio based on the weights and multiply that with the previous output to decrement it before adding the new value multiplied by the first weight. The rationale is treating this as a geometric series, but my test calculations seem to be off, and the n weights are completely arbitrary in production, so I am not certain if that is a viable solution.



In short, my question is: Is there a way in which I can calculate the new value every time a new value is added without having to iterate over the entire set? I need to be able to (at least closely approximate) the new resulting value when the values are shifted.





Edit: I have found an approximate solution, but there is still a margin of error.
enter image description here



The formula is as follows:



Output 2 = (New Value * Weight 1) + ((Sum Weights 2:5)/(Sum Weights 1-5) * Output 1)


Essentially, the values shift over one space, and I take the ratio of the sum of weights 2-5 to the sum of all weights. Then, I multiply the previous output by that ration and add the new value multiplied by the first weight.



If the new value varies too wildly from the mean the error increases though. I'd like to be able to lower that error if possible.










share|cite|improve this question











$endgroup$




I am attempting to optimize a C++ algorithm that calculates a set of values with corresponding weights. There are n values, with the first being the most recent and the last being the least recent. There are n weights which do not change.



The formula is as follows:



let x = values
let w = weights
(x1 * w1) + (x2 * w2) + ... + (xn * wn)


Take, for instance, this set of values and weights:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.40, 2.30, 1.60, 9.10, 1.40
Output: 2.054
Calc: (5.40 * 0.20) + (2.30 * 0.15) + (1.60 * 0.10) + (9.10 * 0.05) + (1.40 * 0.01)


As new values are inserted over time, the older ones are shifted down and eventually removed from the set of values entirely, so if a new value, 5.80, was added, the new data set would be:



Weights: 0.20, 0.15, 0.10, 0.05, 0.01
Values: 5.80, 5.40, 2.30, 1.60, 9.10 [1.40 removed]
Output: 2.371


My algorithm currently has to re-calculate the result every time a new value is added. This is still a very quick operation when the set is small, but I would like to scale this up to much larger sets, and doing so can decrease performance.



I am hoping to be able to somehow exploit a mathematical property in the way the calculations are performed so that each time a new value is added I can avoid having to multiply each value by its weight.



I am by no means a mathematician, but I'm under the impression that, since each existing value is shifted to the right, I could somehow calculate a ratio based on the weights and multiply that with the previous output to decrement it before adding the new value multiplied by the first weight. The rationale is treating this as a geometric series, but my test calculations seem to be off, and the n weights are completely arbitrary in production, so I am not certain if that is a viable solution.



In short, my question is: Is there a way in which I can calculate the new value every time a new value is added without having to iterate over the entire set? I need to be able to (at least closely approximate) the new resulting value when the values are shifted.





Edit: I have found an approximate solution, but there is still a margin of error.
enter image description here



The formula is as follows:



Output 2 = (New Value * Weight 1) + ((Sum Weights 2:5)/(Sum Weights 1-5) * Output 1)


Essentially, the values shift over one space, and I take the ratio of the sum of weights 2-5 to the sum of all weights. Then, I multiply the previous output by that ration and add the new value multiplied by the first weight.



If the new value varies too wildly from the mean the error increases though. I'd like to be able to lower that error if possible.







algorithms geometric-series






share|cite|improve this question















share|cite|improve this question













share|cite|improve this question




share|cite|improve this question








edited Jan 22 at 0:16







Haus

















asked Jan 21 at 22:26









HausHaus

1113




1113












  • $begingroup$
    How are the outputs calculated?
    $endgroup$
    – John Douma
    Jan 21 at 22:32










  • $begingroup$
    Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
    $endgroup$
    – Haus
    Jan 21 at 22:48


















  • $begingroup$
    How are the outputs calculated?
    $endgroup$
    – John Douma
    Jan 21 at 22:32










  • $begingroup$
    Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
    $endgroup$
    – Haus
    Jan 21 at 22:48
















$begingroup$
How are the outputs calculated?
$endgroup$
– John Douma
Jan 21 at 22:32




$begingroup$
How are the outputs calculated?
$endgroup$
– John Douma
Jan 21 at 22:32












$begingroup$
Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
$endgroup$
– Haus
Jan 21 at 22:48




$begingroup$
Updated my post to include the formula. It is simply multiplying the weight and value and then summing them together, e.g. (x1 * w1) + (x2 * w2) where x is a value and w is a weight.
$endgroup$
– Haus
Jan 21 at 22:48










0






active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
});
});
}, "mathjax-editing");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "69"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
noCode: true, onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f3082506%2foptimizing-a-weight-algorithm%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Mathematics Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmath.stackexchange.com%2fquestions%2f3082506%2foptimizing-a-weight-algorithm%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Mario Kart Wii

What does “Dominus providebit” mean?

Antonio Litta Visconti Arese