Solve the Laplace equation
Matlab, 84, 81.2 79.1 bytes = 113 - 30%
function u=l(f,N,a,b);A=toeplitz([2,-1,(3:N)*0]);A([1,2,end-[1,0]])=eye(2);u=[a,f((1:N-2)/N)*(N-1)^2,b]/A;plot(u)
Note that in this example the I use row vectors, this means that the matrix A
is transposed. f
is taken as a function handle, a,b
are the left/right side Dirichlet contraints.
function u=l(f,N,a,b);
A=toeplitz([2,-1,(3:N)*0]); % use the "toeplitz" builtin to generate the matrix
A([1,2,end-[1,0]])=eye(2); % adjust first and last column of matrix
u=[a,f((1:N-2)/N)*(N-1)^2,b]/A; % build right hand side (as row vector) and right mu
plot(u) % plot the solution
For the example f = 10*x, u_L = 0 u_R = 1, N = 15
this results in:
Mathematica, 52.5 bytes (= 75 * (1 - 30%))
+0.7 bytes per @flawr 's comment.
ListPlot[{#,u@#}&/@Subdivide@#4/.NDSolve[-u''@x==#&&u@0==#2&&u@1==#3,u,x]]&
This plots the output.
e.g.
ListPlot[ ... ]&[10 x, 0, 1, 15]
Explanation
NDSolve[-u''@x==#&&u@0==#2&&u@1==#3,u,x]
Solve for the function u
.
Subdivide@#4
Subdivide
the interval [0,1] into N (4th input) parts.
{#,u@#}&/@ ...
Map u
to the output of Subdivide
.
ListPlot[ ... ]
Plot the final result.
Non-graphing solution: 58 bytes
u/@Subdivide@#4/.NDSolve[-u''@x==#&&u@0==#2&&u@1==#3,u,x]&
R, 123.2 102.9 98.7 bytes (141-30%)
Edit: Saved a handful of bytes thanks to @Angs!
If someone wants to edit the pictures feel free to do so. This is basically an R adaptation of both the matlab and python versions posted.
function(f,a,b,N){n=N-1;x=1:N/n;A=toeplitz(c(2,-1,rep(0,N-2)));A[1,1:2]=1:0;A[N,n:N]=0:1;y=n^-2*sapply(x,f);y[1]=a;y[N]=b;plot(x,solve(A,y))}
Ungolfed & explained:
u=function(f,a,b,N){
n=N-1; # Alias for N-1
x=0:n/n; # Generate the x-axis
A=toeplitz(c(2,-1,rep(0,N-2))); # Generate the A-matrix
A[1,1:2]=1:0; # Replace first row--
A[N,n:N]=0:1; # Replace last row
y=n^-2*sapply(x,f) # Generate h^2*f(x)
y[1]=a;y[N]=b; # Replace first and last elements with uL(a) and uR(b)
plot(x,solve(A,y)) # Solve the matrix system A*x=y for x and plot against x
}
Example & test cases:
The named and ungolfed function can be called using:
u(function(x)-2,0,0,10)
u(function(x)x*10,0,1,15)
u(function(x)sin(2*pi*x),1,1,20)
u(function(x)x^2,0,0,30)
Note that the f
argument is an R-function.
To run the golfed version simply use (function(...){...})(args)