Matlab: Why is my plot not converging? - matlab

Would you be able to help me to understand why the plot does not converge? What am I missing from the code? I am plotting mean and variance against number of trials. Thx
samplesize = 10;
trialsize = 1000;
firstvector = [1:trialsize];
vectorB = zeroes(trialsize,1);
vectorC = zeroes(trialsize,1)
for i=1:trialsize
v1 = rand(samplesize, 1)
vectorB(i) = mean(v1);
vectorC(i) = var(v1);
end
plot(firstvector,vectorB)
plot(firstvector,vectorC)

Is this what you wanted to do? Basically take the mean and var of 10 more samples at a time? So 1st loop take 10, next 20, next 30 .... 1000 times?
Before you where just taking the mean and var of 10 random samples at a time so ... you were never going to converge.
samplesize = 10;
trialsize = 1000;
firstvector = [1:trialsize];
vectorB = zeros(trialsize,1);
vectorC = zeros(trialsize,1);
v1 = rand(trialsize*samplesize, 1);
for i=1:trialsize
vectorB(i) = mean(v1(1:i*samplesize));
vectorC(i) = var(v1(1:i*samplesize));
end
subplot(2,1,1);plot(firstvector,vectorB)
subplot(2,1,2);plot(firstvector,vectorC)

Related

Output a percentage of matrices of different sizes in Matlab

I am creating a function that takes matrixes of different sizes and converts the number of the total points scored into a percentage. I feel like I am missing a simple step that would complete this.
function weight = calculatepercentage(exams, homework, quizzes);
exams = ([60,60]./60);
homework = ([30,30,30]./30);
quizzes = ([10,10,10,10]./10);
eScore = exams*.60;
hScore = homework*.25;
qScore = quizzes*.15;
disp(eScore + hScore + qScore)
end
Here is a version that is probably doing the job. Your function was overwriting the variables that you hand over to the function.
final_score = calculatepercentage([60], [30 28], [5 5 5]);
function weight = calculatepercentage(exams, homework, quizzes)
% maximum points that can be obtained in each category
exam_maxpoints = 60;
homework_maxpoints = 30;
quizzes_maxpoints = 10;
% calc percentage per category
exams_percent = mean(exams./exam_maxpoints);
homework_percent = mean(homework./homework_maxpoints);
quizzes_percent = mean(quizzes./quizzes_maxpoints);
% calc percentage by weights for each category
eScore = exams_percent*.60;
hScore = homework_percent*.25;
qScore = quizzes_percent*.15;
% get final percentage
weight = eScore + hScore + qScore;
disp(weight)
end

Matlab: binomial simulation

