I am trying to write a Matlab code to simulate a dice and compute its mean and standard deviation.
The problem is that no matter how many times we run this code, the result of randi(6) keeps the same. It made me crazy.
n=20;
m=0;
c=0;
for i=1:10000
while m<n
x=randi(6);
c=c+1;
m=m+x;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
end
I think you forgot to set m back to ZERO at the end of the for. If you want the sequence of randi to change you should take a look at the function "rng".
n=20;
m=0;
c=1;
for i=1:100
while m<n
x(i, c)=randi(6);
m=m+x(i,c);
c=c+1;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
m = 0;
end
You forgot to reset m and c back to 0 once the while loop terminates. m is set to 0 outside of the for loop only once, and so when m finally surpasses n, m never changes. As such, simply set m = 0 in your for loop before the while loop happens. You also need to set c to 0 because you want to count events each time the for loop iterates.
I'm also not sure how you could think that diff(i) = 2.5 for all i. This difference is a probabilistic value. Also, I don't see how you could get a floating point number in the difference because you are generating integers and accumulating integers for each trial. I think you need to examine what this value should be.
So:
n=20;
%//m=0;
%//c=0;
for i=1:10000
m = 0; %// Change here
c = 0; %// Change here too
while m<n
x=randi(6);
c=c+1;
m=m+x;
end
M(i)=m;
count(i)=c;
diff(i)=M(i)-n;
end
Related
I am getting confused on how to properly set up this equation. To find a value of V(i,j). The end result would be plotting V over time. I understand that there needs to be loops to allow this equation to work, however I am lost when it comes to setting it up. Basically I am trying to take the sum from n=1 to infinity of (1-(-1)^n)/(n^4 *pi^4)*sin((n*pi*c*j)/L)*sin((n*pi*i)/L)
I originally thought that I should make it a while loop to increment n by 1 until I reach say 10 or so just to get an idea of what the output would look like. All of the variables were unknown and values were added again to see what the plot would look like.
I have down another code where the equation is just dependent on i and j. However with this n term, I am thrown off. Any advice would be great as to setting up the equation. Thank you.
L=10;
x=linspace(0,L,30);
t1= 50;
X=30;
p=1
c=t1/1000;
V=zeros(X,t1);
V(1,:)=0;
V(30,:)=0;
R=((4*p*L^3)/c);
n=1;
t=1:50;
while n < 10
for i=1:31
for j=1:50
V(i,j)=R*sum((1-(-1)^n)/(n^4 *pi^4)*sin((n*pi*c*j)/L)*sin((n*pi*i)/L));
end
end
n=n+1;
end
figure(1)
plot(V(i,j),t)
Various ways of doing so:
1) Computing the sum up to one Nmax in one shot:
Nmax = 30;
Vijn = #(i,j,n) R*((1-(-1)^n)/(n^4 *pi^4)*sin((n*pi*c*j)/L)*sin((n*pi*i)/L));
i = 1:31;
j = 1:50;
n = 1:Nmax;
[I,J,N] = ndgrid(i,j,n);
V = arrayfun(Vijn,I,J,N);
Vc = cumsum(V,3);
% now Vc(:,:,k) is sum_n=1^{k+1} V(i,j,n)
figure(1);clf;imagesc(Vc(:,:,end));
2) Looping indefinitely
n = 1;
V = 0;
i = 1:31;
j = 1:50;
[I,J] = meshgrid(i,j);
while true
V = V + R*((1-(-1)^n)/(n^4 *pi^4)*sin((n*pi*c*J)/L).*sin((n*pi*I)/L));
n = n + 1;
figure(1);clf;
imagesc(V);
title(sprintf('N = %d',n))
drawnow;
pause(0.25);
end
Note that in your example you won't need many terms, since:
Every second term is zero (for even n, the term 1-(-1)^n is zero).
The terms decay with 1/n^4. In norms: n=1 contributes ~2e4, n=3 contributes ~4e2, n=5 contributes 5e1, n=7 contributes ~14, etc. Visually, there is a small difference between n=1 and n=1+n=3 but barely a noticeable one for n=1+n=3+n=5.
Given that so few terms are needed, the first approach is probably the better one. Also, skip the even indices, as you don't need them.
I am running a matlab code in order to solve a matrix in an iterative way, I am trying to solve x=A\b in every iteration until x --> 0 by changing A and b, in the first 3 iterations work fine until I reach a point where I start getting imaginary numbers in my solution.
Here is my code:
Q,H,n,R are predefined variables.
while(eps > 10^-6)
i=1;j=1;
while(i<11)
A11(i,j) = 1.852*R(i)*(abs(Q(i)))^(n-1);
i=i+1;
j=j+1;
end
A11(11,11) = 2*R(11)*abs(Q(11));
%calculate -dE & dq
dE = [200-H(1)-R(1)*Q(1)^1.852
H(1)-H(2)- R(2)*Q(2)^1.852
H(1)-H(3)-R(3)*Q(3)^1.852
H(2)-H(7)-R(4)*Q(4)^1.852
H(6)-H(5)-R(5)*Q(5)^1.852
H(7)-H(4)-R(6)*Q(6)^1.852
H(6)-H(7)-R(7)*(Q(7))^1.852
H(5)-H(4)-R(8)*Q(8)^1.852
H(3)-H(2)-R(9)*Q(9)^1.852
H(3)-H(4)-R(10)*Q(10)^1.852
0-H(3)+240- R(11)*Q(11)];
dq = [-Q(1)+Q(2)+Q(3)
-Q(2)-Q(9)+Q(4)+4
-Q(11)+Q(9)+Q(10)+6
-Q(10)-Q(6)-Q(8)+5
-Q(5)+Q(8)+5
-Q(3)+Q(7)+Q(5)+5
-Q(4)-Q(7)+Q(6)+3];
%formulate the full set of equations
zero=zeros(nn,nn);
b=[dE;dq];
upA = [A11,A12];
downA=[A21,zero];
A= [upA;downA];
%solve the equations (x=A\b)
x = A\b;
%update Q and H
i=1;j=1;
while (i<8 && j<12)
H(i)= x(11+i)+ H(i);
Q(j)= x(j)+ Q(j);
i=i+1;
j=j+1;
end
%check stopping criteria
j=1;sumeps=0;
while (j<12)
sumeps=sumeps+x(j);
j=j+1;
end
epscal = sumeps/12;
eps=abs(epscal)
end
I realized that i start getting problems when one of the values of vector Q turns negative, and when that value is raised to the power of 1.852 (while calculating dE) it gives an imaginary number!!
Maybe someone knows whre
That's correct. (-1)^N has an imaginary component whenever N has a fractional component.
Most obviously, (-1)^0.5 is just i.
It's not the fact hat the power is bigger than 1, it's the fact that the power is not an integer (i.e. X^2, X^3, ...). Imagine X^0.5 which equals sqrt(X). Obviously that yields an imaginary number for negative values of X.
I have the problem when I compute in a matrix. This problem is about the speed of computation.
I have a matrix of binary image (f), I find conected component by bwlabel in matlab. [L num]=bwlabel(f);
after that base on some property I found a vector p that include some value of L that I need to remove. this is my code and explanation
function [f,L] = clear_nontext(f,L,nontext)
% p is a vector include a lot of value we need to remove
p=find(nontext(:)~=0);
% example p= [1 2 9 10 100...] that mean we need to find in L matrix where get the value =1,2,9,10,100..] and remove it
[a b]=size(L);
g=zeros(a,b);
for u=1:length(p)
for i=1:a
for j=1:b
if L(i,j)==p(u)
g(i,j)=1;
%L(i,j)=500000;
f(i,j)=0;
end
end
end
end
end
When I use this way, program run but it is so slow, because with one value of p we need to check all value in matrix f (or L) again. So I need another way to run it faster. Could you help me?
Thank you so much
Generally, MATLAB performs matrix operations (or index operations) faster then loops.
You can try the following:
g(ismember(L,p)) = 1;
f(ismember(L,p)) = 1;
EDIT:
I was curious so I ran a little test:
L = round(20*randn(10000,10000));
f = L;
p = 1:5;
[a b]=size(L);
g=zeros(a,b);
tic;
for u=1:length(p)
for i=1:a
for j=1:b
if L(i,j)==p(u)
g(i,j)=1;
f(i,j)=0;
end
end
end
end
toc
for which I got:
Elapsed time is 38.960842 seconds.
When I tried the following:
tic;
g(ismember(L,p)) = 1;
f(ismember(L,p)) = 0;
toc
I got
Elapsed time is 5.735137 seconds.
clear all
k_1 = 37.6;
miu_1 = 41;
Den = 2.7;
N = 100;
n=1;
phi(1)=1;
for n=1:N
phi(n)= 0.3*(n/N);
K_s(n)= K_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
miu_s(n)= miu_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
den1(n)=Den*(1-phi(n));
vp(n)=sqrt((k_s(n)+(4/3)*miu_s(n))/den1(n));
end
figure(1);
plot(phi,miu_s);
figure(2);
plot (phi,vp)
i am new on matlab and do not know what is problem with my code when i run my program only a beep buzz and nothing happens. guide me
The reason your code doesn't work is case sensitivity. You are using k_1 and K_1, and k_s and K_s (unless that is intentional). When I change that, your code compiles ok.
clear all
k_1 = 37.6;
miu_1 = 41;
Den = 2.7;
N = 100;
n=1;
phi(1)=1;
for n=1:N
phi(n)= 0.3*(n/N);
k_s(n)= k_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
miu_s(n)= miu_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
den1(n)=Den*(1-phi(n));
vp(n)=sqrt((k_s(n)+(4/3)*miu_s(n))/den1(n));
end
figure(1);
plot(phi,miu_s);
figure(2);
plot (phi,vp)
when programming in MatLab, is usually a good practice to prealocate variables instead of declaring them in a loop. In this way, MatLab creates the object just once and changes each of it's values once in the loop. Otherwise you will be declaring a new variable and writing all its contents every loop iteration which is a costly process. Your Code might be working but be extreeeeemly slow, leading you to think nothing is happening. Try prealocating all the variables inside the loop with the zeros() function like this:
phi=zeros(N,1);
phi(1)=1;
K_s=zeros(N,1);
%... and so on for all your variables inside the loop
for n=1:N
phi(n)= 0.3*(n/N);
K_s(n)= k_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
miu_s(n)= miu_1*(1-(1+(3*k_1)/(4*miu_1))*phi(n));
den1(n)=Den*(1-phi(n));
vp(n)=sqrt((k_s(n)+(4/3)*miu_s(n))/den1(n));
end
Hope that helps
You are doing a lot of unnecessary things here, including that entire loop.
For example:
N = 100;
n=1; %this value is never used
phi(1)=1; % this is overwritten in loop
for n=1:N
phi(n)= 0.3*(n/N);
... (loop continues)
You don't need a loop here. Instead, work on whole vectors
N = 100;
n = 1:100; %predefine vector
phi = 0.3*(n/N); % outputs vector of phi from 0.003 to 0.3
For cases when you are combining multiple vectors remember to use ./ and .* for element-wise divison and multiplication, e.g. the last equation will end up being:
vp=sqrt((k_s+(4/3)*miu_s)./den1);
Once again I have a problem with the Gauss-Seidel Method in Matlab. Here it is:
function [x] = ex1_3(A,b)
format long
sizeA=size(A,1);
x=zeros(sizeA,1);
%Just a check for the conditions of the Gauss-Seidel Method (if it has dominant diagonal)
for i=1:sizeA
sum=0;
for j=1:sizeA
if i~=j
sum=sum+abs(A(i,j));
end
end
if abs(A(i,i))<sum
fprintf('\nGauss-Seidel''s conditions not met!\n');
return
end
end
%Actual Gauss-Seidel Method
max_temp=10^(-6); %Pass first iteration
while max_temp>(0.5*10^(-6))
xprevious=x;
for i=1:sizeA
x(i,1)=b(i,1);
for j=1:sizeA
if i~=j
x(i,1)=x(i,1)-A(i,j)*x(j,1);
end
end
x(i,1)=x(i,1)/A(i,i);
end
x
%Calculating infinite norm of vector x-xprevious
temp=x-xprevious;
max_temp=temp(1,1);
for i=2:sizeA
if abs(temp(i,1))>max_temp
max_temp=abs(temp(i,1));
end
end
end
It actually works fine for a 100x100 matrix or smaller. However, my tutor wants it to work for 100000x100000 matrices. At first it was difficult to even create the matrix itself, but I managed to do it with a little help from here:
Matlab Help Center
Now, I call the ex1_3 function with A as a parameter, but it goes really slow. Actually it never ends. How can I make it work?
Here's my code for creating the specific matrix my tutor wanted:
The important part is just that it meets these conditions:
A(i; i) = 3, A(i - 1; i) = A(i; i + 1) = -1 n=100000
b=ones(100000,1);
b(1,1)=2;
b(100000,1)=2;
i=zeros(299998,1); %Matrix with the lines that we want to put nonzero elements
j=zeros(299998,1); %Matrix with the columns that we want to put nonzero elements
s=zeros(299998,1); %Matrix with the nonzero elements.
number=1;
previousNumberJ=0;
numberJ=0;
for k=1:299998 %Our index in i and j matrices
if mod((k-1),3)==0
s(k,1)=3;
else
s(k,1)=-1;
end
if k==1 || k==2
i(k,1)=1;
j(k,1)=k;
elseif k==299997 || k==299998
i(k,1)=100000;
j(k,1)=(k-200000)+2;
else
if mod(k,3)==0
number=number+1;
numberJ=previousNumberJ+1;
previousNumberJ=numberJ;
end
i(k,1)=number;
j(k,1)=numberJ;
numberJ=numberJ+1;
end
end
A=sparse(i,j,s); %Creating the sparse array
x=ex1_3(A,b);
the for loop works very slowly in Matlab, perhaps you may want to try the matrix form of the iteration:
function x=gseidel(A,b)
max_temp=10^(-6); %Pass first iteration
x=b;
Q=tril(A);
r=b-A*x;
for i=1:100
dx=Q\r;
x=x+1*dx;
r=b-A*x;
% convergence check
if all(abs(r)<max_temp) && all(abs(dx)<max_temp), return; end
end
For your A and b, it only takes 16 steps to converge.
tril extracts the lower triangular part of A, you can also obtain this Q when you build up the matrix. Since Q is already the triangular matrix, you can solve the equation Q*dx=r very easily if you are not allowed to use \ function.