Not enough input argument for GUI
조회 수: 7 (최근 30일)
이전 댓글 표시
Hi everyone. I am a student, I have a project which need me to create a GUI with 4 differents functions and 4 differents data. I already tried by using 2 different functions and I can run the GUI. but when I tried to run the GUI with 4 different functions I keep on getting the error,
Not enough input arguments.
Error in Covid_model_App/f (line 59)
b(16)=(str2double(get(handles.user_eovump,'String')))/100;
Error in Covid_model_App>@(varargin)app.f(varargin{:}) (line 396)
[tsol,xsol] = ode45(@app.f,tspan,x0);
Error in odearguments (line 90)
f0 = feval(ode,t0,y0,args{:}); % ODE15I sets args{1} to yp0.
Error in ode45 (line 106)
odearguments(FcnHandlesUsed, solver_name, ode, tspan, y0, options, varargin);
Error in Covid_model_App/start_sg_Callback (line 396)
[tsol,xsol] = ode45(@app.f,tspan,x0);
Error while evaluating Button PrivateButtonPushedFcn.
Is there anyone can help me? What is means by 'not eneough input arguments'? Thank you in advance for your help.
댓글 수: 2
채택된 답변
Jan
2023년 3월 2일
"Not enough input arguments" mean, that you call a function with less input arguments that needed.
This line;
[tsol,xsol] = ode45(@app.f,tspan,x0);
let ODE45 call app.f with 2 inputs t and x. You try to access handles in the code, which might be a 3rd input (Please post the ocde to clarify this. It is always hard to fix code which cannot be seen.).
It is a bad design to store the function to be integrated as function handle inside the GUI. Keep code for calculations and GUI separated. Move the contents of app.f to a separate function and provide the contents of handles.user_eovump as parameter:
% in Covid_model_App/start_sg_Callback (line 396)
b = str2double(get(handles.user_eovump,'String')) / 100;
[tsol, xsol] = ode45(@(t, x) yourFcn(t, y, b, tspan, x0);
function dx = yourFcn(t, x, b)
... your function to be integrated
end
By this way, the function can be integrated independently from the GUI also, e.g. in a bacth job or loop.
댓글 수: 4
Jan
2023년 3월 5일
You define the function f() in line 523:
function dx = f(t,x,handles)
...
b(16)=(str2double(get(handles.user_eovump,'String')))/100;
end
In line 139 you call it:
callm = @(t,x)m(t,x,handles); % Not used later
tspan = [0:1:max(tdata)];
[tsol,xsol] = ode45(@f,tspan,x0);
% ^^
If you provide a function handle to ODE45, it is called with the input arguments (t,x), but f requires 3 inputs. Maybe this is wanted instead:
callf = @(t,x) f(t,x,handles);
tspan = 0:1:max(tdata); % No [] needed: This is a vector already
[tsol,xsol] = ode45(@callf, tspan, x0);
The same here:
callz = @(t,x)z(t,x,handles); % Line 258. Not used!
tspan = [0:1:max(tdata)];
[tsol,xsol] = ode45(@f,tspan,x0);
You see a warning in the editor about the unused variable callz. Do not ignore such warnings, because you see, that they point to bugs in the code in your case. Use this valuable information and clean up these warnings.
It would be smarter to avoid forwarding the handles struct to the function to be integrated. Doing so mixes the GUI and the actual calculations. Cleaner:
b16 = str2double(get(handles.user_eovump, 'String')) / 100;
callf = @(t,x) f(t, x, b16);
...
% And in the definition of f:
function dx = f(t, x, b16)
...
b(16) = b16;
end
There is a lot of repeated code, which is a common source of bugs. If you modify one, it is easy to oversee the other locations which required a modification also. Prefer to use only one function instead and control the different behavior by providing different parameters.
Global variables are a shot in your knee also, because they impede the debugging.
Lines without any effect are confusing only and waste time:
size(data_t); % No output, no effect - omit this line.
This command:
getpara(handles);
modifies the handles struct internally, but does not provide the changes to the caller. So nothing happens. Most likely you mean:
handles = getpara(handles);
Then changes are kept.
Finally a numerical problem: Matlab's ODE integrators are designed to handle differentiable functions only. Your functions f,z,m,y are not differentiable due to the if t < 29 switching. This let the step size control of the integrator run into trouble. If you are lucky, you get a warning about to small stepsizes. But with less luck, ODE45 reduces the stepsize until the rounding errors let the discontinuity vanish. You will get a final result, but from the viewpoint of numerical maths, it is more or less random and cannot be treated as "result".
A reliable solution is to let the integration stop at such steps and restart it using the old final values and new initial values. This would be much easier, if you use the GUI to determine the parameters only and move the integration to a separate function.
추가 답변 (0개)
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!