Standardargumente in Matlab

Ist es möglich, Standardargumente in Matlab zu haben? Zum Beispiel hier:

 function wave(a,b,n,k,T,f,flag,fTrue=inline('0')) 

Ich möchte, dass die wahre Lösung ein optionales Argument für die Wellenfunktion ist. Kann dies jemand nachweisen, wenn dies möglich ist? Ich versuche gerade das, was ich oben geschrieben habe und bekomme:

 ??? Error: File: wave.m Line: 1 Column: 37 The expression to the left of the equals sign is not a valid target for an assignment. 

Danke!

105
28 апр. Scott am 28. April eingestellt 2009-04-28 03:46 09 um 03:46 2009-04-28 03:46
@ 15 Antworten

Meines Wissens gibt es keinen direkten Weg, wie Sie es versucht haben.

Der übliche Ansatz besteht darin, Varargs zu verwenden und die Anzahl der Argumente zu überprüfen. So etwas wie:

 function f(arg1,arg2,arg3) if nargin < 3 arg3 = 'some default' end end 

Es gibt einige interessante Dinge, die Sie mit leeren machen können, usw., und Sie möchten die Matlab-Zentralmatrix nach Paketen durchsuchen, die solche Elemente miteinander verknüpfen.

[Update] froh, dass ich geholfen habe.

man kann sich varargin, nargchk usw. anschauen, sie sind nützlich für diese Art von Dingen. Mit varargs können Sie eine variable Anzahl von abschließenden Argumenten belassen. Dies führt jedoch nicht zum Problem der Standardwerte für einige / alle von ihnen.

136
28 апр. beantwortet von simon am 28 Apr. 2009-04-28 03:55 09 um 03:55 2009-04-28 03:55

Ich habe das inputParser Objekt verwendet, um das Festlegen von Standardparametern zu behandeln. Matlab akzeptiert kein Format wie das in der Frage angegebene Python, aber Sie sollten diese Funktion aufrufen können:

 wave(a,b,n,k,T,f,flag,'fTrue',inline('0')) 

Nachdem Sie die wave wie folgt definiert haben:

border=0
 function wave(a,b,n,k,T,f,flag,varargin) i_p = inputParser; i_p.FunctionName = 'WAVE'; i_p.addRequired('a',@isnumeric); i_p.addRequired('b',@isnumeric); i_p.addRequired('n',@isnumeric); i_p.addRequired('k',@isnumeric); i_p.addRequired('T',@isnumeric); i_p.addRequired('f',@isnumeric); i_p.addRequired('flag',@isnumeric); i_p.addOptional('ftrue',inline('0'),1); i_p.parse(a,b,n,k,T,f,flag,varargin{:}); 

Die an die Funktion übergebenen Werte sind i_p.Results über i_p.Results verfügbar. Außerdem war ich nicht sicher, wie ich überprüfen kann, ob der an ftrue Parameter tatsächlich eine inline Funktion ist. ftrue habe ich den Testwert leer gelassen.

53
02 мая '09 в 15:37 2009-05-02 15:37 Die Antwort gibt Matt 02. Mai '09 um 15:37 2009-05-02 15:37

Etwas weniger Hacker-Methode -

 function output = fun(input) if ~exist('input','var'), input='BlahBlahBlah'; end ... end 
18
20 февр. Die Antwort gibt Peter am 20. Februar. 2011-02-20 18:21 '11 um 18:21 2011-02-20 18:21

Ja, es kann sehr schön sein, das tun zu können, was Sie geschrieben haben. Dies ist in MATLAB jedoch nicht möglich. Viele meiner Dienstprogramme, die Standardwerte für Argumente zulassen, werden normalerweise mit expliziten Überprüfungen am Anfang wie folgt geschrieben:

 if (nargin<3) or isempty(myParameterName) MyParameterName = defaultValue; elseif (.... tests for non-validity of the value actually provided ...) error('The sky is falling!') end 

