Creating a universal code - matlab

I have been working on creating a universal equation to calculate the theta function. The current equation I have is not universal. This works for maximum of 2 thetas. If I have to do the calculation for theta more than 2, I have to manually modify the numbers within the brackets of theta().
Is there any way to setup a universal function? something like thata(j) = equation. I have pasted two codes below, one that is working but not universal and the other that I tried playing with and still ended up with error.
Code 1:
for iter = 1:num_iters
theta(1) = theta(1) - (alpha/m)*((X*theta-y)')*X(:,1),
theta(2) = theta(2) - (alpha/m)*((X*theta-y)')*X(:,2);
theta_hist(iter,1) = theta(1);
theta_hist(iter,2) = theta(2);
end
Code 2:
num_cols = size(X,2)
for inter = 1:num_iters
for j = 1:num_cols
theta(j) = theta(j) - (alpha/m)*((X*theta-y)')*X(:,j),
end,
end,
The challenge with this code is that the when the code goes through the loop second time (i=1, j=2). The function is using the new value of the theta. This is screwing up the calculation.
Any feedbacks or suggestion is greatly appreciated.
More description of this issue is mentioned in the link below:
https://docs.google.com/document/d/1XwAVV1OBN9BhQ7n60F2oEUoT263t_2hcAAuCaroR-2g/edit?usp=sharing

After multiple iterations, I was able to answer my own question.
The code is posted on github in the link below:
https://github.com/Boniface316/Octave/tree/master/GradientDescent_ThetaCalculator
Thanks for all the help.

You should vectorize your code. You haven't provided matrix dimenstions and/or sample inputs, but if I'm guessing it correctly, the following should give you what you need:
% Some random inputs
alpha = 1;
m = 1;
num_iters = 15;
N = 5; k = 12;
X = randn(k,N);
y = randn(k,1);
theta = zeros(N,1);
theta_hist = zeros(N,num_iters);
for i = 1:num_iters
theta = theta - (alpha/m)*X'*(X*theta-y);
theta_hist(:,i) = theta;
end

Related

Why my genetic algorithm doesn't converge?

At first I create a script giving the name multi_002
After I create the function that includes the equation
The script calls the function and reads the array 'a'.
Each array include one equation a(i) = x - i
I want to minimize its equation of the 4 lines array 'a'.
I suspect that something doesn't work right. I notice that
Optimtool works but f1,f2,f3,f4 doesn't go to zero. With another words
there isn't convergence.
FitnessFunction = #array_002;
numberOfVariables = 1;
[x,fval] = gamultiobj(FitnessFunction,numberOfVariables);
function [a,y,c]= array_002(x)
size = 4; n = 4;
y = zeros(size,1);
c = zeros(size,1);
for i = 1:n
y(i) = x;
c(i) = i;
a = y - c;
end
Why my genetic algorithm doesn't converge? Is there any idea?
Thank you in advance!

Matlab PDE Solver Issue

Im trying to solve the transient heat equation in 1D and comparing the analytical and numerial solutions. The solutions have the same trend but are very different, also the relative error is coming out to be zero, even though its clearly not supposed to be. Im not sure if I have solved the PDE correctly. (the pde is du/dt = d^2u/dx^2) and bcs are u(0,t)=1, u(100,t) = 0, u(x,0)=0. Can someone please take a look at my code?
function he
m = 0;
x = linspace(0,100,500);
t = linspace(0,1000,500);
sol = pdepe(m,#hepde,#heic,#hebc,x,t);
u = sol(:,:,1);
y = erfc(x./(2*(t.^0.5)));
r=(y-u(70,:))/y;
figure;
plot(x,u(50,:),'.',x,u(150,:),'.',x,u(250,:),'.',x,u(end,:),'.',x,y,'.');
title('Numerical Solutions at different times.');
legend('t=100','t=300','t=500','t=700','y ana',0);
xlabel('Distance x');
ylabel('u(x,t)');
figure;
plot(x,r);
title('error in numerical and analytical solution');
legend('error',0);
xlabel('Distance x');
ylabel('error');
% --------------------------------------------------------------------------
function [c,f,s] = hepde(x,t,u,DuDx)
c = 1;
f = DuDx;
s = 0;
% --------------------------------------------------------------------------
function u0 = heic(x)
u0 = 0;
% --------------------------------------------------------------------------
function [pl,ql,pr,qr] = hebc(xl,ul,xr,ur,t)
pl = ul-1;
ql = 0;
pr = ur;
qr = 0;
You actually had the solution all set up correctly, you just used the results incorrectly. I'll go through the errors one by one.
sol = pdepe(m,#hepde,#heic,#hebc,x,t);
u = sol(:,:,1);
You found the right answer, but the line u=sol(:,:,1); is useless as size(sol)=[2 2], so you may as well just do u=pdepe(...);.
Now when you calculated your exact solution you did it very strangely. You want to find it at each x/t combination, but you did it only at some of them. You need to use meshgrid to get all the combinations of x and t then calculate your exact solution at each one.
[X,T]=meshgrid(x,t);
y = erfc(X./(2*(T.^0.5)));
Then you need to calculate the error differently.
r=(y-u)./y;
figure(3);
And plot differently.
plot(x,u(50,:),'b',x,u(150,:),'g',x,u(250,:),'r',x,u(end,:),'c',x,y(50,:),'b--',x,y(150,:),'g--',x,y(250,:),'r--',x,y(end,:),'c--');
Actually your exact solution doesn't satisfy the boundary condition at x=100......

Matlab: 1D Numerical PDEs without Loops

So, currently I am trying to find the numerical solutions for the berger equation, $u_t+u∗u_x=0$. The numerical solution to this equation is:
$u^{n+1}_j=u_n^j−\frac{Δx}{Δt}u^n_j(u^n_j−u^n_{j−1})$
I wrote code on Matlab that computes this. As you can see, there is only one for-loop in the code. However, my u matrix extremely large, the algorithm becomes slow. Is there a way for me to use no loops at all. I was thinking about using the command cumsum, but I am not sure how to integrate that to my program. Please look at my code. Thanks.
dx = 0.9;
dt = 0.9;
tf = 10;
l = 10;
xstep = [-1:dx:l];
tstep = [0:dt:tf];
uinit = zeros(length(tstep),length(xstep));
%%Setting Initial and Boundary Conditions
bc.left = #(t) 2;
bc.right = #(t) -1;
ic = #(x) ...
2*(x<=0) ...
-1*(x>0);
uinit(1, :) = ic(xstep);
uinit(:, 1) = bc.left(tstep);
uinit(:, end) = bc.right(tstep);
%% Numerical method part
for c=1:(length(tstep)-1)
uinit(2:end -1, c+1) = uinit(2:end -1, c) - dx/dt*(uinit(2:end -1, c).*(uinit(2:end-1, c) - uinit(1:end-2, c)));
end
surf(xstep,tstep,uinit)

Is this correct approach for a single summation in time domain in Matlab?

I am trying to do a single summation of a function in the time domain. I got my code working, but I would feel more confident if someone would verify the correctness or point out my mistakes.
Here is a picture of the formula I am trying to code:
And here is the code itself:
h = 100;
t=[1:400];
rho_w = 1025;
g = 9.81;
Ohm = [0.01:0.01:4]
Phase = rand(1,length(Ohm))*2*pi;
Amp = [1:1:400];
for i = 1:length(t)
P(i) = rho_w*g*sum(Amp.*Ohm.*cos(Ohm*t(i)+Phase))
end
I think it's correct (thanks to #horchler for his valuable comment).
You can also do it with bsxfun:
P = rho_w*g*sum( bsxfun(#times, (Amp.*Ohm).', ...
cos(bsxfun(#plus, bsxfun(#times, Ohm.', t), Phase.'))) );

“dumb” version of Euler’s method using Matlab

I tried to write the 'dumb' version of Euler's method using Matlab but I always came up with nothing. My code was trash :-(
See this pseudocode for this method :
‘set integration range
xi = 0
xf = 0
‘initialize variables
x = xi
y = 1
‘set step size and determine
‘number of calculation steps
dx = 0.5
nc = (xf – xi) / dx
‘ output initial condition
PRINT x, y
‘Loop to implement Euler’s method
‘and display results
DOFOR I = 1, nc
dydx = -(2X**3) + (12X**2) - (20X) + 8.5
y = y + dydx . dx
x = x + dx
PRINT x, y
END DO
I'm pretty sure that this pseudocode is what I need to implement, but I failed to convert it into Matlab code.
Any help please ?
I am not sure where you're failing, it would really help to know how you're failing or what's a complication. Otherwise this just seems like doing your homework.
Here's my attempt at the MATLAB code. (Note: I do not have MATLAB on this computer and have not tested it)
i = 0;
stepsize = .1; % Define as what you want it to be
y = 1; % Initial value condition given
t = 0; % Initial time value
yout = [zeros(1,20)]; % Assuming you want 20 outputs, can change
fvec = [zeros(1,20)];
for i = 1:20 % Time range, can change to correspond to what you want
fvec(i) = 2 - exp(-4*t) - 2*yout(i); % Just loops calculating based on Euler's method
yout(i+1) = yout(i) + stepsize*fvec(i)
t = t+stepsize % Time has passed, increment the time.
end
I'm not entirely sure this code, but it should give you an example of how to go about this. Please comment if something is wrong.