Effacer les filtres
Effacer les filtres

How to use any size array as an input?

15 vues (au cours des 30 derniers jours)
Kristen O'Mara
Kristen O'Mara le 20 Fév 2018
Modifié(e) : Stephen23 le 21 Déc 2018
I need to make a function that calculates the median and mean values of an array. I'm not sure how to use an array as an input when it needs to be able to be any dimensions. Also, matlab is giving me the error, "too many input arguments" for the mod function, not quite sure why. Here is my code:
function [meanValue, medianValue] = statsFunction(array)
sort(array, 'ascend');
if mod(length(array), 2) ~= 0
medianValue = (length(array)/2)+1;
elseif mod(array/2) == 0
medianValue = ((length(array)/2) + ((length(array)/2)+1))/length(array);
end
meanValue = sum(array)/length(array);
  4 commentaires
Stephen23
Stephen23 le 20 Fév 2018
Modifié(e) : Stephen23 le 21 Déc 2018
length is an abomination: do not use it.
One day a bright-eyed user decides to loop over the columns of a matrix, and because they only have a few rows they use length:
>> length(zeros(3,8))
ans = 8
and everything looks hunky-dory: length returned the number of columns of the matrix, which is perfect for their code. But the next day their user inputs an array with more rows than the one that the code was tested with:
>> length(zeros(99,8))
ans = 99
Oh no! length no longer returns the number of columns, it now returns the number of rows! Suddenly their code in the loop tries to access columns that do not exist, it throws an error and they can't figure out why, because, well, yesterday everything worked and they didn't change anything! Confusion reigns, tears flow, there is a great gnashing of teeth, and questions to random strangers on internet forums...
If only they had used size, which always measures exactly the requested dimension, they would have avoided some pointless debugging: to get the number of columns they just needed size(array,2), and this will always return the number of columns, no matter the size of the array.
For much the same reasons, to get the total number of elements in an array use numel.
Jan
Jan le 20 Fév 2018
@Kristen: As Stephen has written already, use size or numel:
doc size
doc numel
See this example:
A = rand(2, 3)
Now length() replies 3, because it is the length of the longest dimension. But this is rarely useful, except if you are sure that the array is a vector. size(A, 2) is accurate to determine the length of the 2nd dimension, numel(A) replies 6, the total number of elements.

Connectez-vous pour commenter.

Réponses (2)

Guillaume
Guillaume le 20 Fév 2018
If not for the bugs, your function would work for vector inputs of any size (but not matrices or arrays, i.e. anything with 2 or more dimensions).
You're calculating the index of the median value, not the median value itself.
mod(array/2) is certainly not the same thing as |mod(length(array), 2)). It's no wonder you get an error for the former.
In any case
if somecondition
%do something
elseeif ~somecondition
%do something else
end
is redundant, if the if is false, then the elseif has to be true. So it can be simplified to:
if condition
%do something
else
%do something else
end
It's not clear what your function is supposed to do with arrays that are not vector or even if it's supposed to work with arbitrary sized arrays. If it is only meant to support vectors, I would add a check as a first line:
validateattributes(array, {'numeric'}, {'vector'});
Finally, note that your sort line is pointless since you don't assign the result to anything.
  2 commentaires
Kristen O'Mara
Kristen O'Mara le 20 Fév 2018
Thanks for the feedback, I fixed the things you said. My function is meant to take arbitrarily sized arrays. Now the biggest issue I seem to be having is my function returning an array for the median value when it should be returning a single number. Indexing seems to have me a bit confused: any tips would be much appreciated.
Guillaume
Guillaume le 20 Fév 2018
Modifié(e) : Guillaume le 20 Fév 2018
What is the median or mean value of an array? For example, what result would you expect for the following arrays:
[1 2
3 4]
[1 3
2 4]
[1 2 3 4]
[1
2
3
4]

Connectez-vous pour commenter.


Jan
Jan le 20 Fév 2018
Modifié(e) : Jan le 20 Fév 2018
If you want to consider all elements and not the shape of the array:
function [meanValue, medianValue] = statsFunction(array)
x = array(:);
...
Now x is a column-vector containing all elements of the input array.
s = sort(x);
This assigns the sorted vector x to s. Of course you can combine the commands:
s = sort(array(:));
In your code
medianValue = (length(array)/2)+1;
you calculate the index of the element containing the median value, but I assume you want the value of the element:
ns = numel(s); % Avoid repeated calls of numel() for clarity
if mod(ns, 2) % You can omit: ~= 0
medianValue = s((ns + 1) / 2);
else
...
This should help you to find the median for an even number of elements also. Use the values s at the indices ns/2 and ns/2+1. Divide by 2, not by the number of elements.

Catégories

En savoir plus sur Matrix Indexing dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by