Set Maximum Limit of Array, but keep Gradients the Same.

I have an array Batt_C that contains 527040 values (data set of Watts for each minute throughout a year), ranging from -2.8373e+05 : 2.2426e+06.
I want to set the maximum limit in the array which I can do, at size = 1.3222e+06 using:
Batt_C(Batt_C>size) = Batt_C;
If these are plotted I want the gradients from the original Batt_C to transfer to the limited Batt_C array. I.e. if the values go down on the original, then I want the limited to also show the same downward shape. And then rise again accordingly to the limit.

 Accepted Answer

First, do not use size as a variable name as it will prevent you from using the extremely important size function.
Secondly, the line
Batt_C(Batt_C>size) = Batt_C;
will only succeed if no element of Batt_C is greater than size. Otherwise you'll get a dimension mismatch error. I assume the right hand side is supposed to be size.
Anyway, to answer your question, you'll have to identify each continuous run of values above your limit (henceforth called limit not size). Once you've down that subtract from each run the difference from the first element of the run and the limit.
There are several files on the file exchange that can identify runs, it's fairly easy to implement anyway:
abovelimit = Batt_C(:) > limit;
%get start and ends of runs:
runstarts = find(diff([0; abovelimit]) == 1);
runends = find(diff([abovelimit; 0]) == -1);
%adjust each run:
for run = 1:numel(runstarts)
Batt_C(runstarts(run):runends(run)) = Batt_C(runstarts(run):runends(run)) - ...
(Batt_C(runstarts(run)) - limit);
end

7 Comments

Yes sorry, should have read:
Batt_C(Batt_C>size) = size
and I've now changed 'size' to 'limit' upon your recommendation - thanks for the heads up.
I'm not sure I understand what your code does though, it's throwing an error up at:
Batt_C(runstarts(run):runends(run)) = Batt_C(runstarts(run):runends(run)) - Batt_C(runstarts(run) - limit);
with the for loop. The workspace variable 'runends' is left as an empty vector and so can't run the loop. Any advice on that?
Thanks for the help!
There were several missing closing brackets that I've now added. With the typos fixed, runends is guaranteed to be the same number of elements as runstarts.
Unfortunately I'm not seeing that, I'm getting the following:
>> runends = find(diff([abovelimit; 0] == -1))
runends =
Empty matrix: 0-by-1
Please, use the edits I made to the code, not matlab's autocorrections since these are wrong. it is:
runends = find(diff([abovelimit; 0]) == -1)
not
runends = find(diff([abovelimit; 0] == -1))
Oh sorry, my mistake on that.
Unfortunately though it keeps throwing up the error:
Subscript indices must either be real positive integers or logicals.
Error in Battery_Charge (line 87)
Batt_C(runstarts(run):runends(run)) = Batt_C(runstarts(run):runends(run)) - (Batt_C(runstarts(run) - limit));
My code for this section is now like this (courtesy of you - thank you):
%Battery size - dependent on the biggest peak-trough displacement
limit = max(Batt_C(1:300000))-min(Batt_C(1:300000)); %Maximum size of Battery in Watt-Hours
abovelimit = Batt_C(:) > limit;
%get start and ends of runs:
runstarts = find(diff([0; abovelimit]) == 1);
runends = find(diff([abovelimit; 0]) == -1);
%adjust each run:
for run = 1:numel(runstarts)
Batt_C(runstarts(run):runends(run)) = Batt_C(runstarts(run):runends(run)) - (Batt_C(runstarts(run) - limit));
end
plot(Batt_C)
So, being the absolute rookie that I am, I cannot get this to work...
There were three lines where I forgot a closing bracket, these were:
runstarts = find(diff([0; abovelimit]) == 1);
runends = find(diff([abovelimit; 0]) == -1);
(Batt_C(runstarts(run)) - limit);
In each case, matlab's autocorrect is wrong. That's why you get the subscript indexing error in line 87.
Having tested this on some data, my logic for the subtracted value is a bit wrong. I suspect this may be more what you want:
%same start as before
for run = 1:numel(runstarts)
runrange = runstarts(run):runends(run);
Batt_c(runrange) = Batt_c(runrange) - (max(Batt_c(runrange)) - limit);
end
Yeah yeah, I'm with it - after some research into what you've done. Your code works for what I was doing: sets the upper limit and mimics the gradients up and down but from this 'new' reference point. I thank you very very much for this.

Sign in to comment.

More Answers (0)

Categories

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!