how to plot the solution to this PDE? - maple

Maple generates a strange solution form for this PDE. I am having hard time plotting the solution.
The solution is in terms of infinite series. I set the number of terms to say 20, and then set the time to plot the solution at t=2 seconds. Then want to plot the solution now for x=0..1. But the plot comes out empty.
When I sample the solution, and use listplot, I get correct solution plot.
Here is MWE
restart;
pde:=diff(u(x,t),t)=diff(u(x,t),x$2)+x;
bc:=u(0,t)=0,u(1,t)=0;
ic:=u(x,0)=x*(1-x);
sol:=pdsolve({pde,ic,bc},u(x,t)):
sol:=value(sol);
Now set the number of terms to 20 and set t=2
sol2:=subs(t=2,sol):
sol2:=subs(infinity=20,sol2);
The above is what I want to plot.
plot(rhs(sol2),x=0..1);
I get empty plot
So had to manually sample it and use listplot
f:=x->rhs(sol2);
data:=[seq([x,f(x)],x=0..1,.01)]:
plots:-listplot(data);
Solution looks correct, when I compare it to Mathematica's result. But Mathematica result is simpler as it does not have those integrals in the sum.
pde=D[u[x,t],t]==D[u[x,t],{x,2}]+x;
bc={u[0,t]==0,u[1,t]==0};
ic=u[x,0]==x(1-x);
DSolve[{pde,ic,bc},u[x,t],x,t];
%/.K[1]->n;
%/.Infinity->20;
%/.t->2;
And the plot is
Question is: How to plot Maple solution without manually sampling it?

Short answer seems to be that it is a regression in Maple 2017.3.
For me, your code works directly in Maple 2017.2 and Maple 2016.2 (without any unevaluated integrals). I will submit a bug report against the regression.
[edited] Let me know if any of these four ways work for your version (presumably Maple 2017.3).
restart;
pde:=diff(u(x,t),t)=diff(u(x,t),x$2)+x;
bc:=u(0,t)=0,u(1,t)=0;
ic:=u(x,0)=x*(1-x);
sol:=pdsolve({pde,ic,bc},u(x,t)):
sol:=value(sol);
sol5:=value(combine(subs([sum=Sum,t=2,infinity=20],sol))):
plot(rhs(sol5),x=0..1);
sol4:=combine(subs([sum=Sum,t=2,infinity=20],sol)):
(UseHardwareFloats,oldUHF):=false,UseHardwareFloats:
plot(rhs(sol4),x=0..1);
UseHardwareFloats:=oldUHF: # re-instate
sol2:=subs([sum=Sum,int=Int,t=2],sol):
# Switch integration and summation in second summand of rhs(sol).
sol3:=subsop(2=Sum(int(op([2,1,1],rhs(sol2)),op([2,2],rhs(sol2))),
op([2,1,2],rhs(sol2))),rhs(sol2)):
# Rename dummy index and combine summations.
sol3:=Sum(subs(n1=n,op([1,1],sol3))+op([2,1],sol3),
subs(n1=n,op([1,2],sol3))):
# Curtail to first 20 terms.
sol3:=lhs(sol2)=subs(infinity=20,simplify(sol3));
plot(rhs(sol3),x=0..1);
F:=unapply(subs([Sum='add'],rhs(sol3)),x):
plot(F,0..1);
[edited] Here is yet another way, working for me in Maple 2017.3 on 64bit Linux.
It produces the plot quickly, and doesn't involve curtailing any sum at 20 terms. Note that it does not do your earlier step of sol:=value(sol); since it does active int rather than Int before hitting any Sum with value. It also uses an assumption on x corresponding to the plotting range.
restart;
pde:=diff(u(x,t),t)=diff(u(x,t),x$2)+x:
bc:=u(0,t)=0,u(1,t)=0:
ic:=u(x,0)=x*(1-x):
sol:=pdsolve({pde,ic,bc},u(x,t)):
solA:=subs(sum=Sum,value(eval(eval(sol,t=2),Int=int))) assuming x>0, x<1;
plot(rhs(solA),x=0..1) assuming x>0, x<1;

Related

Exploring a t-distribution

I am tasked with creating a t-distribution for a homework problem. I have created the code, but I get a result that doesn't look like a t-distribution. What am I doing wrong?
Task:
u=0
n=20
for i=1:5000;
r=randn(20,1);
x(i)=mean(r);
s(i)=std(r);
t(i)=(x-u)/(s/sqrt(n)) ;
end
hist(t)
Hmm, I suspect that you are not using the operator that you think you are using. division is not just limited to scalars, and here you're accidentally getting a scalar result from a matrix operation.
Hint: when you calculate the ith value of t, you probably only want to be using the ith terms for mean and standard deviation.
As pointed out by Matt, you have forgotten to iterate through the means and standard deviation values. What are you doing now is dividing two arrays. Matlab interprets your code then as scalar product of array x and transposed array s. That is why the result is a scalar and the error is not so easy to spot.
Updated code should be fine:
clc
clear
u=0.0
n=20
for i=1:5000
r=randn(n,1);
x(i)=mean(r);
s(i)=std(r);
t(i)=(x(i)-u)/(s(i)/sqrt(n)) ;
end
hist(t)
Generated result for me:
Hint: For small scripts I advise you to add clc (clear command window) and clear (clears workspace) command lines. Sometimes there might be a lot of garbage from previous runned scripts that might spoil the result, and clearing command window definitely make it easier to debug, at least for me.

