Difficulty using mean function

Hello!
I'm attempting to calculate the mean of a vector, and while I'm not getting any errors, the output is just a duplicate of the vector I'm trying to average. My variables are calculated in my function biodex_strengthSC:
function [pk_Torque,impulse,pktorque_avg,impulse_avg] = biodex_strengthSC(data,subcode,type)
%skipping some steps here and just showing how outcomes are calculated:
for i=1:length(Contraction_Torque)
pk_Torque(i)= max(CTorque{i});
end
if type == 1
for i=1:length(startrow_isoV)
IsoV_Torque{i} = Contraction_Torque{i}(startcontr(i):endrow_isoV(i));
end
for i=1:length(IsoV_Torque)
impulse(i) = (trapz(IsoV_Torque{i}))/100;
end
elseif type == 2
for i=1:length(CTorque)
impulse(i) = (trapz(CTorque{i}))/100;
end
end
pktorque_avg = mean(pk_Torque);
impulse_avg = mean(impulse);
end
For example, running:
for i=1:length(ZST_30)
[pk_Torque_ST_30(i),impulse_ST_30(i),pktorque_avg_ST_30(i),impulse_avg_ST_30(i)] = biodex_strengthSC(ZST_30{i},subcode,1);
end
Gives me no errors and correct values for pk_Torque_ST_30 and for impulse_ST_30 (both row vectors), BUT pktorque_avg_ST_30 is identical to pk_Torque_ST_30 and impulse_avg_ST_30 is identical to impulse_ST_30 (instead of being means of the row vectors as I expected).
After digging into the documentation of the mean function I noticed that applying mean to a matrix returns the mean of each column of the matrix.. although my inputs are just row vectors, I tried transposing them into column vectors within biodex_strengthSC:
pk_Torque = pk_Torque';
impulse = impulse';
pktorque_avg = mean(pk_Torque);
impulse_avg = mean(impulse);
After running that, my outcome variables were the exact same as before (pk_Torque_ST_30 and impulse_ST_30 as row vectors and pktorque_avg_ST_30 and impulse_avg_ST_30 as identical row vectors).
If I try the following in the command window, then the mean of pk_Torque_ST_30 is calculated correctly (same with the other respective variables).
pktorque_avg_ST_30 = mean(pk_Torque_ST_30)
This is my first time writing my own function so I'm guessing I'm making some really basic mistake with my function. Sorry this is so long, just wanted to make sure all the information needed was there including troubleshooting steps I've taken. Thanks in advance!!

2 Comments

" I noticed that applying mean to a matrix returns the mean of each column of the matrix.. although my inputs are just row vectors, I tried transposing them into column vectors ..."
Well, a vector is a vector regardless of its orientation so mean() returns mean(v) when one or the other dimension is unity. The documentation also clearly states this in very first line...
"M = mean(A) returns the mean of the elements of A along the first array dimension whose size does not equal 1."
So for a vector array there's only one non-unity dimension left.
You gave us everything except what the actual form of the data are going into the function...the call that works correctly for variable pk_Torque_ST_30, indicates that it must be an array or vector whereas when you call your function you're passing ZST_30{i} which is dereferencing a cell array but we don't know the content of that cell. Apparently it is only a single value?
What does
whos ZST_30
return at command line?
It's always helpful to attach a small(ish) set of data with a question -- there are so many ways to store things in MATLAB that without we're often left guessing as to what the variables are.
Thanks for this! You're right, I forgot to include ZST_30 and didn't include the data itself.
whos ZST_30
Name Size Bytes Class Attributes
ZST_30 1x3 14224 cell
ZST_30 is a cell. I'm clearly kind of a beginner with Matlab and both the function and the code are hand-me-downs from colleagues that I've tried to adapt for my purposes. Initially the call read
[pk_Torque_ST_30{i},impulse_ST_30{i},pktorque_avg_ST_30{i},impulse_avg_ST_30{i}] = biodex_strengthSC(ZST_30{i},subcode,1);
And my outputs were all 1x6 cell arrays, but I changed it because I read that mean doesn't work on cell arrays (even though it wasn't erroring for me). I'm sure messing around with variable types isn't helping, but even when all my variables were cell arrays nothing was erroring but I wasn't getting averages.
To (hopefully) make this a little easier to answer, I've attached the code I'm running (simplified_code.m), the two functions it references, and two example data files. Let me know if you want the data in another format. Thank you!!

Sign in to comment.

 Accepted Answer

Ameer Hamza
Ameer Hamza on 14 Apr 2020
Edited: Ameer Hamza on 14 Apr 2020
The only problem in your code is caused by the misunderstanding of the cell array. Consider this example
>> x = {[1 2 3 4 5]};
>> length(x)
ans =
1
The size of the vector inside the cell array is not returned by the length function. You need to use the following syntax
>> x = {[1 2 3 4 5]};
>> length(x{1})
ans =
5
In your function, there are several for loop of the type
for i=1:length(Contraction_Torque)
CTorque{i}= Contraction_Torque{i}(startcontr(i):contr_vel0(i));
end
Here length(Contraction_Torque) is 1, so the loop only runs once. You should correct it to
for i=1:length(Contraction_Torque{1})
CTorque{i}= Contraction_Torque{i}(startcontr(i):contr_vel0(i));
end
Right now, all the for loops run once and at the line
pktorque_avg = mean(pk_Torque);
pk_Torque is 1x1, so mean() just returns the input.

5 Comments

Thanks so much for this. Your answer made me re-think my data structure and how it is different than the data this code was originally written for. Basically, ZST_30 contains multiple 'trials' and I want to pull pk_Torque from each trial, and then an average of pk_Torque across multiple trials (likewise for impulse) - but each of my text files only contains 1 trial, whereas I think the data this was written for had multiple trials in each text file - all this to say that all of the for loops run once (as you said) for each trial, and the whole process repeats for as many trials as I have - instead of one run-through with multiple loop iterations as I had expected. All this to say that to get the average I want, I need to move the mean function to my code (instead of building it into the function) or figure out another solution that will average all elements of pk_Torque for all trials.
Not sure if this made sense, but it makes sense to me and I know how to proceed. I would've spent days trying to figure this out if it wasn't for your answer, thanks again!
You are probably correct. You need to go through the program logic and maybe use breakpoints and go through the function biodex_strengthSC step by step. That way, you can figure out if each part is working as expected.
I just have one suggestion. The listdlg part of your code is prone to failure. I suggest changing line 8-10 of your code with this one line
fn = {Files.name};
you will see only txt file will appear in the dialog box.
I had started on rewriting the analysis routine to eliminate a bunch of the spurious loops...but having to enter data manually and having no klew what was intended was going to take too long...but I'll attach the first cut for your perusal/consideration.
Agree w/ Ameer's comment above, btw...
Thanks very much, both of you!
OBTW...when you do that dir() search, use a wildcard for the tile type as
d=dir('CS*.txt');
or somesuch that matches desired...then you will not get the spurious Windoes "., .." directory listings--provided, of course, somebody hasn't named a directory with the given name including the trailing .txt. And if they have done, they deserve the grief it will give... :)

Sign in to comment.

More Answers (0)

Tags

Asked:

on 14 Apr 2020

Commented:

dpb
on 15 Apr 2020

Community Treasure Hunt

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

Start Hunting!