Haskell Assignment
A.First Edition
This is my first edition of assignment.
Very simple.
C.Further improvement
กก
กก
--Name: Qingzhe Huang --ID: 5037735 --Title: Comp348 Assignment 1 module A1 where -------------------------------------------------------------------------------------------------- --1 --I don't know what should I print out for an empty list except a "-1000" --to indicate an error. --first :: (Ord a, Num a) => a -> [a]] -> a first e (x:[]) = if abs x < e then x else (-1000) first e (x:y:s) = if abs (x-y) < e then x else first e (y:s) -------------------------------------------------------------------------------------------------- --2 --(f ((a+b)/2))*(f a)>0 means that the mmiddle points has same sign as f(a), --to do this check, we don't have to make aassumption that f(a)<0<f(b), --because f(a)>0>f(b) can also work --this utility function help reading -- half :: Fractional a => a -> a -&> a half a b = (a+b)/2 --I cannot use "real 0" to stop tthe recursive as "cos" function won't stop the infinite loop --even f(x) is as small as 1.0e-23. So, I aarbitrarily chose 1.0e-6 to indicate 0. -- bisect :: (Ord a, Fractional b, Fractiional a) => (b -> a) -> b -> b -> [b] bisect f a b = (half a b):( if abs (f (half a b))< (1.0e-6) then [] else if (((f (half a b))*(f a)) >0) then bisect f (half a b) b else if (((f (half a b))*(f a)) <0) then bisect f a (half a b) else []) -------------------------------------------------------------------------------------------------- --3 --I really don't agree with the use of firsst here. Because mathmatically speaking it is meaningless as --first only finds out the first consequtivve variables which difference is smaller than tolerance. --However, it should be the function value that matters, not the variables. {---We cannot use first here, and I have to use a self-defined function firstf --firstf f e (x:[]) = if abs (f x) < e tthen x else 1000 --firstf f e (x:y:s) = if abs (f x- f y)<t; e then x else firstf f e (y:s) --solve1 e f a b = firstf f e (bisect f a bb)-} --solve1 :: (Ord a, Fractional b, Fractionaal a, Ord b) => a -> (a -> b) -> a -> a -> a solve1 e f a b = first e (bisect f a b) -------------------------------------------------------------------------------------------------- --4 --this is straightforward! --diff :: Fractional a => (a -> a) -&> a -> a diff f x = (f (x+h) - f (x-h)) /2/h where h = 0.00001 -------------------------------------------------------------------------------------------------- --5 --I have to add extra condition to prevent "divide 0" error! --And what's more I need a small number to indicate it is zero now. --newt :: Fractional a => (a -> a) -&> a -> [a] newt f x = x:(if abs (f x) <1.0e-6||(diff f x==0) then [] else newt f (x-(f x)/(diff f x))) -------------------------------------------------------------------------------------------------- --6 --solve2 :: (Ord a, Fractional a) => a --> (a -> a) -> a -> b -> a solve2 e f a b = first e (newt f a) -------------------------------------------------------------------------------------------------- --7 --I use 0.0001 as tolerance. --solve :: (Ord a, Fractional a) => (a --> a) -> a -> a -> (a,a) solve f a b= (solve1 e f a b, solve2 e f a b) where e =0.0001 -------------------------------------------------------------------------------------------------- --8 --trape :: Fractional a => (a -> a) --> a -> a -> a trape f a b = (f a + f b)*(b-a)*0.5 --slope :: Fractional a => (a -> a) --> a -> a -> a slope f a b = (f b - f a)/(b-a) --integrate :: (Fractional a, Ord a) => (a -> a) -> a -> a -> a integrate f a b = if abs (slope f a (half a b) - slope f (half a b) b) <e then (trape f a (half a b))*2 else integrate f a (half a b) + integrate f (half a b) b where e =0.001 --integrate f a b = if abs ((trape f a (hallf a b)) - (trape f (half a b) b)) < e -- then (trape f a (half a b))*2 -- else integrate f a (half a b) + integraate f (half a b) b where e =0.001 -------------------------------------------------------------------------------------------------- --9 --union :: Eq a => [a] -> [a] -> [[a] union [] ys = ys union (x:xs) ys = x:union xs (filter (x/=) ys) --powerset :: Eq a => [a] -> [[a]] powerset [x] = [[], [x]] powerset (x:xs) = union (powerset xs) (map (x:) (powerset xs)) -------------------------------------------------------------------------------------------------- --10 --select :: (Eq a, Num b) => b -> [a]] -> [[a]] select n [] = [] select 1 s = map (\x->x:[]) s select n (x:xs) = union (map (x:) (select (n-1) xs)) (select n xs) ------------------------------------------------------------------------------------------------ --The test part: -------------------------------------------------------------------------------------------------- test1 = first 0.01 [0.9,0.99,0.999,0.9999] {- A1> test1 0.99 -} -------------------------------------------------------------------------------------------------- test2 = bisect sin 4 3 {- A1> test2 [3.5,3.25,3.125,3.1875,3.15625,3.14063,3.14844,3.14453,3.14258,3.1416,3.14111,3. 14136,3.14148,3.14154,3.14157,3.14159,3.14159,3.14159,3.14159] -} -------------------------------------------------------------------------------------------------- test3 = solve1 0.0001 sin 4 3 {- A1> test3 3.14148 -} -------------------------------------------------------------------------------------------------- test4 = diff sin 0 {- A1> test4 1.0 -} -------------------------------------------------------------------------------------------------- test5 = newt sin 2 {- A1> test5 [2.0,4.17935,2.48933,3.25214,3.14131,3.14159] -} -------------------------------------------------------------------------------------------------- test6 = solve2 0.001 sin 4 3 {- A1> test6 3.1416 -} -------------------------------------------------------------------------------------------------- test7 = solve sin 4 3 {- A1> test7 (3.14148,3.1416) -} -------------------------------------------------------------------------------------------------- test8 = integrate sin 0 pi {- A1> test8 2.0 -} -------------------------------------------------------------------------------------------------- test9 = powerset [1..4] {- A1> test9 [[],[4],[3],[3,4],[2],[2,4],[2,3],[2,3,4],[1],[1,4],[1,3],[1,3,4],[1,2],[1,2,4], [1,2,3],[1,2,3,4]] -} -------------------------------------------------------------------------------------------------- test10 = select 3 [1..5] {- A1> test10 [[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5],[2,3,4],[2,3,5],[2,4,5],[3,4,5] ] -} --------------------------------------------------------------------------------------------------