Update a M.file variables from command windows in Matlab? - matlab

I have a simple but interesting question. i tired hard to google it but my google got upset and giving me the same results...
i wanted to know is it possible to Update a constant variable form workspace command..
A Simple Example:
function y =StupidQuestion
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
y = b*a % some operation
I forget to tell you that we can do it with simulink block by using below command
set_param('obj', 'parameter1', value1, 'parameter2', value2, ...)
i Want to use the assigned value for 3 weeks and without any reason i wants to change my values [a,b] to other but through command windows. any Idea. Waiting for your interesting Reply...................

You can set defaults for the inputs:
function y = foo(a,b)
if nargin < 1 || isempty(a), a = 10; end
if nargin < 2 || isempty(b), b = [5,6,7;1,2,8]; end
y = b*a
end
You can call foo() without inputs (and it will use the defaults for a and b) or supply your own values as: foo(12), foo(12,[10,20]), foo([],[23,23]), etc...

A possible way is to save some variables in an external file. Note that in this case a and b are only in the function workspace (you won't see their values unless you load the contents of test.mat separately). I'm passing the filename in rather than hard-coding it in case you need to switch between multiple settings.
Personally I would prefer to have a human-readable data file, but the concept remains the same (you'd just need some parser function which returned values for a and b given a file).
a = 10; % some value
b =[5,6,7;1,2,8]; % some value
save('test.mat','a','b');
clear a b;
function y = savedvariables(filename)
load(filename);
y = b*a; % some operation
end
y = savedvariables('test.mat');

Related

What does the code '[~, width ] = size(I);'mean?I can't undestand '~'especially [duplicate]

Is it possible to get the 'nth' return value from a function without having to create dummy variables for all n-1 return values before it?
Let's say, I have the following function in MATLAB:
function [a,b,c,d] = func()
a = 1;
b = 2;
c = 3;
d = 4;
Now suppose, I'm only interested in the third return value. This can be accomplished by creating one dummy variable:
[dummy, dummy, variableThatIWillUse, dummy] = func;
clear dummy;
But I think this is kind of ugly. I would think that you might be able to do something like one of the following things, but you can't:
[_, _, variableThatIWillUse, _] = func;
[, , variableThatIWillUse, ] = func;
variableThatIWillUse = func(3);
variableThatIWillUse = func()(3);
Are there any elegant ways to do this that do work?
So far, the best solution is to simply use the variableThatIWillUse as a dummy variable. This saves me from having to create a real dummy variable that pollutes the work-space (or that I would need to clear). In short: the solution is to use the variableThatIWillUse for every return value up until the interesting one. Return values after can simply be ignored:
[variableThatIWillUse, variableThatIWillUse, variableThatIWillUse] = func;
I still think this is very ugly code.
With MATLAB Version 7.9 (R2009b) you can use a ~, e.g.,
[~, ~, variableThatIWillUse] = myFunction();
Note that the , isn't optional. Just typing [~ ~ var] will not work, and will throw an error.
See the release notes for details.
This is somewhat of a hack, but it works:
First a quick example function:
Func3 = #() deal(1,2,3);
[a,b,c]=Func3();
% yields a=1, b=2, c=3
Now the key here is that if you use a variable twice on the left-hand side of a multiple-expression assignment, an earlier assignment is clobbered by the later assignment:
[b,b,c]=Func3();
% yields b=2, c=3
[c,c,c]=Func3();
% yields c=3
(Just to check, I also verified that this technique works with [mu,mu,mu]=polyfit(x,y,n) if all you care about from polyfit is the third argument.)
There's a better approach; see ManWithSleeve's answer instead.
If you wish to use a style where a variable will be left to fall into the bit bucket, then a reasonable alternative is
[ans, ans, variableThatIWillUse] = myfun(inputs);
ans is of course the default junk variable for MATLAB, getting overwritten often in the course of a session.
While I do like the new trick that MATLAB now allows, using a ~ to designate an ignored return variable, this is a problem for backwards compatibility, in that users of older releases will be unable to use your code.
I generally avoid using new things like that until at least a few MATLAB releases have been issued to ensure there will be very few users left in the lurch. For example, even now I find people are still using an old enough MATLAB release that they cannot use anonymous functions.
Here's another option you can use. First make a cell array to capture all the outputs (you can use the NARGOUT function to determine how many outputs a given function returns):
a = cell(1,3); % For capturing 3 outputs
% OR...
a = cell(1,nargout(#func)); % For capturing all outputs from "func"
Then call the function as follows:
[a{:}] = func();
Then simply remove the element from a that you want, and overwrite a:
a = a{3}; % Get the third output
I wrote a kth out function:
function kth = kthout(k, ffnc, varargin)
% kthout: take the kth varargout from a func call %FOLDUP
%
% kth = kthout(k, ffnc, varargin)
%
% input:
% k which varargout to get
% ffnc function to call;
% varargin passed to ffnc;
% output:
% kth the kth argout;
[outargs{1:k}] = feval(ffnc, varargin{:});
kth = outargs{k};
end %function
You can then call
val_i_want = kthout(3, #myfunc, func_input_1, func_input_2);
You could also wrap up the function like:
func_i_want = #(varargin)(kthout(3, #myfunc,varargin{:})); % Assuming you want the third output.
After which you use
val_i_want = func_i_want(func_input_1, func_input_2);
Note that there is overhead associated with using anonymous functions like this, and this is not something I would do in code that would be called thousands of times.
In MATLAB 2010a, I found a neat way of doing what you are asking for.
It is simply to use the character "~" (without the quotes of course) as your dummy variable (as many as you want when returning multiple parameters). This also works for input parameters to functions if the functions are designed to handle missing data.
I don't know if this existed in previous versions, but I just came across it recently.
You can make a function (or anonymous function) that only returns selected outputs, e.g.
select = #(a,b) a(b);
Then you can call your function like this:
select(func,2);
select(func,1:3);
Or you can assign the output to a variable:
output(1,2:4) = select(func,1:3);
I don't see any reason not to use ans(n). Like this:
size(rand([5 10 20 40]));
b = ans(2);
It gives b = 10, and this way would be compatible with all MATLAB versions. Note that size() here is just used to represent any function that has multiple return variables.
Furthermore, this works to get the second output argument when you don't know how many arguments there will be! Whereas, if you do this:
[~, b] = size(a);
Then b = 8000! (You need to end with ~, to catch more arguments!)

Looping a Function in Matlab

total newbie here. I'm having problems looping a function that I've created. I'm having some problems copying the code over but I'll give a general idea of it:
function[X]=Test(A,B,C,D)
other parts of the code
.
.
.
X = linsolve(K,L)
end
where K,L are other matrices I derived from the 4 variables A,B,C,D
The problem is whenever I execute the function Test(1,2,3,4), I can only get one answer out. I'm trying to loop this process for one variable, keep the other 3 variables constant.
For example, I want to get answers for A = 1:10, while B = 2, C = 3, D = 4
I've tried the following method and they did not work:
Function[X] = Test(A,B,C,D)
for A = 1:10
other parts of the code...
X=linsolve(K,L)
end
Whenever I keyed in the command Test(1,2,3,4), it only gave me the output of Test(10,2,3,4)
Then I read somewhere that you have to call the function from somewhere else, so I edited the Test function to be Function[X] = Test(B,C,D) and left A out where it can be assigned in another script eg:
global A
for A = 1:10
Test(A,2,3,4)
end
But this gives an error as well, as Test function requires A to be defined. As such I'm a little lost and can't seem to find any information on how can this be done. Would appreciate all the help I can get.
Cheers guys
I think this is what you're looking for:
A=1:10; B=2; C=3; D=4;
%Do pre-allocation for X according to the dimensions of your output
for iter = 1:length(A)
X(:,:,iter)= Test(A(iter),B,C,D);
end
X
where
function [X]=Test(A,B,C,D)
%other parts of the code
X = linsolve(K,L)
end
Try this:
function X = Test(A,B,C,D)
% allocate output (it is faster than changing the size in every loop)
X = {};
% loop for each position in A
for i = 1:numel(A);
%in the other parts you have to use A(i) instead of just A
... other parts of code
%overwrite the value in X at position i
X{i} = linsolve(K,L);
end
end
and run it with Test(1:10,2,3,4)
To answer what went wrong before:
When you loop with 'for A=1:10' you overwrite the A that was passed to the function (so the function will ignore the A that you passed it) and in each loop you overwrite the X calculated in the previous loop (that is why you can only see the answer for A=10).
The second try should work if you have created a file named Test.m with the function X = (A,B,C,D) as the first code in the file. Although the global assignment is unnecessary. In fact I would strongly recommend you not to use global variables as it gets very messy very fast.

Matlab: Automatically create cell array with name with meaning

I would like to name variable (type double) in the following way:
k0 = D(1,1);
k1 = D(2,2);
k2 = D(3,3);
k3 = D(4,4);
k4 = D(5,5);
k5 = D(6,6);
k6 = D(7,7);
k7 = D(8,8);
...
up to k99 automatically using for loop. So I see that I should use array or cell instead of double variable using eval as it is slow. But if I should use array or cell instead of double variable, I have to start at k{1} or k(1), which loses the meaning as I want exactly that k0 refers to D(1,1), i.e. the number in my variable is 1 less. How do I create meaningful cell name like k{0}?
Also, say I have an array A. There are also some times i need meaningful variable name, such as
c111 = A(1)*A(1)*A(1)
c222 = A(2)*A(2)*A(2)
c333 = A(3)*A(3)*A(3)
How can I create c{111} efficiently using for loop?
Use structures:
D = rand(21);
c = 1;
for k = -10:10
if k<0
s.(['k_' num2str(abs(k))]) = D(c,c);
else
s.(['k' num2str(k)]) = D(c,c);
end
c = c+1;
end
This will give you a structure like:
s =
k_10: 0.51785
k_9: 0.90121
k_8: 0.40746
k_7: 0.092989
.
.
k_1: 0.75522
k0: 0.55257
k1: 0.28708
.
.
k9: 0.94182
k10: 0.2124
and don't use eval...
Answer to 1st Question:-
D=randn(100); % A matrix of random elements of size 8x8
for m=0:99
assignin('base', ['k' num2str(m)], D(m+1,m+1))
end
Answer to 2nd Question:-
A=randn(1,3); % An array of 3 random elements
for n=1:3
assignin('base', ['c' num2str(111*n)], A(n)^3)
end
Comments:-
You've stated that you need variables like k0,k1,k2,... and c111,c222,c333 but you're asking how to create k{0}, k{1},k{2},... and c{111},c{222},c{333}. As far as your need is concerned, I have given answer to it. Regarding the latter, k{0} is never possible and c{111},c{222},c{333},... don't make good sense without using any of the first 0:100 values and then 112:221 values and so on. Although you can do it using:
A=rand(1,3); % An array of 3 random elements
c{333} = 0 ; % Pre-allocation
for p=1:3 % Since you want to use a 'for loop'
c{111*p} = A(p)^3;
end
And regarding the requirement that you made in the comment in these words "I also have some variable using negative index", you can never have variables in the negative index. If you mean you want to create variables with names like k-1, k-2,... etc, it is not possible. An alternate way is to use k_1, k_2,... etc but then as you said in the question "k0 refers to D(1,1), i.e. the number in my variable is 1 less". It means k_1 will refer to D(0,0) and so on which is again an invalid thing for MATLAB.
Recommendation:-
You really need to modify your code.

Memory-Allocation for function calls of form x = f(x) in MATLAB

In my code, I have lots of places where I invoke functions of the form
X = f(X)
and X can be a rather large matrix. In my special case, I have mostly calls like
X = feval(somefunc, X)
or
X = obj.myfunc(X)
It would be bad if, every time the function is called, there is new space allocated for X. Is MATLAB smart enough to deal with such function calls? Is there a way to tell?
The answer to this question helps would help very much with a design descision. I like to program in object oriented style and if MATLAB is not smart enough for this, it might pay off for me to add another member for X in the class, although I would rather not do this otherwise.
Whether a copy is made of the input arguments or not when calling a function in MATLAB depends upon what happens inside of the function.
MATLAB uses a system referred to as copy-on-write. This means that if you pass a large variable to a function as an input, as long as you do not modify the variable within that function, the variable will not be copied into the workspace of the function and the function will instead read the data from it's current location in memory.
function Y = func(X)
Y = X + 1;
end
If you are modifying the variable within the function, then a copy of the input variable is made and placed into the local workspace of the function.
function X = func(X)
X = X + 1;
end
There is more information on Loren's Mathworks blog.
An easy way to determine if a copy of the data is made or not is to use the undocumented format debug mode which will show you where the data for a given variable is stored in memory.
format debug
%// Create a variable a and show where debug info
a = [1,2]
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20
%// pi = 0
%// 1 2
%// Assign b = a but don't modify
b = a
%// Structure address = 141f567f0
%// m = 1
%// n = 2
%// pr = 7f9540b85e20 <= POINTER TO DATA REMAINED UNCHANGED
%// pi = 0
%// 1 2
%// Modify (Will create a new copy)
b = b + 1
%// Structure address = 141f55b40
%// m = 1
%// n = 2
%// pr = 7f953bcf1a20 <= POINTER TO DATA CHANGED (COPY)
%// pi = 0
%// 2 3
If you prefer you can use this little anonymous function I've created to inspect the memory location of any particular variable.
memoryLocation = #(x)regexp(evalc('disp(x)'), '(?<=pr\s*=\s*)[a-z0-9]*', 'match')
a = [1,2];
memoryLocation(a)
%// 7f9540b85e20
b = a;
memoryLocation(b)
%// 7f9540b85e20
b = b + 1;
memoryLocation(b)
%// 7f953bcf1a20
As a bit of a side-note, I would recommend against using feval throughout your code and instead just use the function names directly.

How to update a uitable after creation from other functions?

I created a matfile in which I store data that are constantly overwritten by user behavior. This occurs in a function "test()".
n=1
while n < 5
myVal = double(Test704(1, 780, -1)) %Returns the user's behavior
if myVal == 1
n = n + 1 %"n" is the overwritten variable in the matfile
end
save('testSave1.mat') %The matfile
m = matfile('testSave1.mat')
end
Then, I want to display these data in another function (it is essential to have two separated functions) called "storageTest()". More particularly, storageTest() is a GUI function where I developped an uitable "t". So, I first call the function "test()" and give its output values as data of "t". Here is the code of the interesting part of "storageTest":
m = test()
d = [m.n]
t = uitable('Data',d, ...
'ColumnWidth',{50}, ...
'Position',[100 100 461 146]);
t.Position(3) = t.Extent(3);
t.Position(4) = t.Extent(4);
drawnow
This code executes only when "m = test()" running is over and displays me a tab in which I can see the final value of "n". However, I want my table to be displayed before and to see my value incrementing according to user's behavior.
I have searched on the web to solve my issue, but I cannot find any answer, is it possible to do such a thing?
Assuming I'm interpreting the question correctly, it should be fairly trivial to accomplish this if you initialize your table prior to calling test and then pass the handle to your table for test to update in the while loop:
For example:
function testGUI
% Initialize table
t = uitable('ColumnWidth',{50}, 'Position',[100 100 461 146]);
test(t)
function test(t)
n = 1;
while n < 5
n = n + 1;
t.Data = n;
pause(0.25); % Since we're just incrementing a number, a slight so we can actually see the change
end
When you run the above, you'll notice the data in your table iterating as expected.
excaza was a little faster in writing basically the same answer like me. As it looks a slightly different, I'll post it anyway.
function storagetest()
close all
f = figure;
data = [1];
t = uitable(f,'Data',data,'ColumnWidth',{50});
test()
end
function test()
% handle uitable
t = evalin('caller','t')
n = 1;
while n < 5
newVal = input('Enter a number:');
data = get(t,'Data');
set(t,'Data', [data; newVal]);
n = n + 1;
end
end
The "user behaviour" I imitated with the input function. The basic idea is to update your table from within test(). evalin you can use, if you don't want to pass parameters to test(), though passing the handle of the uitable directly is certainly the better option.
If you are working on a serious GUI project I highly recommend you reading this answer.