0
votes

I have created a matlab GUI in which a user selects a variable to integrate with respect to, inputs the equation, and lower and upper limits. When my code goes to calculate the integral on pushbutton Callback, I get an error I don't understand.

This is the line of code causing the error:

i1 = int( eval(get(handles.edit1,'string')),
          (handles.respectvar), 
          get(handles.edit3),
          get(handles.edit2)
        );

%respactvar is the user-selected variable, and edit3 and edit2 are the lower and upper limits.

And this is the error message:

Error using sym>tomupad (line 1135) Conversion to 'sym' from 'struct' is not possible.

Error in sym (line 151) S.s = tomupad(x);

Error in sym/int (line 142) b = sym(b);

Error in projectCALC>pushbutton1_Callback (line 376) i1=int(eval(get(handles.edit1,'string')),(handles.respectvar),get(handles.edit3),get(handles.edit2));

Error in gui_mainfcn (line 95) feval(varargin{:});

Error in projectCALC (line 42) gui_mainfcn(gui_State, varargin{:});

Error in @(hObject,eventdata)projectCALC('pushbutton1_Callback',hObject,eventdata,guidata(hObject))

Error while evaluating UIControl Callback

Thank you!

1
You need to get the strings from the edit boxes containing your integration limits and convert them to a numeric data type. get(handles.edit3) will just return a structure of the properties of the object.excaza
Also, using eval is inefficient and unsafe, especially if you're evaluating something that the user input in the box. What if it's a system call? Are you sure you can't avoid using eval?Andras Deak
@AndrasDeak Though this doesn't address the security concern, I don't think there's any way around eval for this kind of thing. I'm almost positive str2func is just a wrapper for eval but I don't have MATLAB available to check.excaza
@excaza the doc says str2func could be used instead of eval in many cases, suggesting that it's better. And on R2012b str2func('system(''echo oops!'')') will issue a warning (to be an error in a future release) and not execute the command (OK, of course str2func('@() system(''echo oops!'')') can be evaluated by int to cause harm still). Also, str2func is a compiled built-in.Andras Deak
@excaza Thank you for your help! I put the get(handles.edit3) and the other one inside of a str2double(). I am no longer getting errors, but my results box displays NaN no matter what I type in. i1=int(eval(get(handles.edit1,'string')),(handles.respectvar),str2double(get(handles.edit3)),str2double(get(handles.edit2)));Carly Hauser

1 Answers

0
votes

There are multiple problems with your code.

The first problem, as @excaza noted, is that you forgot to get the string property of the last two edit boxes, while you did this for the first one.

The second problem is that eval is very inefficient, and, in your case, very unsafe. What if somebody wrote a system() call into the editbox, erasing your hard drive?

The third problem is that even with eval or str2func, int requires its first argument to be a symbolic expression. This is a good thing: you don't actually have to use eval, you just have to convert your first string to a sym.

The fourth problem is that handles.respectvar also seems to be a GUI object, so you might need to get() some property for it in order to be able to use it as an integration variable.

Assuming that my suspicion is correct, and your edit1 contains a string like '3*x+y', edit2 and edit3 are limits such as '1' and '3', and handles.respectvar has a property that evaluates to 'x', then you should be calling

formula = sym(get(handles.edit1,'string'));
variable = handles.respectvar;    %// more likely: get(handles.respectvar,...)
lim1 = str2double(get(handles.edit3,'string'));
lim2 = str2double(get(handles.edit2,'string'));
i1 = int(formula,variable,lim1,lim2);

A few notes:

  • Don't be afraid of using temporary variables where it helps in readability.
  • I converted the formula from sym to string, otherwise you get a warning or an error (depending on MATLAB version)
  • I left the order of lim1 <-> edit3, lim2 <-> edit2. Make sure this is indeed what you want, and orders are not reversed.
  • I converted the integration limits to double, but it seems that sym/int will also accept string input as the limit variables, so this is mostly for clarity.