【问题标题】:How do I ask MATLAB to run my function for each column in a matrix?如何让 MATLAB 为矩阵中的每一列运行我的函数?
【发布时间】:2012-10-19 01:06:42
【问题描述】:

我的教授的 RA 工作快完成了;但是,我有一个编程问题困扰着我。我的教授要求我做的最后一步是我需要运行我为矩阵编写的所有函数。将会发生的是,对于该矩阵的每一列,我将调用我编写的函数,例如,它看起来像这样:

function [xpeaks, xtroughs]=peaktrough(x,cutoff)

% This function is a modified version of the algorithm used to identify
% peaks and troughs in a series of prices. This will be used to identify
% the head and shoulders algorithm. The function gives you two vectors:
% PEAKS - an indicator vector that identifies the peaks in the function,
% and TROUGHS - an indicator vector that identifies the troughs of the
% function, and a MATRIX - ptdata, which is a matrix of the location and
% the value of the peak/trough.

% The input is the vector of exchange rate series, and the cutoff
% used for the selection of the final peaks and troughs.

% Finding all possible peaks and troughs of our vector.
[posspeak,possploc]=findpeaks(x);
[posstrough,posstloc]=findpeaks(-x);
posspeak=posspeak';
posstrough=posstrough';

% Initialize vector of peaks and troughs.
numobs=length(x);
prelimpeaks=zeros(numobs,1); 
prelimtroughs=zeros(numobs,1);
numpeaks=numel(possploc);
numtroughs=numel(posstloc);

% Indicator for possible peaks and troughs.
for i=1:numobs
    for j=1:numpeaks
        if i==possploc(j);
            prelimpeaks(i)=1;
        end
    end
end

for i=1:numobs
    for j=1:numtroughs
        if i==posstloc(j);
            prelimtroughs(i)=1;
        end
    end
end

% Vector that gives location.
location=1:1:numobs;
location=location';

% From the list of possible peaks and troughs, find the peaks and troughs
% that fit Chang and Osler [1999] definition.
% "A peak is a local minimum at least x percent higher than the preceding
% trough, and a trough is a local minimum at least x percent lower than the
% preceding peak." [Chang and Osler, p.640]

peakcutoff=1.0+cutoff; % cutoff for peaks
troughcutoff=1.0-cutoff; % cutoff for troughs

% First peak and first trough are initialized as previous peaks/troughs.

prevpeakloc=possploc(1);
prevtroughloc=posstloc(1);

% Initialize vectors of final peaks and troughs.
vectpeak=zeros(numobs,1);
vecttrough=zeros(numobs,1);

% We first check whether we start looking for peaks and troughs.
for i=1:numobs
    if prelimpeaks(i)==1;
       if i>prevtroughloc;
           ratio=x(i)/x(prevtroughloc);
           if ratio>peakcutoff;
               vectpeak(i)=1;
               prevpeakloc=location(i);
           else vectpeak(i)=0;
           end
       end
    elseif prelimtroughs(i)==1;
        if i>prevpeakloc;
            ratio=x(i)/x(prevpeakloc);
            if ratio<troughcutoff;
                 vecttrough(i)=1;
                 prevtroughloc=location(i);
            else vecttrough(i)=0;
            end
        end
    else
        vectpeak(i)=0;
        vecttrough(i)=0;
    end
end

% Now from the final peaks and troughs, we now write the matrix of the
% peaks and troughs of the exchange rate series.
xpeaks=find(vectpeak);
xtroughs=find(vecttrough);
end

现在,但是,对于不同的列,我最终会得到不同大小的向量。我想知道的是,我该怎么做?我有 20 个用户创建的函数,对于每个函数,我需要运行 5000 x 10000 矩阵中的每一列。

我的一个朋友建议我编写一个函数来获取矩阵的第 n 列,然后将其作为向量返回,然后针对该结果向量运行矩阵的每个函数。还有其他想法吗?其实,老实说,我不知道怎么写他建议的那个函数。谢谢!

【问题讨论】:

  • 如果您听从朋友的建议,将矩阵的第 N 列作为向量返回是微不足道的,mtx(:,N)。然后将 feval() 与您的每个自定义函数一起使用。
  • 如果您认为我已经回答了该问题,请单击我的答案旁边的勾号标记已回答的问题。如果没有,请告诉我原因,以便我尝试改进我的答案。干杯。
  • 嗨 Colin,对不起,我想你可能已经回答了我的问题,但我还没有看到结果,因为我的电脑很慢。

标签: matlab for-loop matrix


【解决方案1】:

如果输出是不同大小的向量,那么您不能将它们全部存储在一个数值数组中,除非该数组是一个巨大的长行(列)向量,输出向量水平(垂直)堆叠。

因此,我建议使用元胞数组来存储输出。将元胞数组的第一行用于峰,将第二行用于波谷。例如:

NumCol = 10000
YourMatrix = randn(5000, NumCol);
YourCellArrayOutput = cell(2, NumCol);
for m = 1:NumCol
    [CurPeaks, CurTroughs] = peaktrough(YourMatrix(:, m), cutoff);
    YourCellArrayOutput{1, m} = CurPeaks;
    YourCellArrayOutput{2, m} = CurTroughs;
end

请注意,我使用花括号 {} 而不是 () 来索引元胞数组。阅读此herehere

按照我在此处构建的输出结构,您需要为在矩阵上运行的每个函数创建一个元胞数组。我认为考虑到应用程序(技术分析),这可能是最有意义的。

【讨论】:

  • 嗨科林,这个答案只有一个问题。我认为这确实是一个很好的方法,但是,例如,我的大多数自定义函数的输出结果都是列向量。这对我编写上面代码的语法有影响吗?或者无论用于我的输出的向量类型如何,这都会起作用。谢谢!我确实认为这是一个很好的答案,但我还没有结果。我的电脑好慢啊:)
  • @JulioGalvez 是的,CurPeaksCurTroughs 可以是列向量。元胞数组中的单个元胞可以存储任何内容 - 数值标量/向量/矩阵、结构、字符串,甚至是另一个元胞数组。它们是一种非常灵活的存储解决方案,在您目前的情况下很有用,因为您有不同长度的输出向量,因此它们不能全部存储在一个矩形数值矩阵中。
  • 例如,如果我的下一个函数依赖于输出,比如 CurPeaks 和 CurTroughs,那么当我编写代码时,基本上,它的格式与您在此处显示的格式相同,但是那么语法将类似于:for m=1:ncol% Head and Shoulders Patternscadbhead1=headshoulders(cadboot(:,m),cadpeaktrough1{1,m},cadpeaktrough1{2,m},horizsym);% Store results in vectors.cadheadshoulder1{1,m}=cadbhead1;end
  • @JulioGalvez 是的,这对我来说是正确的。或者,您也可以在第一个循环中评估该函数(即使用CurPeaksCurTroughs)。
猜你喜欢
  • 2011-01-19
  • 2016-03-04
  • 2014-11-02
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多