Random number generator issues in matlab - matlab

I have an issue I can't quite figure out. For a simulation I generate artificial data randomly, with randomly drawn variance and a mean of 0. To acheive this I first create a vector of possible variances and then randomly draw the index for the vector, like in the following example
%% Covariance Matrix
% Variances of explanatory variables
var1 = 0.1:0.1:100;
var2 = 0.1:0.1:100;
var3 = 0.1:0.1:100;
%% Randomly selecting variances
% if exist('s','var')
% rng(s) % Loading Random generator settings for replication
% else
% s=rng; % Saving Random generator settings for replication
% end
ind_1=randi([0 1000]);
ind_2=randi([0 1000]);
ind_3=randi([0 1000]);
var_11=var1(ind_1);
var_22=var2(ind_2);
var_33=var3(ind_3);
For some reason the random number generator seems to give me the same numbers in the first (ind_1=815, ind_2=906, ind_3=127) and in the second run (ind_1=914, ind_2=632, ind_3=97) after restarting matlab, if I generate the vector of variances first. I've been able to replicate that on different PC as well. Is there a feature that I'm overlooking or am I making, and I would imagine I am, a crucial mistake? (I am well aware that there are only pseudo random numbers in matlab, but this seems too pseudo for my taste.)

This is because the seed generator in matlab, when you start matlab is always the same take a look at this
>> rng('default')
>> ind_1=randi([0 1000])
ind_2=randi([0 1000])
ind_3=randi([0 1000])
ind_1=randi([0 1000])
ind_2=randi([0 1000])
ind_3=randi([0 1000])
rng('default')
ind_1=randi([0 1000])
ind_2=randi([0 1000])
ind_3=randi([0 1000])
ind_1 =
815
ind_2 =
906
ind_3 =
127
ind_1 =
914
ind_2 =
632
ind_3 =
97
ind_1 =
815
ind_2 =
906
ind_3 =
127
So the only thing that you have to do is change the initial seed every time you generate new numbers.
Execute before rng('shuffle'), it reseeds the generator using a different seed based on the current time.
>> rng('default')
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
815 906 127
>> rng('shuffle')
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
404 10 838
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
31 459 534
>> rng('shuffle')
>> rng('shuffle')
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
708 963 21
>> rng('default')
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
815 906 127
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
914 632 97
>> rng('default')
>> [randi([0 1000]), randi([0 1000]), randi([0 1000])]
ans =
815 906 127

Related

Matlab: Odd linear indexing into array with singleton dimensions

