Undefined 'VARIABLE' error while defining a function in Octave [duplicate] - matlab

I got a problem with running Octave function (ODE), I've tried already present solutions for this problem but nothing is working. I've also tried by saving my filename as egzamin.m but it too not worked.
Code from octave :
function dx=egzamin(x,t)
dx=zeros(4,1);
b=0;
g=9.81;
x1=x(1);
y1=x(2);
Vx=x(3);
Vy=x(4);
dx(1)=Vx;
dx(2)=Vy;
dx(3)=-b*Vx*sqrt(Vx.^2+Vy.^2);
dx(4)=-b*Vy*sqrt(Vx.^2+Vy.^2)-g;
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
The error is :
error: 'x' undefined near line 5 column 4
error: called from
egzamin at line 5 column 3

Since the file starts with function, it is not a script file,
as explained in the doc:
Unlike a function file, a script file must not begin with the keyword
function
Add any statement (even dummy like 1;) before the function line to get a script file.
# dummy statement to get a script file instead of a function file
1;
function dx=egzamin(x,t)
g = 9.81;
Vx = x(3);
Vy = x(4);
dx = [Vx, Vy, 0, -g];
endfunction
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
A very clear explanation of what's going on is given here.

You need to save the function (thus from function to endfunction and naught else) as egzamin.m, and then execute the rest of the code in a script or at the command line. Alternatively, provided Octave does that the same as what MATLAB does nowadays, first put your script (N=(..) to plot()) and then the function.
This is necessary since you are defining your function first, so it doesn't have any inputs yet, as you don't define them until later. The function needs to have its inputs defined before it executes, hence you need to save your function separately.
You can of course save your "script" bit, thus everything which is currently below your function declaration, as a function as well, simply don't give it in- and outputs, or, set all the input parameters here as well. (Which I wouldn't do as it's the same as your
egzamin then.) e.g.
function []=MyFunc()
N=mod(291813,100);
x1=0;
y1=0;
Vx=20+N;
Vy=20+N;
t=0:0.01:500;
sol=lsode("egzamin",[x1,y1,Vx,Vy],t);
plot(sol(:,1),sol(:,2))
endfunction

Related

MATLAB error message "This statement is not inside any function."

I am trying to define a simple function and then call it:
function p=MyExp(N);
p=[ 1 ]; % 0th order polynomial.
for k=1:N
pk=1/(factorial(k));
p=[pk,1];
end
end
poly3=MyExp(3);
disp (poly3)
MATLAB is returning a message:
Error: File: matlab_labIII_3_I.m Line: 10 Column: 1
This statement is not inside any function.
(It follows the END that terminates the definition of the function
"MyExp".)
This script works well on OCTAVE!
Thanks
If you use functions in a Matlab script, you are expected to have all code inside of function(s), of which there can be more than one. Similar products (Octave and Scilab) do not have this restriction.
There's an easy way out with minimal change of code: wrap the non-function code into a function, and invoke that. The main function should appear first in the script.
function MyProgram()
poly3=MyExp(3);
disp (poly3)
end
function p=MyExp(N);
p=[ 1 ]; % 0th order polynomial.
for k=1:N
pk=1/(factorial(k));
p=[pk,1];
end
end
Also, when you use functions, Matlab expects the name of your file to match the name of the function to be called. So, the file should be named MyProgram.m (or whatever your main function is named).

MATLAB symbolic variables couldn't be used in nested function

