-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[mmzk] (feat) Incorporate Year 2024 solution
- Loading branch information
Showing
10 changed files
with
641 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
packages: | ||
. | ||
src/Year2024/ | ||
tests: True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -78,6 +78,7 @@ test-suite test | |
build-depends: | ||
base, | ||
containers, | ||
hft, | ||
mtl, | ||
text, | ||
transformers, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
cabal-version: 3.0 | ||
-- WARNING: YOU MUST NOT UNDER ANY CIRCUMSTANCES EDIT THIS FILE, YOU HAVE BEEN WARNED | ||
name: hft | ||
version: 0.1.0.0 | ||
synopsis: Haskell Final Test 23/24 | ||
author: Imperial College London | ||
maintainer: [email protected] | ||
build-type: Simple | ||
|
||
library | ||
exposed-modules: Int, Types, Utilities, Examples | ||
hs-source-dirs: src | ||
default-language: Haskell2010 | ||
build-depends: base >=4.13 && <5, | ||
containers | ||
|
||
test-suite hft-test | ||
type: exitcode-stdio-1.0 | ||
hs-source-dirs: test | ||
default-language: Haskell2010 | ||
other-modules: IC.TestSuite | ||
main-is: Tests.hs | ||
ghc-options: -threaded | ||
build-depends: hft, | ||
base >=4.13 && <5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
module Examples where | ||
|
||
import Types | ||
import Data.Ratio ((%)) | ||
|
||
p1, p2, p3, p4, p5 :: Polynomial | ||
p1 = [(5,0)] | ||
p2 = [(1,1)] | ||
p3 = [(2,2),(-3,1),(1,0)] | ||
p4 = [(4,1),(-3,0)] | ||
p5 = [(2,3),(-2,1),(2,0)] | ||
|
||
x :: Expr | ||
x = P [(1,1)] | ||
|
||
-- Basic polynomials | ||
e1, e2, e3, e4, e5 :: Expr | ||
e1 = P p1 | ||
e2 = P p2 | ||
e3 = P p3 | ||
e4 = P p4 | ||
e5 = P p5 | ||
|
||
-- Addition of polynomials | ||
e6 :: Expr | ||
e6 = Add e3 e5 | ||
|
||
-- Multiplication by constant | ||
e7 :: Expr | ||
e7 = Mul e1 e6 | ||
|
||
-- Simple functions of x | ||
e8, e9 :: Expr | ||
e8 = Log e2 | ||
e9 = Pow e2 (-1) | ||
|
||
-- Inverse chain rule, id | ||
e10, e11 :: Expr | ||
e10 = Mul e4 e3 | ||
e11 = Mul (Pow x (-1)) (Log x) | ||
|
||
-- Inverse chain rule, others | ||
e12, e13 :: Expr | ||
e12 = Mul e4 (Log e3) | ||
e13 = Mul (Pow e3 (3/2)) e4 | ||
|
||
-- Now with a constant factor | ||
e14, e15 :: Expr | ||
e14 = Mul e4 (Pow (Mul e1 e3) (3/2)) | ||
e15 = Mul (P [(1,2), (-1,0)]) (Log (P [(1,3), (-3,1)])) | ||
|
||
-- No integral to be found | ||
e16 :: Expr | ||
e16 = Mul (Log e3) (Pow e4 (1/2)) | ||
|
||
-- Secret testing... | ||
e17, e18, e19, e20, e21, e22 :: Expr | ||
e17 = | ||
Mul (P [(4 % 5,1),((-3) % 5,0)]) (Pow (Mul (P [(5 % 1,0)]) (P [(2 % 1,2),((-3) % 1,1),(1 % 1,0)])) (3 % 2)) | ||
e18 = | ||
Mul (P [(1 % 5,2),((-1) % 5,0)]) (Log (P [(1 % 1,3),((-3) % 1,1)])) | ||
-- d/dx has factor of 3 => multiply by 1/3 | ||
e19 = P [(1,2), (-1,0)] | ||
e20 = P [(1,3), (-3,1)] | ||
e21 = Mul e19 (Log e20) | ||
|
||
-- As above but making 5/3 | ||
e22 = Mul (Mul e1 e19) (Log e20) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
{-# LANGUAGE NegativeLiterals #-} | ||
{-# LANGUAGE ViewPatterns #-} | ||
|
||
module Int where | ||
|
||
import GHC.Real | ||
import Data.List | ||
import Data.Maybe | ||
import Control.Applicative | ||
|
||
import Types | ||
import Utilities | ||
import Examples | ||
|
||
import Data.Bifunctor | ||
|
||
-- | ||
-- Universal assumptions/preconditions: | ||
-- 1. All polynomials are in standard form with decreasing | ||
-- powers of x | ||
-- 2. 0 is represented by P [(0, 0)]; P [] is undefined for | ||
-- the purposes of the exercise. | ||
-- 3. All constants will be polynomials of the form | ||
-- [(c, 0)], e.g. logarithms of constants and constant | ||
-- powers will not appear. | ||
-- 4. All computed integrals omit the constant of integration. | ||
-- | ||
|
||
------------------------------------------------- | ||
-- Part I (13 marks) | ||
|
||
addP :: Polynomial -> Polynomial -> Polynomial | ||
addP p1@((c1,e1):r1) p2@((c2,e2):r2) | ||
| e1 > e2 = (c1, e1) : addP r1 p2 | ||
| e1 < e2 = (c2, e2) : addP p1 r2 | ||
| otherwise = (c1 + c2, e1) : addP r1 r2 | ||
addP p1 p2 = p1 ++ p2 -- one of them is empty | ||
|
||
mulP :: Polynomial -> Polynomial -> Polynomial | ||
mulP p = sumP . map (\(c,e) -> map (bimap (c *) (e +)) p) | ||
|
||
sumP :: [Polynomial] -> Polynomial | ||
sumP = foldl' addP [(0, 0)] | ||
|
||
prodP :: [Polynomial] -> Polynomial | ||
prodP = foldl' mulP [(1, 0)] | ||
|
||
diffT :: Term -> Term | ||
diffT (c, 0) = (0, 0) | ||
diffT (c, e) = (c * (e % 1), e - 1) | ||
|
||
-- > The speç should specify the constant term to be zero! | ||
intT :: Term -> Term | ||
intT (0, 0) = (0, 0) | ||
intT (c, e) = (c / (e % 1 + 1), e + 1) | ||
|
||
diffP :: Polynomial -> Polynomial | ||
diffP = map diffT | ||
|
||
intP :: Polynomial -> Polynomial | ||
intP = map intT | ||
|
||
------------------------------------------------- | ||
-- Part II (7 marks) | ||
|
||
diffE :: Expr -> Expr | ||
diffE (P p) = P $ diffP p | ||
diffE (Add e1 e2) = Add (diffE e1) (diffE e2) | ||
diffE (Mul e1 e2) = Add (Mul (diffE e1) e2) (Mul e1 (diffE e2)) | ||
diffE (Pow e n) = Mul (Mul (P [(n, 0)]) (Pow e (n - 1))) (diffE e) | ||
diffE (Log e) = Mul (Pow e (-1)) (diffE e) | ||
|
||
-- | ||
-- Given | ||
-- | ||
toExpr :: Rational -> Expr | ||
toExpr n = P [(n, 0)] | ||
|
||
isConstant :: Expr -> Bool | ||
isConstant (P [(_, 0)]) = True | ||
isConstant _ = False | ||
|
||
simplifiedDiff :: Expr -> Expr | ||
simplifiedDiff = simplify . diffE | ||
|
||
printDiff :: Expr -> IO () | ||
printDiff = prettyPrint . simplifiedDiff | ||
|
||
------------------------------------------------- | ||
-- Part III (10 marks) | ||
|
||
intE :: Expr -> Maybe Expr | ||
intE (P p) = Just $ P (intP p) | ||
intE (Add e1 e2) = Add <$> intE e1 <*> intE e2 | ||
intE (Mul e1 e2) | ||
| isConstant e1 = Mul e1 <$> intE e2 | ||
| isConstant e2 = Mul e2 <$> intE e1 | ||
| otherwise = applyICR e1 e2 <|> applyICR e2 e1 | ||
intE e = applyICR e (toExpr 1) | ||
|
||
applyICR :: Expr -> Expr -> Maybe Expr | ||
applyICR fg g' = case factorise g' (diffE fg) of | ||
Just coeff -> Just $ Mul (toExpr $ coeff / 2) (Pow fg 2) | ||
Nothing -> case fg of | ||
Pow g n -> do | ||
coeff <- factorise g' (diffE g) | ||
pure $ case n of | ||
-1 -> Mul (toExpr coeff) (Log g) | ||
_ -> Mul (toExpr $ coeff / (n + 1)) (Pow g (n + 1)) | ||
Log g -> do | ||
coeff <- factorise g' (diffE g) | ||
pure $ Mul (toExpr coeff) (Mul g (Add (Log g) (toExpr -1))) | ||
_ -> Nothing | ||
where | ||
splitByCoeff (simplify -> e) = case e of | ||
P [(c, 0)] -> (c, toExpr 1) | ||
Mul (P [(c, 0)]) e' -> (c, e') | ||
_ -> (1, e) | ||
factorise (splitByCoeff -> (c1, r1)) (splitByCoeff -> (c2, r2)) | ||
| r1 == r2 = Just $ c1 / c2 | ||
| otherwise = Nothing | ||
|
||
-- | ||
-- Given... | ||
-- | ||
simplifiedInt :: Expr -> Maybe Expr | ||
simplifiedInt = fmap simplify . intE | ||
|
||
printInt :: Expr -> IO () | ||
printInt e = maybe (putStrLn "Fail") prettyPrint (simplifiedInt e) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module Types where | ||
|
||
-- WARNING: DO NOT EDIT THIS FILE FOR *ANY* REASON, ANY CHANGES WILL BE DISCARDED | ||
-- YOU WILL BE PENALISED IF YOU CODE NO LONGER COMPILES. | ||
|
||
type Coefficient = Rational | ||
type Exponent = Integer | ||
type Term = (Coefficient, Exponent) | ||
type Polynomial = [Term] | ||
data Expr = P Polynomial | ||
| Add Expr Expr | ||
| Mul Expr Expr | ||
| Pow Expr Rational | ||
| Log Expr | ||
deriving (Eq, Ord, Show) |
Oops, something went wrong.