How do I initialize variables and have them available in the console? - matlab

For example in testinit.m I have the following
function [x, y, m] = testinit
x=4
y=3
m=2
When I run testinit in the console it correctly displays the value. However when I type x it says
error: 'x' undefined...

Just to add to the above answer, the reason you're getting this is because variables in a MatLab function are local variables, they are not passed to the workspace unless you use one of the functions in the above answer. You can read more about global and local variables here.
P.S If you wrote an m-file that is not a function, then the variables are global.

There's the assignin function (evalin is related). And also global.

The other answers are all possible solutions, but potentially more complicated than what you may be looking for. I think the first part of yuk's answer addresses the real problem you are having, but I think it deserves a more detailed explanation...
If you have a function that has output arguments, you need to actually capture those arguments in variables when you call the function. For example, if you typed this in the Command Window:
[x, y, m] = testinit;
Then you would have your three output values present for you to use. What you were probably doing was typing this:
testinit;
This would display the values (because you didn't end each line in the function with a semicolon to suppress displaying them), but it would not store them in variables in the Command Window for you to use later.
This is a result of how variables are stored in MATLAB, as described by the documentation on variable scope:
MATLAB stores variables in a part of memory called a workspace. The base workspace holds variables created during your interactive MATLAB session and also any variables created by running scripts. Variables created at the MATLAB command prompt can also be used by scripts without having to declare them as global.
Functions do not use the base workspace. Every function has its own function workspace. Each function workspace is kept separate from the base workspace and all other workspaces to protect the integrity of the data used by that function. Even subfunctions that are defined in the same file have a separate function workspace.
So, if you want to share variables between functions, the simplest way is to pass them back and forth via their input and output argument lists.
It should also be noted that the names you give variables in the output argument list of the function don't have to match the names of the variables you place those output values in. For example, given this function:
function [a, b, c] = testinit
a = 4;
b = 3;
c = 2;
You can make this call in the Command Window:
[x, y, m] = testinit;
And you will get x = 4, y = 3, and m = 2.

If you run [x, y, m] = testinit in the console you should get the variables. The output variables can have any allowed name, not necessary x, y and m.
In addition you should put ; after each variable assignment in the function to avoid their output to the console. You can control the console output while calling the function.
If you want simply initialize new variables just by typing testinit, use assignin as in #BenVoigt's answer.
assignin('base','x',4)
However, this is dangerous, since some variable may already exist in the calling environment and will be overwritten. You can avoid it adding EXIST tests (inside EVALIN):
function testinit
if ~evalin('base','exist(''x'',''var'')')
assignin('base','x',4)
end
if ~evalin('base','exist(''y'',''var'')')
assignin('base','y',3)
end
if ~evalin('base','exist(''m'',''var'')')
assignin('base','m',2)
end
You can also use 'caller' instead of 'base' if you plan to call the function from another function.

The variables are local to the function so you cannot access them from the command line. As #BenVoigt said, you can use asignin but it's very dirty, and I don't think that it's what you really want to do.
I advise you do go in debug mode
Add a break point or a keyboard to your function like that:
function [x, y, m] = testinit
x=4
y=3
m=2
keyboard
After execute your function, and the command line will remain in the environment of the function.
The usual >> kill be replaced by a K>>. At that point you can access all your local variables.
To quit the debug mode type dbquit, or press shift+F5

Related

using global variable in other functions in matlab [duplicate]

Is there a way to declare global variables in MATLAB?
Please don't respond with:
global x y z;
Because I can also read the help files.
I've declared a global variable, x, and then done something like this:
function[x] = test()
global x;
test1();
end
Where the function test1() is defined as:
function test1()
x = 5;
end
When I run test(), my output is x = []. Is there a way I can make it output the x=5, or whatever I define x to be in a separate function? In C, this would be an external variable, and I thought making it a global variable should accomplish just that.
You need to declare x as a global variable in every scope (i.e. function/workspace) that you want it to be shared across. So, you need to write test1 as:
function test1()
global x;
x = 5;
end
Referring to your comment towards gnovice using a global variable can be an approach to solve your issue, but it's not a commonly used.
First of all make sure that your .m files are functions and not scripts. Scripts share a common workspace, making it easy to unwillingly overwrite your variables. In contrast, functions have their own scope.
Use xUnit in order to generate repeatable unit test for your functions. By testing each function involved in your program you will track down the error source. Having your unit test in place, further code modifications, can be easily verified.
A possible way to get around the global mess is to assign the variable as appdata. You can use the functions setappdata and getappdata to assign and retrieve appdata from a MATLAB window. As long as a MATLAB session is active there exists a window denoted by 0.
>> setappdata(0,'x',10) % 0 indicates the root MATLAB window
Now the variable x is not visible to any script or function but can be accessed wherever needed by using getappdata.
function test
globalX = getappdata(0,'x');
disp(globalX);
end
x =
10
The good news is that you can assign any valid MATLAB object to appdata, just be cautious with the names, using unique names for appdata fields like ModelOptimizerOptions instead of a generic x,y would help. This works on compiled executables and code deployed on the MATLAB production server as well.

What does this matlab statement do

I have a statement in my MATLAB program:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
I understood that f is defined as the function handle to the function distancegauss which contains the parameters/arg list present inside the parentheses.
What does the variable A in #(A) do? Does it have any importance? While browsing I found that the variables within parentheses after # would be the input arguments for an anonymous function..
Can anyone explain what does that A do? Will this handle work even without that A after the # symbol ? Because it is already present as an argument to be passed after the function name.
Your code will create an anonymous function f which accepts one input A. In particular f will call the function DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); where the value of A is whatever you input with f(A) and the other inputs must already exist in your workspace and will be passed to the function. Note: if the other variables don't exist you should get an error when calling f.
Now a reasonable question is why would you want to do this you could just call DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus); directly with whatever values you want, without having to worry about whether some of them exist.
There are two main reasons I can think of why you would do this (I'm sure there are others). Firstly for simplicity where your other inputs don't change and you don't want to have to keep retyping them or have users accidentally change them.
The other reason where you would want this is when optimizing/minimizing a function, for example with fminsearch. The matlab optimization functions will vary all inputs. If you want only vary some of them you can use this sort of syntax to reduce the number of input variables.
As to what A actually is in your case this will depend on what it does in DistanceGauss, which is not a standard MATLAB function so I suggest you look at the code for that.
"f(A)" or "f of A" or "The function of A" here has the handle "f"
DistanceGauss() here is another function that was defined elsewhere in your code.
You would set x_axis, Y_target, Y_initial, numOf, & modus before creating the function f. These arguments would stay the same for Function f, even if you try and set them again later.
'A' though, is different. You don't set it before you make the function. You can later operate on all values of A, such as if you plot the function or get the integral of the function. In that case, it would be performing the DistanceGauss function on every value of 'A', (though we can't see here what DistanceGauss function does. )
Anonymous function should be defined such as:
sqr = #(x) x.^2;
in which x shows the variable of the the function and there is no name for it (it is called anonymous!).
Although you can do something like this:
c = 10;
mygrid = #(x,y) ndgrid((-x:x/c:x),(-y:y/c:y));
[x,y] = mygrid(pi,2*pi);
in which you are modifying an existing function ndgrid to make a new anonymous function.
In your case also:
f = #(A)DistanceGauss(A,x_axis,Y_target,Y_initial,numOf,modus);
This is a new anonymous function by modifying the function DistanceGauss that you may want to have a single variable A.
If you remove (A) from the code, then f would be a handle to the existing function DistanceGauss:
f = #DistanceGauss;
Now you can evaluate the function simply by using the handle:
f(A,x_axis,...)

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.

