Convesion vector Index exceeds array bounds - matlab - matlab

I build some program in Matlab for "Histograma matching".
When I'm trying to implement the function "conVector" I get the error
"Index exceeds array bounds." anyone can help me with this error?
Here is my full code. Thank you!
function [newImage] = histShape (srcimg,destimg)
%find the histogram of the image
src = imgHist(srcimg);
dest = imgHist(destimg);
sna = normalizationHist(src);
dna = normalizationHist(dest);
conVector(sna,dna);
end
function [Hist] = imgHist (img)
[Rows,Cols] = size(img);
Hist = zeros(1,256);
for i=1:Rows
for j=1:Cols
Hist(img(i,j)+1)=Hist(img(i,j)+1)+1;
end
end
end
function [Ahist] = normalizationHist (hist)
[Rows,Cols] = size(hist);
Ahist = hist;
for i=2:256
Ahist(i)=Ahist(i-1)+hist(i);
end
Ahist = Ahist/(Rows*Cols);
end
function [cv] = conVector(SNA,DNA)
cv=zeros(1,257);
s = 1;
d = 1;
while s<=256
if DNA(d)<SNA(s)
d = d+1;
else
cv(s)=d;
s = s+1;
end
end
end

If all values in DNA(d:end) are smaller then the value in SNA(s) than the loop keep adding 1 to d but not to s, and finally goes out of bound because it conditioned only by s.
I guess you should either take the s = s+1 out of the inner condition, so it will be executed on every iteration, or add a condition on d to the loop, or convert it to a for loop.

Related

How to calculate the expected value of a function with random normally distributed X?

I am trying to calculate on MatLab the Expectation for the function e^X where X ~ N(mu,sigma^2). In my example, mu = 0 and sigma = 1.
function [E] = expectedval(m,s)
%find E(e^x) with X~N(mu,sigma)
% mu = 0 , sigma = 1
X = normrnd(m,s);
f=exp(X);
mean(f)
So by the end I can run expectedval(0,1) to get my solution. The code runs with no issue, but I would like to compile a histogram to analyse the data with several runs. How may I collect this data with some sort of loop?
I'd appreciate any improvement ideas or suggestions!
Actually, your function just creates one random value for the given mean and variance... so there's actually no point in calculating a mean. On the top of that, the output E value is not assigned before the function finishes. The function can therefore be rewritten as follows:
function E = expectedval(m,s)
X = normrnd(m,s);
E = exp(X);
end
If you want to draw a sample from the normal distribution, and use the mean to compute the correct expected value, you can rewrite it as follows instead:
function E = expectedval(m,s,n)
X = normrnd(m,s,[n 1]);
f = exp(X);
E = mean(f);
end
And here is an example on how to run your function many times with different parameters, collecting the output on each iteration:
m = 0:4;
m_len = numel(m);
s = 1:0.25:2;
s_len = numel(s);
n = 100;
data = NaN(m_len*s_len,1);
data_off = 1;
for s = 1:s_len
for m = 1:m_len
data(data_off) = expectedval(m,s,n);
data_off = data_off + 1;
end
end

how do I save the result of loop for in a matrix?

I need to save results of a for loop in a matrix where its size is 4*1?
My function:
function test()
for j=2:2:8
h= 3*j
end
end
results:
h=6
h=12
h=18
h=24
Thank you in advance.
You can do this via loop, and than you should first create the matrix:
function test()
n = 2:2:8;
h = zeros(length(n),1)
counter = 1;
for j = n
h(counter) = 3*j
counter = counter+1;
end
end
But that is the long and non-efficient way, instead you should use vectorization:
n = 2:2:8;
h = n.'*3
or just: h = (2:2:8).'.*3;
that's it.

MATLAB LOOPS: Inserting values from a big array to a small array

I have a vector named signal consisting of 300001 values. In each iteration of the for loop, I want to pick up 2000 consecutive values from this vector and store it in another vector X (X is 1*2000 vector)
The code is as follows:
D = 1:300001;
A = zeros(1,2000);
r=1;
n=0;
m=1;
for i=1:300001
for p = (1+(2000*n)):(r*2000)
while m<2000
A(1,m)= signal(1,p);
%disp (m);
m = m+1;
end
end
r = r+1;
n = n+1;
m = 1;
end
But it gives me the error "Index exceeds matrix dimensions.
Can somebody help me out with a better way to do it?
this would work
signal = ones(1,30000);
index1= 1:2000:length(signal);
index2= 2000:2000:length(signal);
for i=1:length(index1)
A = signal(index1(i):index2(i));
end
or this
signal = ones(1,30000);
temp = reshape(signal,2000,[]);
for i = 1:size(temp,2)
A=temp(:,i);
end

How to change loop condition in Matlab?

I run this code:
for i=1:length(matr)
...where matr is square matrix. In this loop the size of the matr changes, but it seems that the loop continues to run, until i doesn't not exceed the initial value of length(matr)
How to maintain the fresh of length(matr) in the loop's condition?
Here is my code.
for i=1:length(matr1)
for j=1:length(matr1)
if((i~=j)&&(ismember(i,ind3)==0)&&(ismember(j,ind3)==0))
if (i>length(matr1))||(j>length(matr1))
continue
end
ind1 = find_tree(matr1,i);
ind2 = find_tree(matr1,j);
b = is_isomorphic(matr1(ind1,ind1),matr1(ind2,ind2),encode(ind1),encode(ind2));
if b,
number = number + length(ind1);
matr1(ind2,:) = [];
matr1(:,ind2) = [];
ind3 = find(summ_rows==-1);
end
end
end
end
I was managed to add
`if (i>length(matr1))||(j>length(matr1))`,
...because i and j exceeded the dimensions of the matrix.
You should be using a while loop:
ii = 0;
while(ii <= length(matr))
ii = ii + 1;
%// Your loop code here: e.g. the following line that alters the size of matr
matr = rand(randi(20) + 10);
end

Matlab : create my own dct2

==Question solved==
This code will get you the dct2 output.
I am working to make improvement on my own codes
Thank you.
%Get the size of the input image
[m, n] = size(image);
output = zeros(m,n);
for u = 0:m-1
for v = 0:n-1
if u==0
a=sqrt(1/8);
else
a=sqrt(2/8);
end
if v==0
b=sqrt(1/8);
else
b=sqrt(2/8);
end
temp = 0;
for x = 0:m-1
for y = 0:n-1
temp = (cos((((2*x)+1)*pi*u)/(2*m))*cos((((2*y)+1)*pi*v)/(2*n)));
end
end
output(u+1,v+1) = a*b*temp;
end
end
There are two problems with your code if you are trying to compare it to the Matlab function dct2. For the record, you can open and analyze the files to understand what Matlab is doing.
In both case you are not following the formula:
a and b need to be a function of n:
if u==0
a=sqrt(1/n);
else
a=sqrt(2/n);
end
if v==0
b=sqrt(1/n);
else
b=sqrt(2/n);
end
You need to multiply your temp term by the image values (which you are not doing):
temp = temp+(image(x+1,y+1))*(cos((((2*x)+1)*pi*u)/(2*m))*cos((((2*y)+1)*pi*v)/(2*n)));
I haven't addressed the performance problem, and you really should look into that on your own.