I'm having trouble understanding the circumstances under which linear indexing applies.
For a 2D array, it seems intuitive:
>> clear x
>> x=[1 2;3 4]
x =
1 2
3 4
>> x([1 2])
ans =
1 3
>> x([1;2])
ans =
1
3
For a 3D matrix, it seems intuitive:
>> clear y
>> y(1:2,1:2,1)=x
y =
1 2
3 4
>> y(1:2,1:2,2)=x+10
y(:,:,1) =
1 2
3 4
y(:,:,2) =
11 12
13 14
>> y([1 2])
ans =
1 3
>> y([1;2])
ans =
1
3
For a 3D matrix in which the 1st two dimensions are singletons, it's not what I would expect:
>> clear y
>> y(1,1,1)=1
y =
1
>> y(1,1,2)=2
y(:,:,1) =
1
y(:,:,2) =
2
>> y([1 2])
ans(:,:,1) =
1
ans(:,:,2) =
2
>> y([1;2])
ans(:,:,1) =
1
ans(:,:,2) =
2
I would have expected exactly the same as the 3D matrix without singleton dimensions.
Is there a rule that can be relied on to predict the behaviour of linear indexing?
The rule for linear indexing of an array x with an array ind is as follows (taken from this great post by Loren Shure):
If at least one of x and ind is not a vector (that is, if x or ind have more than one non-singleton dimension) the output has the same shape (size) as ind:
>> x = rand(3,4);
>> ind = [9 3];
>> x(ind)
ans =
0.276922984960890 0.743132468124916
>> x(ind.')
ans =
0.276922984960890
0.743132468124916
>> x = rand(2,3,4);
>> ind = [1 2; 5 6];
>> x(ind)
ans =
0.814723686393179 0.905791937075619
0.632359246225410 0.097540404999410
If both x and ind are vectors, the output is a vector that has the same orientation as x (i.e. the output dimension which is non-singleton is that in x), and the same number of elements as ind:
>> x = 10:10:70;
>> ind = [1 3 5];
>> x(ind)
ans =
10 30 50
>> x(ind.')
ans =
10 30 50
>> x = reshape(10:10:70,1,1,[]); % 1×1×7
>> ind = reshape([2 3 4],1,1,1,1,[]); % 1×1×1×1×3
>> x(ind)
ans(:,:,1) =
20
ans(:,:,2) =
30
ans(:,:,3) =
40
For completeness, if two or more indexing arrays are applied (so this is not linear indexing anymore), the shape of the output is determined by which dimensions of the original array are being indexed and by the number of elements of each indexing array. It is independent of the shape of the indexing arrays, which are simply read in column-major order as usual:
>> x = [10 20 30 40; 50 60 70 80];
>> x(2, [1 2; 3 4])
ans =
50 70 60 80
>> x(2, [1 2 3 4])
ans =
50 60 70 80
>> x(2, reshape([1 2 3 4],1,1,1,[]))
ans =
50 60 70 80
If there are fewer indices than the number of dimensions of x, the trailing dimensions of x are implicitly collapsed into one before the indexing is applied:
>> x = [10 20 30 40; 50 60 70 80];
>> x(:,:,2) = x+100;
>> x([1 2], [1; 5; 7; 8])
ans =
10 110 130 140
50 150 170 180

fmincon with lower bound fails, even though solution is at initial point

I'm trying to minimize a non-linear objective function (my actual function is much more complicated than that, but I found that even this simple function illustrates the point), where I know that minimum is obtained at the initial point x0:
fun = #(x) x(1)^2+x(2)^2;
x0 = [0 0];
lb1 = [0 0];
lb2 = [-1 -1];
[xc1 fvalc1] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf])
Which outputs:
>> xc1 = 1.0e-03 * [0.6457 0.6457]
>> fvalc1 = 8.3378e-07
However, both using a different lower bound or using fminsearch instead work correctly:
[xc2 fvalc2] = fmincon(fun, x0, [],[],[],[], lb2, [Inf Inf])
>> xc2 = [0 0]
>> fvalc2 = 0
[xs fvals] = fminsearch(fun, x0)
>> xs = [0 0]
>> fvals = 0
What goes wrong in the first fmincon call?
We can diagnose this using the output output argument as specified in the docs
[xc1, fvalc1, ~, output] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf])
The value output.stepsize is the final step size taken in the iterative solving process. In this case:
output.stepsize
>> ans = 6.586e-4
The estimated minima was at x = [6.457e-4, 6.457e-4] and the lower bounds you've permitted are [0 0], so the solver is not permitted to take another step! Another step would give x = [-1.29e-5, -1.29e-5] which is outside of the boundaries.
When you allow the lower bounds to be [-1, -1] the solver can over-shoot the minimum and approach it from all directions.
Moreover, we can use the options input to get even better insight!
options.Display = 'iter';
[xc1, fvalc1, ~, output] = fmincon(fun, x0, [],[],[],[], lb1, [Inf Inf], [], options);
Printed to the command window we see this:
Your initial point x0 is not between bounds lb and ub; FMINCON
shifted x0 to strictly satisfy the bounds.
First-order Norm of
Iter F-count f(x) Feasibility optimality step
0 3 1.960200e+00 0.000e+00 9.900e-01
1 6 1.220345e-02 0.000e+00 8.437e-01 1.290e+00
2 9 4.489374e-02 0.000e+00 4.489e-02 1.014e-01
3 12 1.172900e-02 0.000e+00 1.173e-02 1.036e-01
4 15 3.453565e-03 0.000e+00 3.454e-03 4.953e-02
5 18 1.435780e-03 0.000e+00 1.436e-03 2.088e-02
6 21 4.659097e-04 0.000e+00 4.659e-04 1.631e-02
7 24 2.379407e-04 0.000e+00 2.379e-04 6.160e-03
8 27 6.048934e-05 0.000e+00 6.049e-05 7.648e-03
9 30 1.613884e-05 0.000e+00 1.614e-05 3.760e-03
10 33 5.096660e-06 0.000e+00 5.097e-06 1.760e-03
11 36 2.470360e-06 0.000e+00 2.470e-06 6.858e-04
12 39 8.337765e-07 0.000e+00 8.338e-07 6.586e-04
So your x0 is invalid! This is why the solver doesn't return the result with 1 iteration and lower bounds of [0 0].
fminsearch also works for the same reason - you've not imposed a lower bound on which the solution sits.

