Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
Haskell for Computational Quantum Chemistry
Felipe Zapata
Group of Reactivity and Molecular StructureSeptember 12, 2012
Why on galaxy people use Fortran?
“FORTRAN was the language of choice for the same reason that three-legged races are popular”. Ken Thompson, 1983 Turing Award Lecture.
• Since Fortran has been in use for more than fifty years, there is a vast body of Fortran in daily use throughout the scientific and engineering communities.
If you ask in an academic environment about Fortran is highly probable that you get that...
Buddha Says...“Do not believe in anything simply because you have
heard it. Do not believe in anything simply because
it is spoken and rumoured by many. Do not believe in
anything simply because it is found written in your
religious books. Do not believe in anything merely
on the authority of your teachers and elders. Do not
believe in traditions because they have been handed
down for many generations. But after observation and
analysis, when you find that anything agrees with
reason and is conducive to the good and benefit of
one and all, then accept it and live up to it.”
WhyFunctional Programming
Matters● “As software becomes more and more complex, it is more and more important to structure it well. Well-structured software is easy to write and to debug, and provides a collection of modules that can be reused to reduce future programming costs”
John Hughes
Then, Why Haskell?
The bloody-hands programmer answer
● Haskell is capable of anything, with enough skill. It is very fast (properly optimized).
● Programming at a high level of abstraction should diminish the amount of opportunities you have to introduce bugs.
● Haskell is most likely quite different from any language you've ever used before.
My answer
From my perspective humankind do not create only because it can, we create because through our creations we discover the deepest nature of our being. And those complex data structures that we program reflect the complexity of our nature, being Haskell and adequate tool for materialized our thoughts.
-> Hack your own brainλ
Why bothering about abstract data structure?
Computer Science is about computers only as far as
Cosmological Science is about telescopes.
Edsger W. Dijkstra, Turin award 1971
Immutable Variables
In Haskell, a variable is a name for some valid expression. The word "variable" as applied to Haskell variables is misleading, since a given variable's value never varies during a program's runtime.
A little about the types
Types are the abstract representation of the data that we operate with in the computer
Haskell is smart enough that it can infer the types, but on the contrary of Fortran the “Static Type Declaration” in Haskell is for helping the programmer
3 :: Int 3.1415 :: Double'h' :: Char True :: Bool
Some common operators
and some specific ones like : (rem), (div)
> 5 `div` 4 = (div) 5 4 = 1
> 11 `rem` 3 = (rem) 11 3 = 2
Like most of the language used in Computational Chemistry, Haskell include the basis operators:
(+) ,(-),(*), (^),(**) (/)
> 3+ 4 = 7
> 2.0 ** 1.5 = 2.8284
List and Tuples“Lists are the bread and butter of Haskell collections” Real World Haskell.
[1,2,3,4,5] :: [Int]
“Hi quantum world” :: [char] ≡ String
[True,False,True] :: [Bool]
[1.23,-32.1,1.0/23.1] :: [Double]
(6.62606e-34,”Planck's Const” ::(Double,String)
([1,2,3,5,7,11,13,17],True) :: ([Double],Bool)
(18,”Agua”, “H2O”) :: (Int,String,String)
The fun of functions!!
plus x y = x + y
inv x = recip x
power x y = x ** y
plus x y = x + y = (\x y x + y)→
inv x = recip x = (\x recip x)→
power x y = x ** y = (\x y x ** y)→
Prelude has a big amount of functions, very common functions are there for free!!
Lambda Abstraction
Polymorphism
mmmmm and these other types:
>(/) :: Fractional a => a -> a -> a
>(^) :: (Integral b, Num a) => a -> b -> a
Let's take a look at the type of the previous functions
> (+) :: Num a => a -> a -> a
> (**) :: Floating a => a -> a -> a
It we suppose that those “a” are dummy variables and can represent any values, then those “Num a =>” restrict the kind of values that the “a” can represent
What is Polymorphism use for ?Let's assume that we defined the (+) operador as :
(+) :: Int → Int → int
So far so good, but what if we need to defined the sum over the reals?, we need to defined something like:
(sumDouble) :: Double → Double → Double
So we have to defined a function for every kind of type over we want to operate
TypeClasses
We have met the Num class, where inhabit the floating point representation, integrals of arbitrary precision and some exotic fauna.
● Our previous definition of the (+) operator show us the necessity of defining typeclasses.
● Typeclasses allow some function to behave accordingly to the type over which they are operating.Let's have a Tour for the principal typeclasses in Haskell.
TypeClasses
● The Class show contained those type that can be converted to string and are suitable for printing.
print :: Show a => a → IO ()
● The Class Read, complementary to Show, defines functions for transforming a string to a type member of the Read Class.
read :: Read a => String → a
TypeClasses
● The Ord Class include those types that cansorted.Sort :: Ord a => [a] -> [a]
● The Eq Class contained those types that can be examined for equality.(==) :: Eq a => a -> a -> Bool
Operations over Lists: play with the structures and let alone the
individual data
What if we have a list of data and we want to operate a function over the data?
Give an opportunity to the map function
map :: (a -> b) -> [a] -> [b]
> map sin [pi,0.5*pi,2.0*pi]
And what if we only want some values that fulfil some condition?
filter :: (a -> Bool) -> [a] -> [a]
> filter (\x x `div`2) [1..100]→
Let's talk about Recursion
In Haskell there is not such a thing like “For Loops” then how do we represent then?
Mathematical induction can help us to prove the True of a statement P, for an infinite sequence of cases. We proceed as follow :
1. basis. Prove that 0 has the property P.
2. Induction step. Assume the induction hypotheses is that n has the property P. Prove on the basis of this that n+1 has property P.
∀n ∈ ℕ: P(n)
Recursion in Haskell
We can defined a loop as follow:Basis Case loop :: Double [→ Double] → Doubleloop acc [ ] = acc
Induction steploop :: Double [→ Double] → Doubleloop acc (x:xs) = loop (acc + x) xs
Folds family
Probably when you need to recourse over some data structure, Haskell has a library function that will do it for you, like the beloved folds.
The Fold left function has the following type
foldl :: (a -> b -> a) -> a -> [b] -> a
Let's explore it !!
We can defined the function sum as
Sum xs = foldl (+) 0 xs
But how does it work?
Fold
Basis case
foldl (+) acc [] = acc
Induction step
Foldl (+) 0 (x1:xs) =
(0 + x1) + fold (+) x1 (x2:xs')
= (((0+ x1) +x2) + fold (+) (x1+x2) (x3:xs''))
... ...
= ((((0 +x1) + x2 ) +x3 ).. + xi ..) + xn)
Some remarks
● Haskell do not coerce types, it means that expressions such as 3 + 2.14 are ill typed.
● The lists must contained elements of the same type, there is no such a thing like [12,”boom”].
● Even though Lambda abstraction are very useful in some abstractions most of the time is a better idea to give a meaningfully name to a function.
● At the contrary of Python tuples and list are not interchangeable data structures.
Curryfication
Let f and g be functions of x then the composition of this two functions can be denoted as
f º g(x) == f (g (x))
We can translate this functional denotation in haskell as follows
f x = recip x
g x = sqrt x
(f . g) x == f ( g x)
And what about this one? (5*). (rem 4) $ 3
Curryfication
rem :: Int Int Int→ →Rem 4 :: Int Int→rem 4 3 :: Int
$ has the same meaning that a parenthesis then sqrt $ recip 3.0 == sqrt (recip 3.0)
(*) :: Int Int Int→ →(5*) :: Int Int→(5*1) :: Int
(*5) . (rem 4) :: Int Int→(*5) . (rem 4) $ 2 :: Int
The meaning of function in Haskell is the mathematical one, given the same input a function will always return the same output.
But if all the expressions in Haskell are functions how could we interact with operations and effects with the real world?
If a function lives in the pure world how can I inject the input in the functions?
Let set aside the pure ones from the impure
IO Monad to the Rescue!!!!
IO Monad
If the functions live in the pure world, we can bring them to a “secure zone” where we can “bind” a value to the function.We denote this zone where interaction with the external world is allowed the IO Monad.
f :: [Double] [→ Double]f xs = map ((^2). sin) xs
main :: IO ()main = let ys = f [pi,2.0*pi,-pi,0.5*pi] print ys
Keep in your mind !!
● Before you type something you must have a plan.
● The Static type system protects you against meaningless expressions but could be a nightmare if you do not have the structure of the program in your head.
● Haskell is not only a tool for structuring complex data and operations, it is also a path for acquiring abstraction skills.
Beware Fortranians !!
Welcome to the Haskell Ab Initio Quantum Project
Ĥaskell >>= Ψ λ → εΨ