The data variable is a 3x9 array, where the first row is voltage, the second row is counts, and the third row is error. I want to average the counts/errors at each voltage so that the processed array is something like
combined = [1,2,3;.99,.1.2,1.3;.2,.3,.5]
My attempt so far is:
data = [1,1,1,2,2,2,3,3,3;...
.98,.99,.98,1.1,1.2,1.2,1.3,1.3,1.4;...
.3,.2,.2,.3,.3,.4,.5,.4,.5];
volt = data(1,:);
v_uniq=unique(volt);%Array of unique voltage values
for k=1:length(v_uniq)
volt_i=find(volt==v_uniq(k));%Indices for set of repeating values
combined_m(k)=mean(data(2,volt_i(1):volt_i(end)).')';%averaged means
combined_e(k)=mean(data(3,volt_i(1):volt_i(end)).')';%averaged error
combined(k) = [combined_m(k);combined_e(k)];
%combined(k)=combined(k);
end
The challenging part is appending the combined array after each iteration, since v_uniq is an array itself and causes problems when trying to iterate through.
Is there some way to append the combined array without having to index v_uniq? Or if nor, is there another, simpler way to approach this problem?
If you want to get your code working, using Daniel's suggestion in his comment to you above will work. Simply replace the last line of your
for
loop code to this:You want to insert a column that shows the combined counts and errors for each unique voltage.
However, I would recommend using
accumarray
instead of yourfor
loop approach, and use the voltage as the key and use the other two rows of your matrix as values. Howaccumarray
works is that you have two arrays:keys
andvalues
. For each value that is stored inkeys
, we see what the corresponding number is invalues
, and we place this number into a bin that is indexed bykeys
. Once we do all of this binning, you then use a function that combines all of these entries per bin together. By defaultaccumarray
usessum
, and so you'd just sum all of the values that get mapped to each bin together.However, for your case you would use
mean
as the function to apply over each of the bins to find the average error and counts for each unique voltage. Something like this:In
accumarray
, the first argument is the keys, which are the voltages in our case, andvalues
are either the counts or the errors - essentially those values that need to be combined.ave_counts
will contain the average counts per unique voltage whileave_error
will contain the average error per unique voltage. We can then combine these into a 2 column matrix like the last line of code to createcombined
, as what was seen in your code.Because your voltages are already ordered in an increasing way, this will mean that each element corresponds to that voltage exactly. After running this, this is what I get for
ave_counts
andave_error
:This says that for
voltage = 1
, the average count and average error are0.9833
and0.2333
respectively. You can verify this by calculating this by hand. The first three counts and errors are forvoltage = 1
, and if we calculate the average error and counts, we get:Similarly for
voltage = 2
:Finally for
voltage = 3
:The quantities that we calculated above by hand are exactly what
accumarray
outputs for both quantities.Caveat
accumarray
is only designed to take in integer keys. If you have floating-point values, you can still useaccumarray
, but you'd have to do some pre-processing first. What I would do is useunique
and use the third output specifically. The third output takes each unique value in the input and assigns an integer ID to it. Any values that are the same get assigned the same integer ID, which is thus ideal as input intoaccumarray
. You would also need the first output to keep track of what voltages are being averaged per row of thecombined
matrix.You would thus use the third output of
unique
as input intoaccumarray
. Therefore, do something like this:In this case, each element of
ave_counts
andave_error
will correspond to the same element stored involtages
. As such,voltages(1)
will correspond to the first row ofcombined
,voltages(2)
will correspond to the second row ofcombined
, and so on.For completeness, if we ran the above with your example data, this is what we get for
voltages
andcombined
:Therefore,
voltage = 1
gives us an average count of0.9833
with an average error of0.2333
, and so on.