Matlab - creating an automatically animation transition for a line

I have the following picture:
and I want to create a continuous transition. The blue line (-20deg-start) goes until become like (22deg - original), and then goes until become like (60deg-stop).
the code to generate this lines is:
>> clear all
>> x=[0 11 20 34];
>> y=[2 8 17 32];
>> z=[9 20 29 43];
>> v=[16 23 32 43];
>> w=[15 26 35 49];
>> t=[30 40 47 55];
>> figure
>> hold on
>> plot(t,x, t,y, t,z, t,v, t,w)
Is it possible with the help of Matlab?
Thanks!
The following example shows how to do a linear transition between two curves, provided they are both defined on the same set of x values.
x = linspace(0,1,200); %// x values
y1 = log(1+x); %// y values of line 1
y2 = 1-x.^2; %// y values of line 2
c1 = [1 0 0]; %// red
c2 = [0 0 1]; %// blue
plot(x, y1, ':', 'color', c1); %// plot first line
hold on
plot(x, y2, ':', 'color', c2); %// plot second line
tt = linspace(0,1,100); %// define time axis, between 0 and 1. Adjust "100" for smoothness
h = plot(x, y1, '-', 'color', c2); %// moving line. Initially coincides with line 1
for t = tt
y = y1*(1-t) + y2*t;
c = c1*(1-t) + c2*t;
set(h, 'YData', y, 'Color', c); %// update y values and color of moving line
pause(.02) %// adjust ".02" as needed
end
Yes you can (well from what I understand you wish to achieve). You can put all your data into 1 big array and loop through each row and display it, with a small pause between each set of data.
Example:
clear
clc
close all
clear all
x=[0 11 20 34];
y=[2 8 17 32];
z=[9 20 29 43];
v=[16 23 32 43];
w=[15 26 35 49];
t=[30 40 47 55];
%// Put everything in single array
AllArrays = [x;y;z;v;w];
figure
hold all
%// Loop through each rows
for k = 1:size(AllArrays,1)
plot(t,AllArrays(k,:))
%// Make a pause to see output
pause(.5)
end
Output:
Is this what you meant? Or maybe a smoother transition?

Matlab: Extracting error values from a fit

