MATLAB为所有X,Y对创建函数的曲面图

时间:2015-10-20 14:53:29

标签: matlab

我有一个名为dissmeasure的自定义函数,它从频率的输入向量输出标量。另一个名为music.tone2freq的函数将整数转换为频率。

我的目标是为所有x,y整数对创建dissmeasure的曲面图,其中X和Y等于[0:1:11]

看起来应该是这样的(这是mesh(X,Y, ones(12,12) )): sample

mesh docs开始,我尝试过的是:

[X,Y] = meshgrid(0:1:12)
Z = dissmeasure(music.tone2freq([X., Y.]))

但我得Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.

Z = dissmeasure(music.tone2freq([X(:), Y(:)]))

[X(:), Y(:)]似乎没有正确的尺寸。此外,我接受向量的函数返回整个输入的一个标量。我需要的是多次退货。

请注意,dissmeasure(music.tone2freq([X(:), Y(:)]))dissmeasure(music.tone2freq([X, Y]))都有效,但dissmeasure的结果是单个标量数,而不是每个x,y对的此函数结果的矩阵。

有任何帮助吗?谢谢

tone2freq.m

function f = tone2freq(T)
% MUSIC.TONE2FREQ converts a musical semitone to a frequency.
%    F = MUSIC.TONE2FREQ(T) converts the musical semitones in T to frequencies.
%
%    Example
%       f = music.tone2freq(0:2);  % returns [261.63  277.19  293.67]
%
%    See also music.tone2interval, music.tone2note, music.freq2tone.

%    Author: E. Johnson
%    Copyright 2010 The MathWorks, Inc.


fC4 = 261.625565300599;  % Middle C (C4) is 261.63 Hz

f = fC4 .* 2 .^ (T / 12);

dissmeasure.m:

% calculate dissonace
% input param fvec - list of frequencies
% input param amp  - list of amplitudes
% output is sum of dissonances of each pair of partials (scalar)
function d = dissmeasure(fvec, amp)
  if ~exist('amp','var')
    amp = ones(size(fvec));
  end 

  Xstar = 0.24;   % place with maximum dissonance

  S1 = 0.0207;    % to fit frequency dependend curves
  S2 = 18.96;     % so max. dissonance occures at 1/4 critical bandwidth

  C1 = 5; 
  C2 = -5;

  B1 = -3.51;     % derived from model of Levelt & Plomp
  B2 = -5.75; 

  N = length(fvec);

  [fvec, idx_list] = sort(fvec);  % sort partial frequencies ascending
  amp = amp(idx_list);            % rearrange amplitude values
  %amp = loudness(amp);

  D = 0;

  for i=2:N
    Fmin = fvec(1 : N-i+1);       % get slice as list of Fmin
    S = Xstar./(S1*Fmin+S2);      % calc list of s-scalings with list of Fmin

    % treat vector as tail and head ...
    Fdif = fvec(i:N) - fvec(1:N-i+1);   % build element wise difference
    a = min(amp(i:N), amp(1:N-i+1));    % select element wise a minimum
    Dnew = a .* (C1*exp(B1*S.*Fdif) + C2*exp(B2*S.*Fdif));

    D = D + sum(Dnew);              % sum up last D and vector elements 
  end

  d=D;

1 个答案:

答案 0 :(得分:1)

您的函数dissmeasure不支持向量化操作,这意味着对于大小为N的输入,将为每个元素计算函数,并返回大小为N的输出。

相反,您的函数会返回汇总的不一致。

%assuming you have X and Y already converted
Z=X*0 % initialize Z of same size
for ix = 1:numel(X)
    Z(ix)=dissmeasure(X(ix),Y(ix));
end