Might be growing inside the loop. Consider Prealocating for Speed - matlab

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);

Related

How to run a for loop using two variables at the same time in Matlab

I am using this command in Matlab:
grazAng = grazingang(H,R)
If i fix H, I can treat R as a vector:
z=[];
for i=1:1000
z(i)=abs(grazingang(1,i));
end
Now I would like to have both H and R to by dynamic. For example:
H=[0,0.25,0.5]
R=[1,2,3]
And I would like my loop to run three times, each time selecting a pair of (H,R) values with the same indexes, i.e. (0,1),(0.25,2),(0.5,3) and then store the result in z. Could anyone help me out with this?
Remember, everything in MATLAB is an array. To do this with a loop, you need to index into the arrays:
H = [0,0.25,0.5];
R = [1,2,3];
z = zeros(size(H)); % Pre-allocation is generally advised
for i = 1:1000
z(i) = abs(grazingang(H(i),R(i)));
end
But MATLAB functions generally accept vectors and do this for you, so all you need to do is:
H=[0,0.25,0.5];
R=[1,2,3];
z = abs(grazingang(H,R));

Newton Raphson method problem when iterating a variable

I need help with a problem. I written a program to calculate the value of a function using the Newton Raphson method. However, the function also has a variable i would like to iterate over, V. The program runs fine until the second iteration of the outer for loop, then the inner for loop will not run further once it reaches the Newton Raphson function. If someone has any ideas of what is wrong, I would greatly appreciate it. The error i get is: Warning: Solution does not exist because the system is inconsistent.
The code is below for detail.
for V = 1:50;
syms x;
f(V)= Il-x-Is.*(exp((q.*(V+x.*Rs))./(1000.*y.*K.*T))-1)-((V+x.*Rs)./Rsh);
g(V)=diff(f(V));
x0 = 0;
i = 1;
for i=1:10
f0=vpa(subs(f,x,x0));
f0_der=vpa(subs(g,x,x0));
y=x0-f0/f0_der; % Newton Raphson
x0=y;
end
end
Assuming you have a function defined like
func = #(x,V) V+x+exp(x);
There are plenty of options that avoid expensive symbolic calculations.
Firstly, making a vector of values of x0 using fzero and a for loop:
for V = 1:50
x0(V) = fzero(#(x) func(x,V),0);
end
Secondly, the same thing again but written as an anonymous function, so you can call x0(1.5) or x0(1:50):
x0 = #(V) arrayfun(#(s) fzero(#(x) func(x,s),0),V);
Finally, if you want to use ten steps of Newton's method and calculate the derivative symbolically (although this is not a great method),
syms y Vsym
g = matlabFunction(diff(func(y,Vsym),y),'Vars',[y Vsym]);
for V = 1:50
x0(V) = 0;
for i = 1:10
x0(V) = x0(V)-func(x0(V),V)/g(x0(V),V); % Newton Raphson
end
end
Which at least will be more efficient in the loops because it's just using anonymous functions.

Quickly Evaluating MANY matlabFunctions

This post builds on my post about quickly evaluating analytic Jacobian in Matlab:
fast evaluation of analytical jacobian in MATLAB
The key difference is that now, I am working with the Hessian and I have to evaluate close to 700 matlabFunctions (instead of 1 matlabFunction, like I did for the Jacobian) each time the hessian is evaluated. So there is an opportunity to do things a little differently.
I have tried to do this two ways so far and I am thinking about implementing a third and was wondering if anyone has any other suggestions. I will go through each method with a toy example, but first some preprocessing to generate these matlabFunctions:
PreProcessing:
% This part of the code is calculated once, it is not the issue
dvs = 5;
X=sym('X',[dvs,1]);
num = dvs - 1; % number of constraints
% multiple functions
for k = 1:num
f1(X(k+1),X(k)) = (X(k+1)^3 - X(k)^2*k^2);
c(k) = f1;
end
gradc = jacobian(c,X).'; % .' performs transpose
parfor k = 1:num
hessc{k} = jacobian(gradc(:,k),X);
end
parfor k = 1:num
hess_name = strcat('hessian_',num2str(k));
matlabFunction(hessc{k},'file',hess_name,'vars',X);
end
METHOD #1 : Evaluate functions in series
%% Now we use the functions to run an "optimization." Just for an example the "optimization" is just a for loop
fprintf('This is test A, where the functions are evaluated in series!\n');
tic
for q = 1:10
x_dv = rand(dvs,1); % these are the design variables
lambda = rand(num,1); % these are the lagrange multipliers
x_dv_cell = num2cell(x_dv); % for passing large design variables
for k = 1:num
hess_name = strcat('hessian_',num2str(k));
function_handle = str2func(hess_name);
H_temp(:,:,k) = lambda(k)*function_handle(x_dv_cell{:});
end
H = sum(H_temp,3);
end
fprintf('The time for test A was:\n')
toc
METHOD # 2: Evaluate functions in parallel
%% Try to run a parfor loop
fprintf('This is test B, where the functions are evaluated in parallel!\n');
tic
for q = 1:10
x_dv = rand(dvs,1); % these are the design variables
lambda = rand(num,1); % these are the lagrange multipliers
x_dv_cell = num2cell(x_dv); % for passing large design variables
parfor k = 1:num
hess_name = strcat('hessian_',num2str(k));
function_handle = str2func(hess_name);
H_temp(:,:,k) = lambda(k)*function_handle(x_dv_cell{:});
end
H = sum(H_temp,3);
end
fprintf('The time for test B was:\n')
toc
RESULTS:
METHOD #1 = 0.008691 seconds
METHOD #2 = 0.464786 seconds
DISCUSSION of RESULTS
This result makes sense because, the functions evaluate very quickly and running them in parallel waists a lot of time setting up and sending out the jobs to the different Matlabs ( and then getting the data back from them). I see the same result on my actual problem.
METHOD # 3: Evaluating the functions using the GPU
I have not tried this yet, but I am interested to see what the performance difference is. I am not yet familiar with doing this in Matlab and will add it once I am done.
Any other thoughts? Comments? Thanks!

compute speed in for loop matlab

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.

Fixed Point Iteration

I am new to Matlab and I have to use fixed point iteration to find the x value for the intersection between y = x and y = sqrt(10/x+4), which after graphing it, looks to be around 1.4. I'm using an initial guess of x1 = 0. This is my current Matlab code:
f = #(x)sqrt(10./(x+4));
x1 = 0;
xArray(10) = [];
for i = 1:10
x2 = f(x1);
xArray(i) = x2;
x1 = x1 + 1;
end
plot(xArray);
fprintf('%15.8e\n',xArray);
Now when I run this it seems like my x is approaching 0.8. Can anyone tell me what I am doing wrong?
Well done. You've made a decent start at this.
Lets look at the graphical solution. BTW, this is how I'd have done the graphical part:
ezplot(#(x) x,[-1 3])
hold on
ezplot(#(x) sqrt(10./(x+4)),[-1 3])
grid on
Or, I might subtract the two functions, then looking for a zero of the difference, so where it crosses the x axis.
This is what the fixed point iteration does anyway, trying to solve for x, such that
x = sqrt(10/(x+4))
So how would I change your code to fix it? First of all, I'd want to use more descriptive names for the variables. You don't get charged by the character, and making your code easier to read & follow will pay off greatly in the future for you.
There were a couple of code issues. To initialize a vector, use a form like one of these:
xArray = zeros(1,10);
xArray(1,10) = 0;
Note that if xArray was ALREADY defined because you have been working on this problem, the latter form will only zero out that single element. So the first form is best by a large margin. It affirmatively creates an array, or overwrites an existing array if it is already present in your workspace.
Finally, I like to initialize an array like this with something special, rather than zero, so we can see when an element was overwritten. NaNs are good for this.
Next, there was no need to add one to x1 in your code. Again, I'd strongly suggest using better variable names. It is also a good idea to use comments. Be liberal.
I'd suggest the idea of a convergence tolerance. You can also have an iteration counter.
f = #(x)sqrt(10./(x+4));
% starting value
xcurrent = 0;
% count the iterations, setting a maximum in maxiter, here 25
iter = 0;
maxiter = 25;
% initialize the array to store our iterations
xArray = NaN(1,maxiter);
% convergence tolerance
xtol = 1e-8;
% before we start, the error is set to be BIG. this
% just lets our while loop get through that first iteration
xerr = inf;
% the while will stop if either criterion fails
while (iter < maxiter) && (xerr > xtol)
iter = iter + 1;
xnew = f(xcurrent);
% save each iteration
xArray(iter) = xnew;
% compute the difference between successive iterations
xerr = abs(xnew - xcurrent);
xcurrent = xnew;
end
% retain only the elements of xArray that we actually generated
xArray = xArray(1:iter);
plot(xArray);
fprintf('%15.8e\n',xArray);
What was the result?
1.58113883e+00
1.33856229e+00
1.36863563e+00
1.36479692e+00
1.36528512e+00
1.36522300e+00
1.36523091e+00
1.36522990e+00
1.36523003e+00
1.36523001e+00
1.36523001e+00
For a little more accuracy to see how well we did...
format long g
xcurrent
xcurrent =
1.36523001364783
f(xcurrent)
ans =
1.36523001338436
By the way, it is a good idea to know why the loop terminated. Did it stop for insufficient iterations?
The point of my response here was NOT to do your homework, since you were close to getting it right anyway. The point is to show some considerations on how you might improve your code for future work.
There is no need to add 1 to x1. your output from each iteration is input for next iteration. So, x2 from output of f(x1) should be the new x1. The corrected code would be
for i = 1:10
x2 = f(x1);
xArray(i) = x2;
x1 = x2;
end
f(x)x^3+4*x^2-10 in [1,2] find an approximate root