Ok, ich wende normalerweise eine bessere, beschreibendere Fehlermeldung an. Wenn Sie eine leere Variable überprüfen, kann der Benutzer ein leeres Paar [] als Platzhalter für eine Variable übergeben, die den Standardwert akzeptiert. Der Autor sollte weiterhin Code bereitstellen, um dieses leere Argument durch den Standardwert zu ersetzen.

Meine komplexeren Dienstprogramme mit MANY-Parametern, die alle über Standardargumente verfügen, verwenden häufig die Eigenschafts- / Wert-Paar-Schnittstelle für die Standardargumente. Dieses grundlegende Paradigma wird in den Handwriting-Verarbeitungswerkzeugen im Matlab sowie in Optimset, Oodeset usw. behandelt.

Um mit diesen Eigenschafts- / Wert-Paaren arbeiten zu können, müssen Sie etwas über Varargin lernen, um eine vollständig variable Anzahl von Argumenten für eine Funktion einzugeben. Ich habe ein Hilfsprogramm für die Arbeit mit solchen Eigenschafts- / Wert-Paaren parse_pv_pairs.m geschrieben (und gepostet). Dies hilft Ihnen, Eigenschafts- / Wertepaare in eine Matlab-Struktur umzuwandeln. Sie können auch Standardwerte für jeden Parameter angeben. Das Umwandeln einer schwerfälligen Liste von Parametern in eine Struktur ist eine sehr gute Methode, um sie nach MATLAB zu übertragen.

9
28 апр. Die Antwort wird von user85109 April 28 gegeben 2009-04-28 14:56 09 um 14:56 2009-04-28 14:56

Es gibt auch einen Hack, der verwendet werden kann, obwohl er irgendwann aus Matlab entfernt werden kann: Die eval-Funktion benötigt tatsächlich zwei Argumente, von denen das zweite ausgeführt wird, wenn beim ersten ein Fehler aufgetreten ist.

Also können wir verwenden

 function output = fun(input) eval('input;', 'input = 1;'); ... end 

Verwenden Sie den Standardwert 1 für das Argument

3
07 дек. die antwort ist vuakko 07 dec gegeben. 2010-12-07 12:30 '10 um 12:30 Uhr 2010-12-07 12:30 Uhr

Dies ist meine einfache Möglichkeit, mit try Standardwerte für eine Funktion festzulegen:

 function z = myfun (a,varargin) %% Default values b = 1; c = 1; d = 1; e = 1; try b = varargin{1}; c = varargin{2}; d = varargin{3}; e = varargin{4}; end %% Calculation z = a * b * c * d * e ; end 

Hallo!

3
09 июня '15 в 17:01 2015-06-09 17:01 Die Antwort wird von Jonay Cruz am 09. Juni 15 um 17:01 Uhr gegeben

Ich habe festgestellt, dass die Funktion parseArgs sehr nützlich sein kann.

3
29 апр. Die Antwort wird Herrn Fooz am 29. April gegeben 2009-04-29 00:00 09 um 0:00 2009-04-29 00:00

Nachdem ich ASSIGNIN (dank dieser Antwort b3 ) und EVALIN realisiert hatte, schrieb ich zwei Funktionen, um endlich eine sehr einfache Aufrufstruktur zu erhalten:

 setParameterDefault('fTrue', inline('0')); 

