如何使用多个输入创建函数?

时间:2019-04-25 05:31:54

标签: matlab function

我必须制作一个50x50的矩阵,其随机值介于-10到10之间,然后使用一个名为averageColumn()的自定义函数,我必须创建一个每列平均值的1x50矩阵,不包括任何小于0。

生成矩阵没有问题,但是我不知道如何使函数起作用。我不断收到一条错误消息,指出我的函数输入参数不足。

该功能的代码为:

function outputArg1 = averageColumn(inputArg1, inputArg2)
%inputArg1 = an m x n matrix
% inputArg2 = the column# to average
% outputArg1 = the column average, or zero if all the values happen to be zero
for rowNum = 1:50
if inputArg1(rowNum, inputArg2) > 0
    inputArg1(rowNum, inputArg2) = inputArg1(rowNum, inputArg2);
else
    inputArg1(rowNum, inputArg2) = NaN;
end

outputArg1 = nanmean(inputArg1, inputArg2);
end

在单独文件中矩阵的代码是:

inputArg1 = randi([-10 10],50,50)

for inputArg2 = 1:50
    outputArg1 = averageColumn(inputArg1, inputArg2)    
end

请保持温柔,我真的是Matlab的新手。

5 个答案:

答案 0 :(得分:2)

为什么每个人都在迭代?使用更多矢量化!...

那为什么所有的NaN?积极向上查询!...

我的提案

功能:

function ret = averageCol(A, n)

ret = mean(A(A(:, n)>=0, n))

end

命名

A = randi([-100, 100], 50);

out = arrayfun( @(n) averageCol(A, n), 1:size(A, 2))

说明

从内到外

[1] A(:, n)-返回第n列

[2] [1] >= 0-返回布尔列向量,该向量也可用于索引

[3] A([2], n)-从第n列返回所有大于或等于零的值

[4]取[3]的平均值...轰!你在那里...

答案 1 :(得分:1)

还有两个选项可获得相同的结果:

使用

A = randi([-10, 10], 50);

解决方案1:使用矩阵索引和nanmean

A(A<0)=NaN;
out = nanmean(A);

解决方案2:使用线性代数

out = ones(1,size(A,2))*(A.*(A>=0))./sum(A>=0)

在我使用X̅ = 1'*X*(1'*1)^-1且其中1为1的n x 1列向量的情况下

答案 2 :(得分:0)

我相信您的实现会使事情变得有些复杂。也许您可以尝试一种更简单的方法。

如果我正确理解了您的要求,则下面的代码应该可以为您提供所需的信息。如果没有,请通知我。

代码中的注释应该足以让您了解发生了什么。

sharedLibrarySetupEnv branch: "$env.GIT_BRANCH", envMapping: EnvMap

答案 3 :(得分:0)

编辑:啊,我还没有看到您的上一次编辑。只需使用nanmean即可。


因此,我试图保留尽可能多的代码。

首先,让我们看一下调用函数的脚本:

inputArg1 = randi([-10 10], 50, 50)

for inputArg2 = 1:size(inputArg1, 2)
    outputArg1(inputArg2) = averageColumn(inputArg1, inputArg2);   
end

outputArg1

只是一般建议:更好地提取提供给您的输入的维数,而不是对值进行硬编码。 (当然,您可以在此处自行设置输入,但是请记住这一点。)要使用平均值创建所需的数组,只需将for循环中的列号用作数组索引即可。

现在,让我们进入您的功能:

function outputArg1 = averageColumn(inputArg1, inputArg2)
% inputArg1 = an m x n matrix
% inputArg2 = the column# to average
% outputArg1 = the column average, or zero if all the values happen to be zero

for rowNum = 1:size(inputArg1, 1)
    if inputArg1(rowNum, inputArg2) < 0
        inputArg1(rowNum, inputArg2) = NaN;
    end
end

outputArg1 = nanmean(inputArg1(:, inputArg2));

end

同样,不要对值(rowNum)进行硬编码!另外,该end循环(您的编辑)的for也丢失了。 if语句太复杂了,因为inputArg1(rowNum, inputArg2) = inputArg1(rowNum, inputArg2)是多余的。只需将所有负输入设置为NaN。要计算“平均值”,只需使用带有omitnan标志的mean函数。或者,如果您有权访问“统计和机器学习工具箱”,则可以使用nanmean函数。

答案 4 :(得分:-1)

由于我对实现进行了很多更改,因此我决定将此提交为另一个答案。

所以我相信这是您想要的,希望这次。

inputArg1 = randi([-10 10],50,50);

outputArg1 = [];
for inputArg2 = 1:50
    outputArg1 = [outputArg1 averageColumn(inputArg1, inputArg2)];  
end

在上面的脚本中,我更改了每次迭代中操作outputArg1的方式,因此请看一下它。我在每次迭代中都从averegaColumn函数中获取一个值,并将其添加到outputArg数组中。

请注意,在循环内更改像这样的数组的大小是不好的做法!!!但是话又说回来,您的问题仍然可以在3-4行中完成:)

剩下的就是这里。我认为代码是不言自明的。

function outputArg1 = averageColumn(inputArg1, inputArg2)
% inputArg1 = an m x n matrix
% inputArg2 = the column# to average
% outputArg1 = the column average, or zero if all the values happen to be zero

column = inputArg1(:,inputArg2); % take the required column from the input matrix
column(column < 0) = 0; % thanks to Sven Krüger for reminding me this usage!!!
outputArg1 = mean(column);

我认为这是可以使用此任务的函数和多个输入参数完成的最简单的实现。但是,当然,社区的力量可以找到一些更简单的解决方案。让我知道,如果您什么都不懂。