Numerically solving a pde with changing domain in Matlab - matlab

I'm trying to implement a changing domain into my Matlab code which solves a pde numerically. In the given problem, I am modelling the baking of bread. It is a 1D problem where there is a single heat source from above. I am using the heat diffusion equation and for a fixed domain, I have provided my code below which solves it. However, I need to also model the rising of the bread, so over time my domain, 'L' in my code, changes. I am told that I can assume it changes linearly over an hour and that the bread initially fills 80% of the tin. What suggestions do you guys have for how I can account for the rising?
close all
clear all
clc
Tend = 3600; %Time to end after
dt = 1; %Time step size
Nstep = (Tend/dt)+1; %Number of time points
M = 1000; %Number of x points
dx = 1/M; %Size of the x steps
L = 1; %Length of domain
x = [0:dx:L]; %Creating the x points
kdiff = 2.7e-4; %Diffusion constant value
R = kdiff*dt/(dx*dx);
for i = 1:M+1
u(i,1) = 20;
end
for n = 1:Nstep
DIG(1) = 1;
b(1) = 200; %Boundry condition
DIG(M+1) = 1;
LF(1) = 0;
RT(1) = 0;
LF(M+1) = -1; %Insulated boundry
RT(M+1) = 0;
b(M+1) = 0; %Boundry condition
for m = 2:M
DIG(m) = 2+(2/R);
LF(m) = -1;
RT(m) = -1;
b(m) = u(m+1,n) + u(m-1,n) + (-2 + (2/R))*u(m,n);
end
u(:,n+1) = tdma(LF,DIG,RT,b,M+1);
end
plot(x,u(:,1:600:end)

Related

MATLAB Neural Network - Forward Propagation

I am creating a Forward Propagation In the feedforward step, an input pattern is propagated through the network to obtain an output. I have written this in pseudo code and currently attempting to implement this within MATLAB.
There are two errors I currently receive.
Patterns = x'; Desired = y; NHIDDENS = 1; prnout=Desired;
% Patterns become x so number of inputs becomes size of patterns
[NINPUTS,NPATS] = size(Patterns); [NOUTPUTS,NP] = size(Desired);
%apply the backprop here...
LearnRate = 0.15; Momentum = 0; DerivIncr = 0; deltaW1 = 0; deltaW2 = 0;
% Keeps the tan ordering of the examples of x
Inputs1= [Patterns;ones(1,NPATS)]; %Inputs1 = [ones(1,NPATS); Patterns];
% Weight initialisation
Weights1 = 0.5*(rand(NHIDDENS,1+NINPUTS)-0.5);
Weights2 = 0.5*(rand(1,1+NHIDDENS)-0.5);
TSS_Limit = 0.02;
for epoch = 1:10
% FORWARD LOOP
size(NOUTPUTS)
size(NPATS)
for ii = 0: ii < length(NINPUTS)
NOUTPUTS(ii+1) = NPATS(ii);
% Sets bias to 1
NOUTPUTS(1) = 1;
end
for ii = NHIDDENS: ii < NINPUTS
sum = 0;
for ij = 0: ij < ii
sum = sum + deltaW1(ii,ij) * NOUTPUTS(ij);
NOUTPUTS(ii) = tanh(sum);
end
end
Unable to perform assignment because the
left and right sides have a different
number of elements.
Error in mlpts (line 66)
NOUTPUTS(i+1) = NPATS(i);
i am still new to MATLAB and trying to become use to it.
After iterating through the loop
NOUTPUTS = 0 and the error is displayed. I am confused as I am trying to increment NOUTPUTS with ii by 1 through each loop.
I have been able to create the forward propagation with a loop.
for i =3:NNODES
summ = 0;
for j=1:i-1
summ = summ + weights(i,j) * Node_outputs(j);
end
if i == NNODES
Node_outputs(i) = summ
else
Node_outputs(i) = sigmoid(summ);
end
end
Out = Node_outputs(NNODES);
% BOut = ((Node_outputs(NNODES)) * (1 - Node_outputs));
BOut=zeros(1,6);
DeltaWeight = zeros(6,6);

single perceptron not converging

I am programming a simple perceptron in matlab but it is not converging and I can't figure out why.
The goal is to binary classify 2D points.
%P1 Generate a dataset of two-dimensional points, and choose a random line in
%the plane as your target function f, where one side of the line maps to +1 and
%the other side to -1. Let the inputs xn 2 R2 be random points in the plane,
%and evaluate the target function f on each xn to get the corresponding output
%yn = f(xn).
clear all;
clc
clear
n = 20;
inputSize = 2; %number of inputs
dataset = generateRandom2DPointsDataset(n)';
[f , m , b] = targetFunction();
signs = classify(dataset,m,b);
weights=ones(1,2)*0.1;
threshold = 0;
fprintf('weights before:%d,%d\n',weights);
mistakes = 1;
numIterations = 0;
figure;
plotpv(dataset',(signs+1)/2);%mapping signs from -1:1 to 0:1 in order to use plotpv
hold on;
line(f(1,:),f(2,:));
pause(1)
while true
mistakes = 0;
for i = 1:n
if dataset(i,:)*weights' > threshold
result = 1;
else
result = -1;
end
error = signs(i) - result;
if error ~= 0
mistakes = mistakes + 1;
for j = 1:inputSize
weights(j) = weights(j) + error*dataset(i,j);
end
end
numIterations = numIterations + 1
end
if mistakes == 0
break
end
end
fprintf('weights after:%d,%d\n',weights);
random points and signs are fine since plotpv is working well
The code is based on that http://es.mathworks.com/matlabcentral/fileexchange/32949-a-perceptron-learns-to-perform-a-binary-nand-function?focused=5200056&tab=function.
When I pause the infinite loop, this is the status of my vairables:
I am not able to see why it is not converging.
Additional code( it is fine, just to avoid answers asking for that )
function [f,m,b] = targetFunction()
f = rand(2,2);
f(1,1) = 0;
f(1,2) = 1;
m = (f(2,2) - f(2,1));
b = f(2,1);
end
function dataset = generateRandom2DPointsDataset(n)
dataset = rand(2,n);
end
function values = classify(dataset,m,b)
for i=1:size(dataset,1)
y = m*dataset(i,1) + b;
if dataset(i,2) >= y, values(i) = 1;
else values(i) = -1;
end
end
end

Finding the Optimum Input for a Simulation in Matlab

I have the following simulation running in Matlab. For a period of 25 years, it simulates "Assets", which grow according to geometric brownian motion, and "Liabilities", which grow at a fixed rate of 7% each year. At the end of the simulation, I take the ratio of Assets to Liabilities, and the trial is successful if this is greater than 90%.
All inputs are fixed except for Sigma (the standard deviation). My goal is to find the lowest possible value of sigma that will result in a ratio of assets to liabilities > 0.9 for every year.
Is there anything in Matlab designed to solve this kind of optimization problem?
The code below sets up the simulation for a fixed value of sigma.
%set up inputs
nPeriods = 25;
years = 2016:(2016+nPeriods);
rate = Assumptions.Returns;
sigma = 0.15; %This is the input that I want to optimize
dt = 1;
T = nPeriods*dt;
nTrials = 500;
StartAsset = 81.2419;
%calculate fixed liabilities
StartLiab = 86.9590;
Liabilities = zeros(size(years))'
Liabilities(1) = StartLiab
for idx = 2:length(years)
Liabilities(idx) = Liabilities(idx-1)*(1 + Assumptions.Discount)
end
%run simulation
obj = gbm(rate,sigma,'StartState',StartAsset);
%rng(1,'twister');
[X1,T] = simulate(obj,nPeriods,'DeltaTime',dt, 'nTrials', nTrials);
Ratio = zeros(size(X1))
for i = 1:nTrials
Ratio(:,:,i)= X1(:,:,i)./Liabilities;
end
Unsuccessful = Ratio < 0.9
UnsuccessfulCount = sum(sum(Unsuccessful))
First make your simulation a function that takes sigma as the input:
function f = asset(sigma)
%set up inputs
nPeriods = 25;
years = 2016:(2016+nPeriods);
rate = Assumptions.Returns;
%sigma = %##.##; %This is the input of the function that I want to optimize
dt = 1;
T = nPeriods*dt;
nTrials = 500;
StartAsset = 81.2419;
%calculate fixed liabilities
StartLiab = 86.9590;
Liabilities = zeros(size(years))'
Liabilities(1) = StartLiab
for idx = 2:length(years)
Liabilities(idx) = Liabilities(idx-1)*(1 + Assumptions.Discount)
end
%run simulation
obj = gbm(rate,sigma,'StartState',StartAsset);
%rng(1,'twister');
[X1,T] = simulate(obj,nPeriods,'DeltaTime',dt, 'nTrials', nTrials);
Ratio = zeros(size(X1))
for i = 1:nTrials
Ratio(:,:,i)= X1(:,:,i)./Liabilities;
end
Unsuccessful = Ratio < 0.9
UnsuccessfulCount = sum(sum(Unsuccessful))
f = sigma + UnsuccessfulCount
end
Then you can use fminbnd (or fminsearch for multiple inputs) to find the minimized value of sigma.
Sigma1 = 0.001;
Sigma2 = 0.999;
optSigma = fminbnd(asset,Sigma1,Sigma2)

Matlab solution for non-homogenous heat equation using finite differences

Given the following PDE (non-homogenous heat equation):
ut(x,t) = c2uxx(x,t) + f(x,t)
u(0,t) = u(l,t) = 0
u(x,0) = g(x)
0 < x < l ; t > 0 ; c > 0
I wrote the following code in Matlab, to solve the problem using finite differences:
syms xj tk
% Manually define this values
c = 9;
f(xj,tk) = xj;
g(xj) = 0*xj;
l = 1;
Tmax = 0.1;
% Grid definition
Nx = 50;
Nt = 50;
hx = 1/Nx;
ht = 1/Nt;
x = 0:hx:l;
t = 0:ht:Tmax;
lambda = c^2*ht/hx^2;
% Our target
u = zeros(Nx+1,Nt+1);
% Initial values
for j=1:Nx,
u(j,1) = g(x(j)); % u(x,0) = g(x)
end
for k=1:Nx,
u(1,k+1) = 0; % border condition u(0,t) = 0
for j=2:Nt,
u(j,k+1) = u(j,k) + lambda*(u(j+1,k)-2*u(j,k)+u(j-1,k)) + ht*f(j,k); % the formula here is ok
end
u(Nt,k+1) = 0; % border condition u(l,t) = 0
end
contour3(u)
For some reason that I cant't figure out, data is only appearing in the last columns and in a very strange way.
I'm guessing the implementation of the BC's are doing something nasty. But I don't see it.
Is there something that I'm missing?
Thanks in advance!

Using Heat Equation to blur images using Matlab

I am trying to use the PDE heat equation and apply it to images using Matlab. The problem i am having is that the image isn't blurring , it is just going white. Also, I am getting different results from the rest of the class who is using Maple.
Here is the code:
% George Lees Jr.
% Heat equation
clear,clc;
dx = 1;
dy = 1;
dt = .025;
%dt/(dx*dx)
t = 0;
time = 3;
T_old = imread('tulipgray.jpg');
T_temp=T_old;
[m,n,k] = size(T_temp);
%colormap gray;
%imagesc(T_temp);
%imshow(T_old);
T_new = T_temp;
T_new=ind2gray(T_new,colormap);
%T_new(:,50)=0;
%T_old(1,70)
%imagesc(T_new);
%diff_x = dt/(dx*dx)
%diff_y = dt/ (dy*dy)
%time = 0;
while t < time
for i = 2:1:m-1
for j = 2:1:n-1
T_new(i,j) = T_temp(i,j) + dt*(T_temp(i+1,j) -2*T_temp(i,j) + T_temp(i-1,j)) + dt*(T_temp(i,j+1)-2*T_temp(i,j) + T_temp(i,j-1));
t = t+dt;
T_temp(i,j) = T_new(i,j);
end
end
end
figure
imshow(T_new)
Yeah the image just gets whiter
There's 2 issues with your code:
1) you're incrementing the time counter after each individual pixel instead of after doing the whole image
2) you need to do the calculations on floating points values, not integers. dt is small, so the values from the RHS of the equation are <1
Fixed code should look something like this
clear,clc;
dt = 0.025;
time = 3;
T_old = imread('rice.png');
T_temp=double(T_old);
[m,n,k] = size(T_temp);
T_new = double(T_temp);
T_new=ind2gray(T_new,colormap);
while t < time
for i = 2:1:m-1
for j = 2:1:n-1
T_new(i,j) = T_temp(i,j) + dt*(T_temp(i+1,j) -2*T_temp(i,j) + T_temp(i-1,j)) + dt*(T_temp(i,j+1)-2*T_temp(i,j) + T_temp(i,j-1));
end
end
T_temp = T_new;
t = t+dt;
imshow(uint8(T_new))
getframe;
end