I have a MATLAB function to solve a Inertia Tensor , and I have a nested function in my program . All the variables in it are symbolics but it told me
“Error using assignin: Attempt to add ”x“ to a static workspace”
and I don't understand why this happens . Here is my test.m code:
function test
syms x y z
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
After searching this web-forum I have found some answers . But at the same time I just don't understand it
Andrew Janke explianed it like this : While syms A may look like a static variable declaration, it isn't. It's just a regular function call. It's using Matlab's "command" invocation style to look like syntax, but it's really equivalent to syms('a', 'b', 'c').
on this page : Matlab: "Error using assignin: Attempt to add "c" to a static workspace"
what does static variable mean ?
I also search the HELP doc and it said :In functions and scripts, do not use syms to create symbolic variables with the same names as MATLAB® functions. For these names MATLAB does not create symbolic variables, but keeps the names assigned to the functions.
I only know syms x to create a symbolic variable in the workspace but why does the documentation say MATLAB does not create ?
'Static' means fixed, 'workspace' is what Matlab calls the places where all of its variables are stored. For non-nested functions the workspace starts off as empty when Matlab is at the beginning of the function; as Matlab continues through function's lines of code it continuously add more variables to the workspace.
For functions with a nested function, Matlab first parses the function to see what variable will be created (it specifically looks for x = type lines), then it creates all of these variables (with value as 'unassigned'), and then only does it start to run through the code; but while running through the code, it can never create a new variable.
This is why the code
function TestNestedFunction
syms x;
function Nested()
end
end
generates an error, there is no x = to tell it to pre-create the unassigned variable x at the start of the code. It fails at syms x;, as that line tries to create a new variable x, which fails as it may not.
This is also why the following code runs
function TestNestedFunction
syms x;
x = x;
function Nested()
end
end
it sees the x = and then pre-creates x. (This is why your example of adding [x, y, z] = deal([]); also works).
You can test this with a break point at the beginning of simple non-nested function and a simple nested function. Just run it step by step.
This code works:
function test
x=sym('x')
y=sym('y')
z=sym('z')
f=x
f1=f+1
f2=f1^2
function r=test2
r=f2^3;
end
f3=test2
end
I think the pages you found are quite clear.
You need to declare the variables one by one and use:
x = sym('x')
Otherwise syms will try to assign the values into a workspace where this is not allowed.

Problems with Embedded Functions within Simulink