I am using the following code to import a spreadsheet with two coloumns x = intensity and y = angle and to get the Gaussian curve fitting:
%% Initialize variables
filename = ['E:\XRD\Enamel\MPS\3PC\Chiplots (starting from 0)\MPS_3Pcontrol_map_' j '.dat'];
startRow = 5;
%% Format string for each line of text:
formatSpec = '%14f%f%[^\n\r]';
%% Open the text file.
fileID = fopen(filename,'r');
%% Read columns of data according to format string.
dataArray = textscan(fileID, formatSpec, 'Delimiter', '', 'WhiteSpace', '', 'HeaderLines' ,startRow-1, 'ReturnOnError', false);
%% Close the text file.
fclose(fileID);
%% Allocate imported array to column variable names
plots.angle = dataArray{:, 1};
plots.intensity = dataArray{:, 2};
%% Fit: 'Gauss'.
[xData, yData] = prepareCurveData(plots.(['angle' num2str(j)]), plots.(['intensity' num2str(j)]));
% Set up fittype and options.
ft = fittype( 'y0+a*exp(-((x-xa)/wa)^2) + b*exp(-((x-xb)/wb)^2) + c*exp(-((x-xc)/wc)^2) + d*exp(-((x-xd)/wd)^2) + e*exp(-((x-xe)/we)^2) + f*exp(-((x-xf)/wf)^2)', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
opts.Display = 'Off';
opts.Lower = [0 0 0 0 0 0 0.1 0.1 0.1 0.1 0.1 0.1 -Inf -Inf -Inf -Inf -Inf -Inf -Inf];
opts.StartPoint = [1400 1400 1000 1200 1200 1000 25 25 25 25 25 25 75 125 170 250 275 325 0.5];
opts.Upper = [inf inf inf inf inf inf 50 50 50 50 50 50 inf inf inf inf inf inf Inf];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
I can get the values of the coefficients using: cfit(fitresult) to get the following:
From the above I can extract the coefficients values using coeffvalues(cfit(fitresult)):
The problem is I cant get the values highlighted in yellow, which I need to calculate the standard error using the equation (standard error = standard deviation/square root of n)
Can I extract the values highlighted in yellow in order to calculate the standard error?
You need to use the confint function. This will give you the 95% confidence bounds for the fit. It works like this:
confint(cfit(fitresult))
If you want your own confidence interval, you can set it like this:
confint(cfit(fitresult,[insert confidence interval here (such as 0.85)]))
That should do what you are looking for.

Matlab: normalized cut implementation

I have implemented "normalized cut" segmentation. The change here is that, instead of giving an image as input, I have given an matrix of image. As my output looks odd to me. I need to know whether my implementation is correct or not.
Code:
clear all
tic;
% im = imread('lena.pgm');
im =[94 122 99 101 111 101;
99 92 103 87 107 116;
93 109 113 84 86 106;
5 17 6 54 56 53;
13 11 5 56 44 50;
0 10 5 49 42 51];
% resizing to avoid out of memory error
% cim=imresize(im,[100 100]);
cim=im;
[r, c]=size(cim);
ind=find(cim);
lind=length(ind);
[I,J]=ind2sub([r,c],ind);
% % I've used linear indexing to speed up the partitioning
% vectoring the pixel nodes
for i=1:lind
V1(i)=double(cim(ind(i)));
end
% normalizing to [0-1] scale
V=(V1./255);
% w is the weight matrix (similarity matrix or adjacency matrix)
w=zeros(lind,lind);
% r, sigmaI, sigmaX values
rad=4.5;
sigi=10;
sigx=25;
% computing the weight matrix
for i=1:lind
x1=I(i,1);
y1=J(i,1);
for j=1:lind
if (i==j)
w(i,j)=1;
else
x2=I(j,1);
y2=J(j,1);
dist=((x1-x2)^2 + (y1-y2)^2);
if sqrt(dist)>=rad
dx=0;
else
dx=exp(-((dist)/(sigx^2)));
end
pdiff=(V(i)-V(j))^2;
di=exp(-((pdiff)/(sigi)^2));
w(i,j)=di*dx;
end
end
end
d=zeros(lind,lind);
s=sum(w,2);
% the diagonal matrix for computing the laplacian matrix
for i=1:lind
d(i,i)=s(i);
end
A=zeros(lind,lind);
A=(d-w); % A is the laplacian matrix
% vt has the eigen vectors corresponding to eigen values in vl
% other eigs / eig functions in matlab can be used but I'm using the
% function to compute the 5 smallest eigenvectors
[vt,vl]=eigs(A,d,5,'sm');
% se has the second smallest eigen vector, third and so on
se=vt(:,2:4);
% % % % % Simultaneous 'k' partitions
k=6;
id=kmeans(se,k);
imp=cell(1,k);
pic=cell(1,k);
for i=1:k
imp{1,i}= find(id(:,1)==i);
mat=zeros(100,100);
in=imp{1,i};
mat(in)=cim(in);
pic{1,i}=uint8(mat);
% figure,imshow(pic{1,i});
end
% pic has the sub graphs or partitiond sub images
figure;
subplot(2,4,1);imshow(uint8(im));title('Original image');
subplot(2,4,2);imshow(uint8(cim));title('Preprocessed image');
subplot(2,4,3);imshow(pic{1,1});title('Partition 1');
subplot(2,4,4);imshow(pic{1,2});title('Partition 2');
subplot(2,4,5);imshow(pic{1,3});title('Partition 3');
subplot(2,4,6);imshow(pic{1,4});title('Partition 4');
subplot(2,4,7);imshow(pic{1,5});title('Partition 5');
subplot(2,4,8);imshow(pic{1,6});title('Partition 6');
toc;
Output:
Thanks in advance.