【问题标题】:MATLAB Create surface plot of function for all X, Y pairsMATLAB 为所有 X、Y 对创建函数曲面图
【发布时间】:2015-10-20 14:53:28
【问题描述】:

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

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

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

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;

【问题讨论】:

  • .s 有什么用?例如[X., Y.]?此外,您的错误是因为您在这一行 Z = myfunc([X(:), Y(:)])) 中有一个额外的 )。最后,您需要发布myfunc...的代码...
  • 如果Z = myfunc([X(:), Y(:)])) 不起作用,可能是您的函数有问题。请将代码添加到您的问题中。
  • 正如目前所写,在您的声明末尾有一个额外的)...应该是Z = myfun([X(:), Y(:)])
  • 我添加了函数源和更多信息,包括我所追求的示例网格
  • 请注意[X., Y.] 中的点只是因为我认为这是“每个单独”的符号

标签: matlab


【解决方案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

【讨论】:

  • 你能告诉我我需要做什么来实现我的目标吗?
  • 请注意,这很好。我想要聚合 dissmeasure 函数。我现在需要的是分别评估所有 x,y 对
  • 使用循环并为每一对单独调用它。
  • 你能发布一些关于如何实现这一点的代码吗?您是否建议调整 dissmeasure 函数,使其适用于向量或使用循环?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多