How do i simulate a binomial distribution with values for investment with two stocks acme and widget?
Number of trials is 1000
invest in each stock for 5 years
This is my code. What am I doing wrong?
nyears = 5;
ntrials = 1000;
startamount = 100;
yrdeposit = 50;
acme = zeros(nyears, 1);
widget = zeros(nyears,1);
v5 = zeros(ntrials*5, 1);
v5 = zeros(ntrials*5, 1);
%market change between -5 to 1%
marketchangeacme = (-5+(1+5)*rand(nyears,1));
marketchangewidget = (-3+(3+3)*rand(nyears,1));
acme(1) = startamount;
widget(1) = startamount;
for m=1:numTrials
for n=1:nyears
acme(n) = acme(n-1) + (yrdeposit * (marketchangeacme(n)));
widget(n) = acme(n-1) + (yrdeposit * (marketchangewidget(n)));
vacme5(i) = acme(j);
vwidget5(i) = widget(j);
end
theMean(m) = mean(1:n*nyears);
p = 0.5 % prob neg return
acmedrop = (marketchangeacme < p)
widgetdrop = (marketchangewidget <p)
end
plot(mean)
Exactly what you are trying to calculate is not clear. However some things that are obviously wrong with the code are:
widget(n) presumable isn't a function of acme(n-1) but rather 'widget(n-1)`
Every entry of theMean will be mean(1:nyears*nyears), which for nyears=5 will be 13. (This is because n=nyears always at that point in code.)
The probability of a negative return for acme is 5/6, not 0.5.
To find the locations of the negative returns you want acmedrop = (marketchangeacme < 0); not < 0.5 (nor any other probability). Similarly for widgetdrop.
You are not preallocating vacme5 nor vwidget5 (but you do preallocate v5 twice, and then never use it.
You don't create a variable called mean (and you never should) so plot(mean) will not work.

How I can alter the probability of an event in Matlab?

I have a network with N = 5 nodes. The probability that a new connection exit node "Ni" is:
P(N1) = P(N2) = P(N3) = P(N4) = P(N5) = 1/5
And the sum of all P(Ni) = 1.
which is a uniform distribution. I would like, nodes N3 and N5 had more chance to leave the rest. For example:
P(N1) = P(N2) = P(N4) = 2/15
P(N3) = P(N5) = 3/10
And the sum of all P(Ni) = 1.
The code I am using now is this:
nodes = 21;
NODES=(1:nodes);
R=randperm(nodes);
nodeSource=NODES(R(1));
nodeDestin=NODES(R(2));
Thanks.
You might want to look at randsample
nodeSource = randsample(1:numel(P), numel(P), true, P)

Generating random numbers...Faster way?

Using Run & Time on my algorithm I found that is a bit slow on adding standard deviation to integers. First of all I created the large integer matrix:
NumeroCestelli = 5;
lover_bound = 0;
upper_bound = 250;
steps = 10 ;
Alpha = 0.123
livello = [lover_bound:steps:upper_bound];
L = length(livello);
[PianoSperimentale] = combinator(L,NumeroCestelli,'c','r');
for i=1:L
PianoSperimentale(PianoSperimentale==i)=livello(i);
end
then I add standard deviation (sigma = alpha * mu) and error (of a weigher) like this:
%Standard Deviation
NumeroEsperimenti = size(PianoSperimentale,1);
PesoCestelli = randn(NumeroEsperimenti,NumeroCestelli)*Alfa;
PesoCestelli = PesoCestelli.*PianoSperimentale + PianoSperimentale;
random = randn(NumeroEsperimenti,NumeroCestelli);
PesoCestelli(PesoCestelli<0) = random(PesoCestelli<0).*(Alfa.*PianoSperimentale(PesoCestelli<0) + PianoSperimentale(PesoCestelli<0));
%Error
IncertezzaCella = 0.5*10^(-6);
Incertezza = randn(NumeroEsperimenti,NumeroCestelli)*IncertezzaCella;
PesoIncertezza = PesoCestelli.*Incertezza+PesoCestelli;
PesoIncertezza = (PesoIncertezza<0).*(-PesoIncertezza)+PesoIncertezza;
Is there a faster way?
There is not enough information for me to test it, but I bet that eliminating all the duplicate calculations that you do will lead to a speedup. I have tried to remove some of them:
PesoCestelli = randn(NumeroEsperimenti,NumeroCestelli)*Alfa;
PesoCestelli = (1+PesoCestelli).*PianoSperimentale;
random = randn(NumeroEsperimenti,NumeroCestelli);
idx = PesoCestelli<0;
PesoCestelli(idx) = random(idx).*(1+Alfa).*PianoSperimentale(idx);
%Error
IncertezzaCella = 0.5*10^(-6);
Incertezza = randn(NumeroEsperimenti,NumeroCestelli)*IncertezzaCella;
PesoIncertezza = abs((1+PesoCestelli).*Incertezza);
Note that I reduced the last two lines to a single line.
You calculate PesoCestelli<0 a number of times. You could just calculate it once and save teh value. You also create a full set of random numbers, but only use a subset of them where PesoCestelli<0. You might be able to speed things up by only creating the number of random numbers you need.
It is not clear what Alfa is, but if it is a scalar, instead of
Alfa.*PianoSperimentale(PesoCestelli<0) + PianoSperimentale(PesoCestelli<0)
it might be faster to do
(1+Alfa).*PianoSperimentale(PesoCestelli<0)

Using MATLAB to calculate offset between successive images

I'm taking images using a tunneling microscope. However, the scope is drifting between successive images. I'm trying to use MatLab to calculate the offset between images. The code below calculates in seconds for small images (e.g. 64x64 pixels), but takes >2 hrs to handle the 512x512 pixel images I'm dealing with. Do you have any suggestions for speeding up this code? Or do you know of better ways to track images in MatLab? Thanks for your help!
%Test templates
template = .5*ones(32);
template(25:32,:) = 0;
template(:,25:64) = 0;
data_A = template;
close all
imshow(data_A);
template(9:32,41:64) = .5;
template(:,1:24) = 0;
data_B = template;
figure, imshow(data_B);
tic
[m n] = size(data_B);
z = [];
% Loop over all possible displacements
for x = -n:n
for y = -m:m
paddata_B = data_B;
ax = abs(x);
zerocols = zeros(m,ax);
if x > 0
paddata_B(:,1:ax) = [];
paddata_B = [paddata_B zerocols];
else
paddata_B(:,(n-ax+1):n) = [];
paddata_B = [zerocols paddata_B];
end
ay = abs(y);
zerorows = zeros(ay,n);
if y < 0
paddata_B(1:ay,:) = [];
paddata_B = vertcat(paddata_B, zerorows);
else
paddata_B((m-ay+1):m,:) = [];
paddata_B = vertcat(zerorows, paddata_B);
end
% Full matrix sum after array multiplication
C = paddata_B.*data_A;
matsum = sum(sum(C));
% Populate array of matrix sums for each displacement
z(x+n+1, y+m+1) = matsum;
end
end
toc
% Plot matrix sums
figure, surf(z), shading flat
% Find maximum value of z matrix
[max_z, imax] = max(abs(z(:)));
[xpeak, ypeak] = ind2sub(size(z),imax(1))
% Calculate displacement in pixels
corr_offset = [(xpeak-n-1) (ypeak-m-1)];
xoffset = corr_offset(1)
yoffset = corr_offset(2)
What you're calculating is known as the cross-correlation of the two images. You can calculate the cross-correlation of all offsets at once using Discrete Fourier Transforms (DFT or FFT). So try something like
z = ifft2( fft2(dataA) .* fft2(dataB).' );
If you pad with zeros in the Fourier domain, you can even use this sort of math to get offsets in fractions of a pixel, and apply offsets of fractions of a pixel to an image.
A typical approach to this kind of problem is to use the fact that it works quickly for small images to your advantage. When you have large images, decimate them to make small images. Register the small images quickly and use the computed offset as your initial value for the next iteration. In the next iteration, you don't decimate the images as much, but you're starting with a good initial estimate of the offset so you can constrain your search for solutions to a small neighborhood near your initial estimate.
Although not written with tunneling microscopes in mind, a review paper that may be of some assistance is: "Mutual Information-Based Registration of Medical Images: A Survey" by Pluim, Maintz, and Viergever published in IEEE Transactions on Medical Imaging, Vol. 22, No. 8, p. 986.
below link will help you find transformation between 2 images and correct/recover the distorted (in your case, image with offset)
http://in.mathworks.com/help/vision/ref/estimategeometrictransform.html
index_pairs = matchFeatures(featuresOriginal,featuresDistorted, 'unique', true);
matchedPtsOriginal = validPtsOriginal(index_pairs(:,1));
matchedPtsDistorted = validPtsDistorted(index_pairs(:,2));
[tform,inlierPtsDistorted,inlierPtsOriginal] = estimateGeometricTransform(matchedPtsDistorted,matchedPtsOriginal,'similarity');
figure; showMatchedFeatures(original,distorted,inlierPtsOriginal,inlierPtsDistorted);
The inlierPtsDistored, inlierPtsOriginal have attributes called locations.
These are nothing but matching locations of one image on another. I think from that point it is very easy to calculate offset.
The function below was my attempt to compute the cross-correlation of the two images manually. Something's not quite right though. Will look at it again this weekend if I have time. You can call the function with something like:
>> oldImage = rand(64);
>> newImage = circshift(oldImage, floor(64/2)*[1 1]);
>> offset = detectOffset(oldImage, newImage, 10)
offset =
32 -1
function offset = detectOffset(oldImage, newImage, margin)
if size(oldImage) ~= size(newImage)
offset = [];
error('Test images must be the same size.');
end
[imageHeight, imageWidth] = size(oldImage);
corr = zeros(2 * imageHeight - 1, 2 * imageWidth - 1);
for yIndex = [1:2*imageHeight-1; ...
imageHeight:-1:1 ones(1, imageHeight-1); ...
imageHeight*ones(1, imageHeight) imageHeight-1:-1:1];
oldImage = circshift(oldImage, [1 0]);
for xIndex = [1:2*imageWidth-1; ...
imageWidth:-1:1 ones(1, imageWidth-1); ...
imageWidth*ones(1, imageWidth) imageWidth-1:-1:1];
oldImage = circshift(oldImage, [0 1]);
numPoint = abs(yIndex(3) - yIndex(2) + 1) * abs(xIndex(3) - xIndex(2) + 1);
corr(yIndex(1),xIndex(1)) = sum(sum(oldImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)) .* newImage(yIndex(2):yIndex(3),xIndex(2):xIndex(3)))) * imageHeight * imageWidth / numPoint;
end
end
[value, yOffset] = max(corr(margin+1:end-margin,margin+1:end-margin));
[dummy, xOffset] = max(value);
offset = [yOffset(xOffset)+margin-imageHeight xOffset+margin-imageWidth];