behavior of matlab's rng() function in loop - matlab

With rng() before for loop Matlab generate one array of random number, within for loop another one. Both results are repeatable, so rng() seeds work. But I want to know the reason of such behavior.I was expecting the results to be same. I think actually it is not because of rng but for loop
Code exapmle?
for i = 1:2
rng(1,'philox');
disp(randn(2,1)); % 1st number is 0.0906, 2nd one is -0.7327
end
rng(1,'philox');
for i = 1:2
disp(randn(2,1)); % 1st number is 0.7565, 2nd one is -0.7096
end
Shouldn't the results be same? Isn't rng(1,..) storing same array of numbers for seed 1

Your code works as you expect and would describe, I believe. You are definitely not showing in your code example all the outputs. This is what I get when running it.
>> test
First case:
0.0906
-0.7327
0.0906
-0.7327
Second case:
0.0906
-0.7327
0.7565
-0.7096
In the first case, you reset the random number generator inside the loop, and there fore you get twice the same results (two numbers). In the second case, you only set it once, and therefore you get the same numbers as before, and then the second loop you get the next 2 corresponding random numbers produced by the algorithm. These algorithms, once started, will produce an infinite amount of different numbers, and they won't produce the same unless you explicitly call the restart of the algorithm with the seed, like you do in the first example.
All this is way less confusing if you call disp(randn(1)) inside the loop, instead of generating 2 numbers each time.

Related

What are these lines doing? (Matlab)

I am trying to translate a small program from MATLAB to Python. I do not have MATLAB to run the code and see the output. Anyways, the program has a weird section that I do not know how to interpret correctly.
Here is that part of the code:
randn('state',2)
for ncase=1:3
sumex=0;
I know randn gives a matrix with normally distributed numbers - but what does it have to do with the for loop - and 'state'? I notice there is no semicolon after it.
I am guessing 'state' is the name of the matrix, and it is not initiated - nor referenced anywhere else in the code.
If I commented out randn('state',2) is it going to change the output?
Commenting out randn('state',2) will have an effect on the code and its output as randn('state',2) is old discouraged MATLAB syntax to specify the random number generator to use with randn and to seed it.
You could replace it simply with your own method to seed your own random number generator of choice in python.
for ncase=1:3 will loop from 1 to 3 in increments of 1. ncase will be 1 in the first iteration, 2 in the second iteration and 3 in the third and final iteration.
sumex=0; sets the variable sumex equal to 0.

Create different `randperm` numbers in loops

Suppose that we have this structure:
for i=1:x1
Out = randperm(40);
Out_Final = %% divide 'Out' to 10 parts. and select these parts for some purposes
for j=1:x2
%% Process on `Out_Final`
end
end
I'm using outer loop (for i=1:x1) to repeat main process (for j=1:x2) loop and average between outputs to have more robust results. I want randperm doesn't result equal (or near equal) outputs. I want have different Output for this function as far as possible in every calling in (for i=1:x1) loop.
How can i do that in MATLAB R2014a?
The randomness algorithms used by randperm are very good. So, don't worry about that.
However, if you draw 10 random numbers from 1 to 10, you are likely to see some more frequently than others.
If you REALLY don't want this, you should probably not focus on randomly selecting the numbers, but on selecting the numbers in a way that they are nicely spread out througout their possible range. (This is a quite different problem to solve).
To address your comment:
The rng function allows you to create reproducible results, make sure to check doc rng for examples.
In your case it seems like you actually don't want to reset the rng each time, as that would lead to correlated random numbers.

cellfun randperm downsampling: keep track of indexes (matlab)