Declaring a global variable in MATLAB

Is there a way to declare global variables in MATLAB?
Please don't respond with:
global x y z;
Because I can also read the help files.
I've declared a global variable, x, and then done something like this:
function[x] = test()
global x;
test1();
end
Where the function test1() is defined as:
function test1()
x = 5;
end
When I run test(), my output is x = []. Is there a way I can make it output the x=5, or whatever I define x to be in a separate function? In C, this would be an external variable, and I thought making it a global variable should accomplish just that.
You need to declare x as a global variable in every scope (i.e. function/workspace) that you want it to be shared across. So, you need to write test1 as:
function test1()
global x;
x = 5;
end
Referring to your comment towards gnovice using a global variable can be an approach to solve your issue, but it's not a commonly used.
First of all make sure that your .m files are functions and not scripts. Scripts share a common workspace, making it easy to unwillingly overwrite your variables. In contrast, functions have their own scope.
Use xUnit in order to generate repeatable unit test for your functions. By testing each function involved in your program you will track down the error source. Having your unit test in place, further code modifications, can be easily verified.
A possible way to get around the global mess is to assign the variable as appdata. You can use the functions setappdata and getappdata to assign and retrieve appdata from a MATLAB window. As long as a MATLAB session is active there exists a window denoted by 0.
>> setappdata(0,'x',10) % 0 indicates the root MATLAB window
Now the variable x is not visible to any script or function but can be accessed wherever needed by using getappdata.
function test
globalX = getappdata(0,'x');
disp(globalX);
end
x =
10
The good news is that you can assign any valid MATLAB object to appdata, just be cautious with the names, using unique names for appdata fields like ModelOptimizerOptions instead of a generic x,y would help. This works on compiled executables and code deployed on the MATLAB production server as well.