how to convert this result using exponentials to hyperbolic trig functions?

The solution to Laplace PDE on rectangle is usually written using hyperbolic trig functions. I solve this PDE using Maple. Verified Maple solution is correct. But having hard time figuring how to make its result match the book result.
I tried sol:=convert(rhs(sol),trigh): then simplify(sol,trig); and it become little closer to the book solution, but is still can be more simplified.
Are there any tricks to do this?
Here is MWE
restart;
interface(showassumed=0):
pde:=diff(u(x,y),x$2)+diff(u(x,y),y$2)=0:
bc:=u(0,y)=0,u(a,y)=f(y),u(x,0)=0,u(x,b)=0:
sol:=pdsolve([pde,bc],u(x,y)) assuming(0<=x and x<=a and 0<=y and y<=b):
sol:=subs(infinity=20,sol);
Which gives
The above is same as the following, which I am trying to convert the above to
textbookU:= Sum(2*sin(n*Pi*y/b)*(Int(sin(n*Pi*y/b)*f(y),
y = 0 .. b))*sinh(n*Pi*x/b)/(b*sinh(n*Pi*a/b)), n = 1 .. 20);
The above are the same. I checked few points, and they give same answer. They must be the same, as the above textbook solution is correct, and I am assuming Maple solution is correct.
Now I tried to convert Maple sol to the above as follows
sol:=convert(rhs(sol),trigh):
simplify(sol,trig);
May be someone knows a better way to obtain the textbook solution form, starting from the Maple solution above.
Using Maple 2017.3 on windows
After the convert you can first expand it, to then simplify it again:
s := convert(sol, trigh):
s := expand(s):
simplify(s);
which gives:

Using MATLAB pcg to Solve Inexactly

I am using MATLAB's PCG subroutine to solve a system of linear equations. However, I don't want it to solve exactly. I want it to run for only 20 iterations and if it doesn't converge, I want it to return the value at the 20th iteration.
What MATLAB (My version is the latest one) is doing however is returning a zero vector if it doesn't find an acceptable solution by 20 iterations. Is there any way to override this without changing the source code of pcg.m?
I have a code which I wrote which does that (I just copied from Wikipedia) but obviously, it is not close to how robust MATLAB's version is.
function [x] = conjgrad(A,b,x)
r=b-A*x;
p=r;
rsold=r'*r;
for i=1:20
Ap=A*p;
alpha=rsold/(p'*Ap);
x=x+alpha*p;
r=r-alpha*Ap;
rsnew=r'*r;
if sqrt(rsnew)<1e-10
break;
end
p=r+rsnew/rsold*p;
rsold=rsnew;
end

Inverse Mills Ratio in Matlab

I am trying to program in Matlab a conditional expectation of the form:
E[x|A<=x<=B] where X~N(u,s^2) (sorry, apparently the math editing here isn't what I am used to)
In Matlab, I have written up the following code:
Y=u+s*(normpdf(A,u,s)-normpdf(B,u,s))/(normcdf(B,u,s)-normcdf(A,u,s))
the problem is that it breaks down at higher values of A and B. For example, let u=0, s=1, A=10 and B=11. Simple logic says the answer should be between 10 and 11, but Matlab gives me back Inf because the denominator essentially becomes 0 while the numerator is 10^-23.
Any suggestions to make the formula give real numbers for all inputs?
One way is to do the numerical integration yourself:
x = linspace(A,B,1000);
trapz(x,x.*normpdf(x,u,s)) / trapz(x,normpdf(x,u,s))
With your example values, this gives 10.0981, and it is pretty fast

Suppress kinks in a plot matlab

I have a csv file which contains data like below:[1st row is header]
Element,State,Time
Water,Solid,1
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,6
Water,Solid,7
Water,Solid,8
Water,Solid,7
Water,Solid,6
Water,Solid,5
Water,Solid,4
Water,Solid,3
The similar pattern is repeated for State: "Solid" replaced with Liquid and Gas.
And moreover the Element "Water" can be replaced by some other element too.
Time as Integer's are in seconds (to simplify) but can be any real number.
Additionally there might by some comment line starting with # in between the file.
Problem Statement: I want to eliminate the first dip in Time values and smooth out using some quadratic or cubic or polynomial interpolation [please notice the first change from 5->2 --->8. I want to replace these numbers to intermediate values giving a gradual/smooth increase from 5--->8].
And I wish this to be done for all the combinations of Elements and States.
Is this possible through some sort of coding in Matlab etc ?
Any Pointers will be helpful !!
Thanks in advance :)
You can use the interp1 function for 1D-interpolation. The syntax is
yi = interp1(x,y,xi,method)
where x are your original coordinates, y are your original values, xi are the coordinates at which you want the values to be interpolated at and yi are the interpolated values. method can be 'spline' (cubic spline interpolation), 'pchip' (piece-wise Hermite), 'cubic' (cubic polynomial) and others (see the documentation for details).
You have alot of options here, it really depends on the nature of your data, but I would start of with a simple moving average (MA) filter (which replaces each data point with the average of the neighboring data points), and see were that takes me. It's easy to implement, and fine-tuning the MA-span a couple of times on some sample data is usually enough.
http://www.mathworks.se/help/curvefit/smoothing-data.html
I would not try to fit a polynomial to the entire data set unless I really needed to compress it, (but to do so you can use the polyfit function).