I'm trying to simulate a very simple model using an embedded matlab function that takes the input and add's 10 to the value using a constant block that inputs into the matlab function, which then outputs to a display block.
As soon as I press simulate I get an abundance of errors. First I get a huge paragraph in orange text stating a warning out the solver 'variableStepDiscrete' instead of solver 'ode45'
Here is the remaining lines that are echo'd from the command prompt:
Code Directory :
"/Users/dazgti/Documents/MATLAB/slprj/_sfprj/embeddedFunction/_self/sfun/src"
Machine (#32): "embeddedFunction" Target : "sfun"
Chart "MATLAB Function" (#49):
.
"c2_embeddedFunction.h"
"c2_embeddedFunction.c"
"embeddedFunction_sfun.h"
"embeddedFunction_sfun.c"
"embeddedFunction_sfun_debug_macros.h"
Interface and Support files:
"embeddedFunction_sfun_registry.c"
Code generation failed Attempt to execute SCRIPT union as a function:
/Users/dazgti/Documents/MATLAB/union.m
I have a script file within my matlab directory called union.m, but I have no idea why its mentioning it.
function y = fcn(u)
%#codegen
x = u + 10;
y = x;
MATLAB Function block works by generating "C" code for the MATLAB code you entered in the block. In the process of generating code there could have been a call to union function in MATLAB from MATLAB Function block infrastructure. Since you have overridden the union function instead of the built-in function MATLAB might have attempted to call your script which caused the error. It is better to avoid naming your functions same as MATLAB built-in functions.

How to wrap an already existing function with a new function of the same name

Is it possible to create a wrapper around a function that has the exact same name as the original function?
This would be very useful in circumstances where the user wants to do some additional checks on input variables before they are passed on to the built in function How to interrupt MATLAB IDE when it hangs on displaying very large array?
Actually alternatively to slayton's answer you don't need to use openvar. If you define a function with the same name as a matlab function, it will shadow that function (i.e. be called instead).
To then avoid recursively calling your own function, you can call the original function from within the wrapper by using builtin.
e.g.
outputs = builtin(funcname, inputs..);
Simple example, named rand.m and in the matlab path:
function out = main(varargin)
disp('Test wrapping rand... calling rand now...');
out = builtin('rand', varargin{:});
Note that this only works for functions that are found by builtin. For those that are not, slayton's approach is likely necessary.
Yes this is possible but it requires a bit of hacking. It requires that you copy around some function handles.
Using the example provided in the question I will show how to wrap the function openvar in a user defined function that checks the size of the input variable and then allows the user to cancel any open operation for variables that are too large.
Additionally, this should work when the user double clicks a variable in the Workspace pane of the Matlab IDE.
We need to do three things.
Get a handle to the original openvar function
Define the wrapper function that calls openvar
Redirect the original openvar name to our new function.
Example Function
function openVarWrapper(x, vector)
maxVarSize = 10000;
%declare the global variable
persistent openVarHandle;
%if the variable is empty then make the link to the original openvar
if isempty(openVarHandle)
openVarHandle = #openvar;
end
%no variable name passed, call was to setup connection
if narargin==0
return;
end
%get a copy of the original variable to check its size
tmpVar = evalin('base', x);
%if the variable is big and the user doesn't click yes then return
if prod( size( tmpVar)) > maxVarSize
resp = questdlg(sprintf('Variable %s is very large, open anyway?', x));
if ~strcmp(resp, 'Yes')
return;
end
end
if ischar(x) && ~isempty(openVarHandle);
openVarHandle(x);
end
end
Once this function is defined then you simply need to execute a script that
Clears any variables named openvar
run the openVarWrapper script to setup the connection
point the original openVar to openVarWrapper
Example Script:
clear openvar;
openVarWrapper;
openvar = #openVarWrapper;
Finally when you want to clean everything up you can simply call:
clear openvar;
I prefer jmetz's approach using builtin() when it can be applied, because it is clean and to the point. Unfortunately, many many functions are not found by builtin().
I found that I was able to wrap a function using a combination of the which -all and cd commands. I suspect that this approach can be adapted to a wide variety of applications.
In my example case, I wanted to (temporarily) wrap the interp1 function so that I could check for NaN output values. (The interp1 function will, by default, return a NaN under some conditions, such as if a query point is larger than the largest sample point.) Here's what I came up with:
function Vq = interp1(varargin)
persistent interp1_builtin;
if (isempty(interp1_builtin)) % first call: handle not set
toolbox = 'polyfun';
% get a list of all known instances of the function, and then
% select the first such instance that contains the toolbox name
% in its path
which_list = which('interp1','-all');
for ii = 1:length(which_list)
if (strfind(which_list{ii}, [filesep, toolbox, filesep]))
base_path = fileparts(which_list{ii}); % path to the original function
current_path = pwd;
cd(base_path); % go to the original function's directory
interp1_builtin = #interp1; % create a function handle to the original function
cd(current_path); % go back to the working directory
break
end
end
end
Vq = interp1_builtin(varargin{:}); % call the original function
% test if the output was NaN, and print a message
if (any(isnan(Vq)))
dbstack;
disp('ERROR: interp1 returned a NaN');
keyboard
end
end
See also: How to use MATLAB toolbox function which has the same name of a user defined function

Passing a defined function to ODE solver

I have defined a function
function dy = toggle(t,y,p)
dy = zeros(2,1);
dy(1) = - y(1) + p(1)./(1+y(2).^p(2));
dy(2) = - y(2) + p(1)./(1+y(1).^p(3));
and saved it in an .m file with the same name as the function. In another file, caltoggle.m, I write:
[T,Y] = ode45(#toggle,[0 100],[0.2,0.1],[],[3,2,2]);
When I run the script caltoggle.m I get the error:
??? [T,Y] = ode45(#
|
Missing variable or function.
Error in ==> C:\MATLABR11\work\caltoggle.m
On line 1 ==>
caltoggle
The above code is an example from a tutorial so should be right. My problem is in general I am not able to call a defined function.
If the other file is not in the same directory, you should add the directory to the path.
Try to write in Matlab:
pathtool
Also, though it is probably not your case, if you name a file with a reserved word like "try", it can cause havoc.
Also, try to write
which toggle
it might be insightful.
In the Matlab documentation for the ODE solvers all of the examples pass as the first argument to ode45 a function of 2 variables, not three like your function toggle. Can you change your toggle function to accept only two input arguments and see if that fixes the problem (as a first test just set p(:)=1 or something similar)