I have this snippet of code, downsampling data from a cell array based on the length of its shortest element.
sizeShortest = min(cellfun('size', data, 2));
f=#(x)(x(:,sort(getfield(randperm(size(x,2)),{1:sizeShortest}))));
dummy = cellfun(f, data, 'UniformOutput', false);
I would also like to keep track of the indexes of the elements of data saved in dummy (Basically what's the 1:sizeShortest values from the randperm call).
I couldn't find an answer so far...any help is greatly appreciated!
From our comments, you can simply take the code that is indexing your array and obtain your indices:
f=#(x) sort(getfield(randperm(size(x,2)),{1:sizeShortest}));
indices = cellfun(f, data, 'UniformOutput', false);
In essence, you'd run cellfun twice. Once for getting the data, and again for the indices. However, as you have cleverly stated in your comments, running randperm subsequent times will generate a new sequence of numbers. You can "cheat" by resetting the random generator seed before you call the next randperm call. What this does is that once you reset the seed, the random numbers that you generate should be reproducible. You can do this by the rng function. This accepts any integer that will act as a seed. Once you set this up, the numbers generated by any random generation function will follow a prescribed format that relies on this seed.
As an example:
rng(10)
C = randperm(10)
This gives:
C =
2 10 9 7 6 5 3 4 8 1
If you run those two statements again, you will get the same sequence stored in C. As such, set your random number generator to any integer you want. Run the first cellfun command... then after, reset to the same seed and run the second cellfun command.
Now to make this truly dynamic, you'll want to choose a random seed first. Store this number for later so that you can use this same seed for both cellfun calls. You could poll the current time of the day, and use the seconds to give you your custom seed.
In other words:
c = clock;
seedNum = c(5); %// c(5) is the number of seconds in the minute you're currently on.
rng(seedNum);
%// Do your first set of commands here...
rng(seedNum);
%// Do your second set of commands here...
If you want to reset it back to default after you're done, you can call rng('default'); What this will do is that it will reset the random number generation as if you restarted MATLAB. You don't have to, but I think it's good practice!
Good luck!

Change value inside a loop on Matlab

I have a question about how can I use different values in each iteration with a loop. I have an image with 145 bands. I calculate the size, the number of rows, columns and bands
size=size(HYP);
nrow= size(1);
ncolu= size(2);
nbands= size(3);
I have to do an operation for every band, and then obtain the result but I don't know how to change one of the values automatically for every iteration. I'm going to try to simplify the question. This is my loop. The value rad1 is defined before. I need that on every loop uses some value defined before (for example, band2 value rad2, band3 rad3...) and extract a result for each one (nd1 changes automatically to nd2, etc.)
output= zeros(nrow,ncolu,nbands);
for banda=1:nbands;
nd1= -((3.141592*rad1)/-HYP2(:,:,1));
output(banda,1)= (nd1);
end
end
So, for the first iteration:
nd1= -((3.141592*rad1)/-HYP2(:,:,1));
output(banda,1)= (nd1);
for the second...
nd2= -((3.141592*rad2)/-HYP2(:,:,2));
output(banda,2)= (nd2);
Rad1,rad 2... rad145 etc is defined before. And at the end, output would be a 145 band matrix.
Do you know how can I do it? Really thanks in advance,
Don't try using different variable names. Just use rad(1), rad(2) etc. and then
output= zeros(nrow, ncolu, nbands);
for banda=1:nbands;
output(:,:,banda) = -((3.141592*rad(banda))/-HYP2(:,:,1));
end
(Your initialization of output doesn't match the code in your loop, by the way.)

how to create a changing variable for fsolve

i want fsolve to calculate the output for different uc each time (increasing uc by 0.001 each time). each output from fsolve should be sent to a simulink model seperatly. so i set a loop to do so, but i believe that at the currenty constellation (if it will work)will just calculate 1000 different values? is there a way to send out the values seperately?
if not, how can i create a parameter uc. that goes from 0 to say 1000? i tried uc=0:0.001:1000, but again, the demension doen't seem to fit.
how do i create a function that takes the next element of a vector/matrix each time the function is called?
best regards
The general approach to iterating over an array of values and feeding them one-by-one into a series of evaluations of a function follows this form:
for ix = 0:0.1:10
func(arg1, arg2, ix)
end
See how each call to func includes the current value of ix ? On the first iteration ix==0, on the next ix==0.1 and so forth. You should be able to adapt this to your needs; in your code the loop index (which you call i) is not used inside the loop.
Now some un-asked-for criticism of your code. The lines
x0=[1,1,1];
y=x0(1);
u=x0(2);
yc=x0(3);
options=optimset('Display','off');
do not change as the loop iterations advance; they always return the same values whatever the value of the loop iterator (i in your code) may be. It is pointless including them inside the loop.
Leaving them inside the loop may even be a waste of a lot of time if Matlab decides to calculate them at every iteration. I'm not sure what Matlab does in this case, it may be smart enough to figure out that these values don't change at each iteration, but even if it does it is bad programming practice to write your code this way; lift constant expressions such as these out of loops.
It's not clear from the fragment you've posted why you have defined y, u and yc at all, they're not used anywhere; perhaps they're used in other parts of your program.