4

我有一個MATLAB文件,其中包含一個頂級函數​​。該函數又包含兩個嵌套函數,即mysummyprod,它們的功能和參數相同,除了一個在內部使用@sum,而另一個在內部使用@prod。我的目標是創建一個包裝函數,用於處理mysummyprod中的所有驗證和輸入解析。這個功能被稱爲applyFunc如何在可選字符串輸入中使用MATLAB的inputParser?該文件說「使用驗證功能」,但目前還不清楚如何做到這一點

這裏是棘手的地方。 mysummyprod有兩種形式:

  1. mysum(v)回報sum(v, 1)
  2. mysum(v, 'imag')sum(v, 1) + 1i返回

輸入的任何其它的組合應引發錯誤。

我在使用inputParser解析輸入的各種組合時遇到問題,特別是可選的字符串輸入。下面的代碼:

function sandbox() 
%% Data 
v = [1 4; 3 3]; 

%% Calculations 
s = mysum(v); 
si = mysum(v, 'imag'); 
p = myprod(v); 
pi = myprod(v, 'imag'); 

%% Accuracy tests 
assert(isequal(s, [4 7])) 
assert(isequal(si, [4+1i 7+1i])) 
assert(isequal(p, [3 12])) 
assert(isequal(pi, [3+1i 12+1i])) 

    function x = mysum(varargin) 
     x = applyFunc(@sum, varargin{:}); 
    end 

    function x = myprod(varargin) 
     x = applyFunc(@prod, varargin{:}); 
    end 
end 

function x = applyFunc(func, varargin) 

p = inputParser(); 
p.addRequired('func', @(x) validateattributes(x, {'function_handle'}, {'scalar'})); 
p.addRequired('v', @(x) validateattributes(x, {'double'}, {}, 'applyFunc:msg', 'v')); 
p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''})); % THIS LINE IS THE PROBLEM 
p.parse(func, varargin{:}); 

f = p.Results.func; 
v = p.Results.v; 
strflag = p.Results.imag; 

x = f(v); 
if ~isempty(strflag) 
    validatestring(strflag, {'imag'}); 
    x = x + 1i; 
end 
end 

是造成該問題的行這一個(如標註在上面的代碼中):

p.addOptional('imag', '', @(x) validatestring(x, {'imag', ''})); 

爲inputParser文檔說:

For optional string inputs, specify a validation function. Without a validation function, the input parser interprets valid string inputs as invalid parameter names and throws an error.

不幸的是,我不知道如何做到這一點。有什麼簡單的我失蹤或什麼?如果'imag'說法是沒有(如在sp分配)通過,代碼工作正常,但如果我不通過它,我得到這個錯誤:

Error using sandbox>applyFunc (line 32) 
The value of 'imag' is invalid. It must satisfy the function: 
@(x)validatestring(x,{'imag',''}). 
Error in sandbox/mysum (line 18) 
     x = applyFunc(@sum, varargin{:}); 
Error in sandbox (line 7) 
si = mysum(v, 'imag'); 

任何幫助嗎?

回答

4

問題是validatestring返回單元格參數({'imag',''})中的匹配字符串,而不是布爾值,指示它是否通過驗證。相反,使用strcmpany

@(x) any(strcmp(x,{'imag', ''})) 

而且,與validatestring,如果輸入的字符串不匹配或者'imag'''(其實只是'imag'因爲空字符串只在R2014a +匹配),它會拋出一個錯誤,而不是返回false以便inputParser可以返回相應的錯誤。

另一種很好的方式來解決這個問題是要改變的applyFunc語法完全讓,而不是隻'imag'作爲一個可選的字符串輸入參數,使用Parameter-Value'imag'作爲參數和經過驗證的布爾值作爲輸入。

評價通過荷銀建議的輸入定義:

p.addParameter('imag', false, @(x)validateattributes(x, {'logical'}, {'scalar'})) 

用法:

mysum(x,'imag',true) 
mysum(x)    % default is equivalent to mysum(x,'imag',false) 

這將簡化的代碼的其餘部分與p.Result.imag是一個logical標量。我建議:

x = f(v) + p.Result.imag*1i; 
+3

+1使用'strcmp'解決了這個問題。我個人不喜歡「可選參數」,我寧願使用名稱值參數參數:'p.addParameter('imag',false,@(x)validateattributes(x,{'logical'},{'標量'}))'。那麼'p.Result.imag'可能是真或假。 – Amro

+0

這是在代碼中稍後清理比較的好方法。它可能是具有邏輯值的參數值參數。 – chappjc

+0

@chappjc感謝您的幫助。我真的很喜歡使用名稱 - 值對而不是可選參數,所以我可能會將它用於新代碼。不幸的是,我現在正在使用的代碼是不允許更改的API的遺留問題。 –

1

問題不inputParser,我認爲這個問題是validatestring

1)首先,它不匹配空字符串:

>> x = '' 
x = 
    '' 

>> validatestring(x, {'imag',''}) 
Expected input to match one of these strings: 

imag, 

The input did not match any of the valid strings. 
Caused by: 
    Error using validatestring>checkString (line 85) 
    Expected input to be a row vector. 

2)其次,如果匹配成功,它返回解析字符串(從有效的選擇之一),而不是真/假。 inputParser要求驗證功能要麼返回一個布爾值,要麼失敗時拋出錯誤。

+0

你見過R2014a預發佈發行說明嗎?現在似乎是一個空的字符串匹配。就好像MathWorks讀取SO一樣。 :) – chappjc

+0

我還沒有看到預售,但這是個好消息。感謝您讓我們知道..出於好奇,預售中是否有重大變化? HG2圖形也許? – Amro

+0

HG2不是默認設置。當你在命令行上點擊向上鍵時,會出現一個令人討厭的新彈出命令歷史記錄。 MEX設置現在更容易,但是使用單獨的C和C++配置(前面我看到質量混亂)。 「flipud」,「fliplr」和「rot90」命令現在可用於多維數組,但語法已更改。一些新的測試功能,例如'issymmetric','isdiag'等。 – chappjc

相關問題