KnowledgeHub
Questions
Tags
Users
Search
Alex Rivera
|
Logout
Edit Question
Title
Body
I am new to functional programming, and now learn Haskell. As an exercise I decided to implement the explicit Euler method for 1D linear diffusion equation. While the code below works correctly, I am not happy about its performance. In fact, I am concerned with memory consumption. I believe that it is related to lazy evaluation, but cannot figure out how I can reduce its memory usage. The idea of the algorithm is really simple, to make it clear in imperative terms: it takes an `array', and to every inner point it adds a value, which is calculated as a combination of the values in the point itself and in its neighbors. Boundary points are special cases. So, this is my Euler1D.hs module: module Euler1D ( stepEuler , makeu0 ) where -- impose zero flux condition zeroflux :: (Floating a) => a -> [a] -> [a] zeroflux mu (boundary:inner:xs) = [boundary+mu*2*(inner-boundary)] -- one step of integration stepEuler :: (Floating a) => a -> [a] -> [a] stepEuler mu u@(x:xs) = (applyBC . (diffused mu)) u where diffused mu (left:x:[]) = [] -- ignore outer points diffused mu (left:x:right:xs) = -- integrate inner points (x+mu*(left+right-2*x)) : diffused mu (x:right:xs) applyBC inner = (lbc u') ++ inner ++ (rbc u') -- boundary conditions where u' = [head u] ++ inner ++ [last u] lbc = zeroflux mu -- left boundary rbc = (zeroflux mu) . reverse -- right boundary -- initial condition makeu0 :: Int -> [Double] makeu0 n = [ ((^2) . sin . (pi*) . xi) x | x <- [0..n]] where xi x = fromIntegral x / fromIntegral n And a simple Main.hs: module Main where import System ( getArgs ) import Euler1D main = do args <- getArgs let n = read $ head args :: Int let u0 = makeu0 n let un = stepEuler 0.5 u0 putStrLn $ show $ sum un Fo
Tags (comma-separated)
Save Edits
Cancel