Optimizing a weight algorithm
$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.
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
$endgroup$
add a comment |
$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.
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
$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)
wherex
is a value andw
is a weight.
$endgroup$
– Haus
Jan 21 at 22:48
add a comment |
$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.
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
$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.
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
algorithms geometric-series
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)
wherex
is a value andw
is a weight.
$endgroup$
– Haus
Jan 21 at 22:48
add a comment |
$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)
wherex
is a value andw
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
$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)
wherex
is a value andw
is a weight.$endgroup$
– Haus
Jan 21 at 22:48