Hier ist die Auflistung:

 function setParameterDefault(pname, defval) % setParameterDefault(pname, defval) % Author: Tobias Kienzler (https://stackoverflow.com/users/321973) % sets the parameter NAMED pname to the value defval if it is undefined or % empty if ~isParameterDefined('pname') error('paramDef:noPname', 'No parameter name defined!'); elseif ~isvarname(pname) error('paramDef:pnameNotChar', 'pname is not a valid varname!'); elseif ~isParameterDefined('defval') error('paramDef:noDefval', ['No default value for ' pname ' defined!']); end; % isParameterNotDefined copy since evalin can't handle caller's % caller... if ~evalin('caller', ['exist(''' pname ''', ''var'')  ~isempty(' pname ')']) callername = evalin('caller', 'mfilename'); warnMsg = ['Setting ' pname ' to default value']; if isscalar(defval) || ischar(defval) || isvector(defval) warnMsg = [warnMsg ' (' num2str(defval) ')']; end; warnMsg = [warnMsg '!']; warning([callername ':paramDef:assigning'], warnMsg); assignin('caller', pname, defval); end 

und

 function b = isParameterDefined(pname) % b = isParameterDefined(pname) % Author: Tobias Kienzler (https://stackoverflow.com/users/321973) % returns true if a parameter NAMED pname exists in the caller workspace % and if it is not empty b = evalin('caller', ['exist(''' pname ''', ''var'')  ~isempty(' pname ')']) ; 
2
22 марта '11 в 12:55 2011-03-22 12:55 Die Antwort wird gegeben Tobias Kienzler 22. März 11 um 12:55 2011-03-22 12:55

Es ist mir peinlich, niemand hat diesen Blogeintrag bei Lauren, einem der Entwickler von Matlab, aufgeführt. Der Ansatz basiert auf varargin und vermeidet all diese endlosen und schmerzhaften Fälle mit t120 oder t22 bei gefalteten Bedingungen. Bei mehreren Standardwerten ist der Effekt dramatisch. Hier ist ein Beispiel aus einem verwandten Blog:

 function y = somefun2Alt(a,b,varargin) % Some function that requires 2 inputs and has some optional inputs. % only want 3 optional inputs at most numvarargs = length(varargin); if numvarargs > 3 error('myfuns:somefun2Alt:TooManyInputs', ... 'requires at most 3 optional inputs'); end % set defaults for optional inputs optargs = {eps 17 @magic}; % now put these defaults into the valuesToUse cell array, % and overwrite the ones specified in varargin. optargs(1:numvarargs) = varargin; % or ... % [optargs{1:numvarargs}] = varargin{:}; % Place optional args in memorable variable names [tol, mynum, func] = optargs{:}; 

Wenn Sie es immer noch nicht bekommen, lesen Sie den gesamten Blogeintrag Lauren. Ich habe den folgenden Blogbeitrag geschrieben , in dem fehlende Positionsvorgaben behandelt werden. Ich meine, du könntest so etwas schreiben:

 somefun2Alt(a, b, '', 42) 

und ist standardmäßig auf eps für den Parameter tol (und @magic callback für @magic ) eingestellt. Der Loren-Code erlaubt dies mit einer kleinen, aber komplexen Änderung.

Zum Schluss noch ein paar Vorteile dieses Ansatzes:

  • Auch bei einer großen Anzahl von Standardwerten wird der Vorlagencode nicht sehr groß (im Gegensatz zur Familie der if-then-else Ansätze, die mit jedem neuen Standardwert länger werden).
  • Alle Standardwerte befinden sich an einer Stelle. Wenn einer von ihnen eine Änderung benötigt, haben Sie nur einen Platz zum Suchen.

Sie sagen, dass es einen Fehler gibt. Wenn Sie eine Funktion in die Matlab-Shell eingeben und deren Parameter vergessen, werden Sie als Hinweis einen sinnlosen varargin . Um dies zu bewältigen, sollten Sie einen sinnvollen Verwendungsvorschlag schreiben.

2
06 апр. die antwort ist all3fox 06 apr. 2014-04-06 22:01 14 um 22:01 Uhr 2014-04-06 22:01

Ich bin der Meinung, dass ich einen ziemlich guten Weg gefunden habe, um dieses Problem zu lösen, indem ich nur drei Codezeilen einnehme (Verbot von Zeilenumbrüchen). Folgendes wird direkt aus der Funktion entfernt, die ich schreibe, und es scheint, dass es wie gewünscht funktioniert:

 defaults = {50/6,3,true,false,[375,20,50,0]}; %set all defaults defaults(1:nargin-numberForcedParameters) = varargin; %overload with function input [sigma,shifts,applyDifference,loop,weights] = ... defaults{:}; %unfold the cell struct 

Ich dachte nur, ich würde es teilen.

2
16 янв. Bonnevie antwortete am 16. Januar 2014-01-16 17:18 14 um 17:18 2014-01-16 17:18

Matlab bietet hierfür keinen Mechanismus, aber Sie können ihn in einen benutzerdefinierten Feldcode einbauen, der strenger ist als inputParser oder "if nargin <1 ...".

 function varargout = getargs(args, defaults) %GETARGS Parse function arguments, with defaults % % args is varargin from the caller. By convention, a [] means "use default". % defaults (optional) is a cell vector of corresponding default values if nargin < 2; defaults = {}; end varargout = cell(1, nargout); for i = 1:nargout if numel(args) >= i  ~isequal(args{i}, []) varargout{i} = args{i}; elseif numel(defaults) >= i varargout{i} = defaults{i}; end end 

Dann können Sie es in Ihren Funktionen wie folgt aufrufen:

 function y = foo(varargin) %FOO % % y = foo(a, b, c, d, e, f, g) [a, b, c, d, e, f, g] = getargs(varargin,... {1, 14, 'dfltc'}); 

Die Formatierung ist eine Konvention, mit der Sie Parameternamen mit ihren Standardwerten lesen können. Sie können Ihr getargs () mit zusätzlichen Parameterspezifikationen (zur Fehlererkennung oder impliziten Konvertierung) und Argumentzählbereichen erweitern.

Dieser Ansatz hat zwei Nachteile. Erstens ist es >

1
13 мая '09 в 7:18 2009-05-13 07:18 Die Antwort gibt Andrew Janke am 13. Mai 09 um 07:18 2009-05-13 07:18

Dies wird mehr oder weniger aus dem Matlab-Handbuch entfernt . Ich habe nur die Erfahrung des Passierens ...

 function my_output = wave ( a, b, n, k, T, f, flag, varargin ) optargin = numel(varargin); fTrue = inline('0'); if optargin > 0 fTrue = varargin{1}; end % code ... end 
1
28 апр. Antwort von kyle 28 Apr 2009-04-28 03:59 09 um 03:59 2009-04-28 03:59

Wenn Sie eine Oktave verwenden, können Sie dies wie folgt tun, aber Matlab unterstützt diese Funktion leider nicht.

 function hello (who = "World") printf ("Hello, %s!\n", who); endfunction 

(aus doc entnommen)

0
10 июня '14 в 17:09 2014-06-10 17:09 Die Antwort wird gegeben wuschLOR 10. Juni 14 um 17:09 2014-06-10 17:09

Sie können den Befehl parseparams in matlab verwenden. Die Nutzung wird so aussehen:

 function output = wave(varargin); % comments, etc [reg, props] = parseparams(varargin); ctrls = cell2struct(props(2:2:end),props(1:2:end),2); %yes this is ugly! a = reg{1}; b = reg{2}; %etc fTrue = ctrl.fTrue; 
0
08 окт. die antwort ist gegeben shabbychef 08 oct. 2010-10-08 22:04 10 am 10:04 PM 2010-10-08 22:04
 function f(arg1, arg2, varargin) arg3 = default3; arg4 = default4; % etc. for ii = 1:length(varargin)/2 if ~exist(varargin{2*ii-1}) error(['unknown parameter: ' varargin{2*ii-1}]); end; eval([varargin{2*ii-1} '=' varargin{2*ii}]); end; 

zum beispiel. f(2,4,'c',3) macht den Parameter c gleich 3.

0
11 окт. Die Antwort gibt Tobias Kienzler 11. Okt. 2010-10-11 16:56 '10 um 16:56 2010-10-11 16:56

Andere Fragen zu Labels oder Frage stellen