To link a value in an .M-file to a .MAT-file

I'm writing a program in MATLAB to solve integrals, and I have my function in a .M-file. Now I wonder how I can write a program in the .MAT-file that lets the user set a value that exists in the both files. The .M-file looks like this:
function fh = f(y)
fh = 62.5.*(b-y).*(40-20.*exp(-(0.01.*y).*(0.01.*y)));
and as you can see, the function depends on two variables, y and b. I want the user to set b. I tried putting b = input('Type in the value of b: ') in the .M-file but for some reason the user would then have to put in the same value four times.
Can I ask for the value of b in the .MAT-file?
Firstly, m-files store code (i.e. functions), while MAT-files store data (i.e. variables). You can save workspace variables to a MAT-file using the function SAVE and load them into a workspace from a file using the function LOAD. If you have a user choose a value for b, then save it to a MAT-file ('b_value.mat', for example), you can simply load the value from the MAT-file inside your m-file function like so:
function fh = f(y)
load('b_value.mat','b');
fh = 62.5.*(b-y).*(40-20.*exp(-(0.01.*y).*(0.01.*y)));
However, this is not a very good way to handle the larger problem I think you are having. It requires that you hardcode the name of the MAT-file in your function f, plus it will give you an error if the file doesn't exist or if b isn't present in the file.
Let's address what I think the larger underlying problem is, and how to better approach a solution...
You mention that you are solving integrals, and that probably means you are performing numerical integration using one or more of the various built-in integration functions, such as QUAD. As you've noticed, using these functions requires you to supply a function for the integrand which accepts a single vector argument and returns a single vector argument.
In your case, you have other additional parameters you want to pass to the function, which is complicated by the fact that the integration functions only accept integrand functions with a single input argument. There is actually a link in the documentation for QUAD (and the other integration functions) that shows you a couple of ways you can parameterize the integrand function without adding extra input arguments by using either nested functions or anonymous functions.
As an example, I'll show you how you can do this by writing f as an anonymous function instead of an m-file function. First you would have the user choose the parameter b, then you would construct your anonymous function as follows:
b = input('Type in the value of b: ');
f = #(y) 62.5.*(b-y).*(40-20.*exp(-(0.01.*y).^2));
Note that the value of b used by the anonymous function will be fixed at what it was at the time that the function was created. If b is later changed, you would need to re-make your anonymous function so that it uses the new value.
And here's an example of how to use f in a call to QUAD:
q = quad(f,lowerLimit,upperLimit);
In your m file declare b as a global
function fh = f(y)
global b
fh = 62.5.(b-y).(40-20.*exp(-(0.01.y).(0.01.*y)));
This allows the variable to be accessed from another file without having to create another function to set the value of b. You could also add b to the arguments of your fh function.