SICP Integral Procedure - scheme

In SICP section 3.5 the following procedure is given
(define (integral integrand initial-value dt)
(define int
(cons-stream
initial-value
(add-streams (scale-stream integrand dt)
int)))
int)
I understand how the procedure itself works but not how or why it finds the integral.

With some pseudocode mashup, it is
(integral ys z dt) = int
where
int =
[ z, ...[ dt * y + i | y <- ys
| i <- int ]
]
-- i.e. --
int[0] = z
int[k+1] = int[k] + ys[k]*dt
;; or,
(integral [y, ...ys] z dt) =
[z, ...(integral ys (z+y*dt) dt)]
(integral [] z dt) =
[]
which is a stream of partial sums following the definition of an integral, calculating an approximation of the area beneath the function's curve by the rectangle rule, under the assumption that the consecutive values of the function, ys, are taken at evenly spaced x values on the X axis at dt distances between them, i.e. we have
xs[k+1] - xs[k] = dt
ys[k] = foo(xs[k])
for the function foo(x), at any valid index k.
So we don't actually have the actual x coordinates, as we just assume they are evenly spaced in our representation of functions as streams of their y values.

Related

How can I speed up this haskell lastDigits x y function?

I have a haskell assignment in which i have to create a function lastDigit x y of 2 arguments that calculates the sum of all [x^x | (0..x)], mine is too slow and i need to speed it up. Anyone has any ideas??
list :: Integral x=>x->[x]
list 0 = []
list x = list(div x 10) ++ [(mod x 10)]
sqrall :: Integer->[Integer]
sqrall x y = [mod (mod x 10^y)^x 10^y | x <- [1..x]]
lastDigits :: Integer -> Int -> [Integer]
lastDigits x y = drop (length((list(sum (sqrall x y))))-y) (list(sum (sqrall x)))
The main reason this will take too long is because you calculate the entire number of x^x, which scales super exponentially. This means that even for very small x, it will still take a considerable amount of time.
The point is however that you do not need to calculate the entire number. Indeed, you can make use of the fact that x×y mod n = (x mod n) × (y mod n) mod n. For example Haskell's arithmoi package makes use of this [src]:
powMod :: (Integral a, Integral b) => a -> b -> a -> a
powMod x y m
| m <= 0 = error "powModInt: non-positive modulo"
| y < 0 = error "powModInt: negative exponent"
| otherwise = f (x `rem` m) y 1 `mod` m
where
f _ 0 acc = acc
f b e acc = f (b * b `rem` m) (e `quot` 2)
(if odd e then (b * acc `rem` m) else acc)
We can make a specific version for modulo 10 with:
pow10 :: Integral i => i -> i
pow10 x = go x x
where go 0 _ = 1
go i j | odd i = rec * j `mod` 10
| otherwise = rec
where rec = go (div i 2) ((j*j) `mod` 10)
This then matches x^x `mod` 10, except that we do not need to calculate the entire number:
Prelude> map pow10 [1 .. 20]
[1,4,7,6,5,6,3,6,9,0,1,6,3,6,5,6,7,4,9,0]
Prelude> [x^x `mod` 10 | x <- [1..20]]
[1,4,7,6,5,6,3,6,9,0,1,6,3,6,5,6,7,4,9,0]
Now that we have that, we can also calculate the the sum of the two last digits with integers that range to at most 18:
sum10 :: Int -> Int -> Int
sum10 x y = (x + y) `mod` 10
we thus can calculate the last digit with:
import Data.List(foldl')
lastdigit :: Int -> Int
lastdigit x = foldl' sum10 0 (map pow10 [0 .. x])
For example for x = 26, we get:
Prelude Data.List> lastdigit 26
4
Prelude Data.List> sum [ x^x | x <- [0 .. 26] ]
6246292385799360560872647730684286774
I keep it as an exercise to generalize the above to calculate it for the last y digits. As long as y is relatively small, this will be efficient, since then the numbers never take huge amounts of memory. Furthermore if the numbers have an upper bound, addition, multiplication, etc. are done in constant time. If you however use an Integer, then the numbers can be arbitrary large, and thus operations like addition are not constant.

Filtering with a predicate that takes 2 arguments

What I want would basically be a O(n^2) iteration over a list. Let's say I have a list of two integers,
let list = [2312, 8000, 3456, 7000, 1234]
and a function to check if adding two integers together would produce a result higher than 20000 (this could be an arbitrary function that takes two integers and returns a boolean).
myPredicate :: Int -> Int -> Bool
myPredicate x y = x + y > 10000
Is there a way to apply this predicate to the above list to get a list of lists that include valid pairs, like this:
>> filter myPredicate list
>> [[2312, 8000], [3456, 8000], [3456, 7000], [8000, 7000]]
If I understood you correctly you want to construct the list of pairs,
pairs xs = [(y,z) | (y:ys) <- tails xs, z <- ys]
and then filter it out using your predicate which needs to be in uncurried form,
myPredicate' :: (Int,Int) -> Bool
myPredicate' x y = x + y > 10000
so,
filter myPredicate' (pairs list)
or equivalently
filter (uncurry myPredicate) (pairs list)
This is supported by Haskell syntax directly.
[(x, y) | x <- myList, y <- myList, x + y > 20000]
This will return reversed and repeated pairs. If that's not what you need, consider these list comprehensions:
[(x, y) | x <- myList, y <- myList, x < y, x + y > 20000] -- no reversed pairs, no repeats
[(x, y) | x <- myList, y <- myList, x <= y, x + y > 20000] -- repeats, no reversed pairs
If for some reason unknown to science you have a list with duplicate elements, say [30000,30000] and you want only elements at different positions to form valid pairs, then this simple list comprehension won't work. I have no idea what kind of real life problem would require this, but here you are:
[(y,z) | (y:ys) <- tails xs, z <- ys, y + z > 20000]
(idea stolen from the other answer)

Most efficient algorithm to find integer points within an ellipse

I'm trying to find all the integer lattice points within various 3D ellipses.
I would like my program to take an integer N, and count all the lattice points within the ellipses of the form ax^2 + by^2 + cz^2 = n, where a,b,c are fixed integers and n is between 1 and N. This program should then return N tuples of the form (n, numlatticePointsWithinEllipse n).
I'm currently doing it by counting the points on the ellipses ax^2 + by^2 + cz^2 = m, for m between 0 and n inclusive, and then summing over m. I'm also only looking at x, y and z all positive initially, and then adding in the negatives by permuting their signs later.
Ideally, I'd like to reach numbers of N = 1,000,000+ within the scale of hours
Taking a specific example of x^2 + y^2 + 3z^2 = N, here's the Haskell code I'm currently using:
import System.Environment
isqrt :: Int -> Int
isqrt 0 = 0
isqrt 1 = 1
isqrt n = head $ dropWhile (\x -> x*x > n) $ iterate (\x -> (x + n `div` x) `div` 2) (n `div` 2)
latticePointsWithoutNegatives :: Int -> [[Int]]
latticePointsWithoutNegatives 0 = [[0,0,0]]
latticePointsWithoutNegatives n = [[x,y,z] | x<-[0.. isqrt n], y<- [0.. isqrt (n - x^2)], z<-[max 0 (isqrt ((n-x^2 -y^2) `div` 3))], x^2 +y^2 + z^2 ==n]
latticePoints :: Int -> [[Int]]
latticePoints n = [ zipWith (*) [x1,x2,x3] y | [x1,x2,x3] <- (latticePointsWithoutNegatives n), y <- [[a,b,c] | a <- (if x1 == 0 then [0] else [-1,1]), b<-(if x2 == 0 then [0] else [-1,1]), c<-(if x3 == 0 then [0] else [-1,1])]]
latticePointsUpTo :: Int -> Int
latticePointsUpTo n = sum [length (latticePoints x) | x<-[0..n]]
listResults :: Int -> [(Int, Int)]
listResults n = [(x, latticePointsUpTo x) | x<- [1..n]]
main = do
args <- getArgs
let cleanArgs = read (head args)
print (listResults cleanArgs)
I've compiled this with
ghc -O2 latticePointsTest
but using the PowerShell "Measure-Command" command, I get the following results:
Measure-Command{./latticePointsTest 10}
TotalMilliseconds : 12.0901
Measure-Command{./latticePointsTest 100}
TotalMilliseconds : 12.0901
Measure-Command{./latticePointsTest 1000}
TotalMilliseconds : 31120.4503
and going any more orders of magnitude up takes us onto the scale of days, rather than hours or minutes.
Is there anything fundamentally wrong with the algorithm I'm using? Is there any core reason why my code isn't scaling well? Any guidance will be greatly appreciated. I may also want to process the data between "latticePoints" and "latticePointsUpTo", so I can't just rely entirely on clever number theoretic counting techniques - I need the underlying tuples preserved.
Some things I would try:
isqrt is not efficient for the range of values you are working work. Simply use the floating point sqrt function:
isqrt = floor $ sqrt ((fromIntegral n) :: Double)
Alternatively, instead of computing integer square roots, use logic like this in your list comprehensions:
x <- takeWhile (\x -> x*x <= n) [0..],
y <- takeWhile (\y -> y*y <= n - x*x) [0..]
Also, I would use expressions like x*x instead of x^2.
Finally, why not compute the number of solutions with something like this:
sols a b c n =
length [ () | x <- takeWhile (\x -> a*x*x <= n) [0..]
, y <- takeWhile (\y -> a*x*x+b*y*y <= n) [0..]
, z <- takeWhile (\z -> a*x*x+b*y*y+c*z*z <= n) [0..]
]
This does not exactly compute the same answer that you want because it doesn't account for positive and negative solutions, but you could easily modify it to compute your answer. The idea is to use one list comprehension instead of iterating over various values of n and summing.
Finally, I think using floor and sqrt to compute the integral square root is completely safe in this case. This code verifies that the integer square root by sing sqrt of (x*x) == x for all x <= 3037000499:
testAll :: Int -> IO ()
testAll n =
print $ head [ (x,a) | x <- [n,n-1 .. 1], let a = floor $ sqrt (fromIntegral (x*x) :: Double), a /= x ]
main = testAll 3037000499
Note I am running this on a 64-bit GHC - otherwise just use Int64 instead of Int since Doubles are 64-bit in either case. Takes only a minute or so to verify.
This shows that taking the floor of sqrt y will never result in the wrong answer if y <= 3037000499^2.

Equality for two simple expressions with only bitwise operations

Given the following two functions in C language:
int f(int x, int y, int z) {
return (x & y) | ((~x) & z);
}
int g(int x, int y, int z) {
return z ^ (x & (y ^ z));
}
The results of the two functions are equal for any valid integer.
I just wonder the mathematics between the two expressions.
I've first seen the expression for function f in the SHA-1 algorithm on wikipedia.
http://en.wikipedia.org/wiki/Sha1
In the "SHA-1 pseudocode" part, inside the Main loop:
if 0 ≤ i ≤ 19 then
f = (b and c) or ((not b) and d)
k = 0x5A827999
...
In some open source implementation, it uses the form in function g: z ^ (x & (y ^ z)).
I write a program and iterate all the possible values for x, y, z, and all the results are equal.
How to deduce the form
(x & y) | ((~x) & z)
to the form
z ^ (x & (y ^ z))
in mathematics? Not just only proving the equality.
Since bitwise operations are equivalent to boolean operations on the individual bits, you can prove the equivalence simply by enumerating the eight assignments of the {x, y, z} three-tuples.
Fill out the truth tables for each of these two functions, and then compare the eight positions to each other. If all eight positions match, the two functions are equivalent; otherwise, the functions are different.
You do not need to do it manually either: plug in both functions in three nested loops that give x, y, and z values from zero to one, inclusive, and compare the results of invoking f(x,y,z) to g(x,y,z).
You can do this using a Karnaugh Map. Given the truth table for z ^ (x & (y ^ z)), the Karnaugh map is:
As can be seen, you can make two groups from the diagram, giving you (x & y) | (~x & z)

Haskell data type error PBMfile

i am doing my homework and have an error
I have to do a functions about a data type described now
data RGBdata= RGB Int Int Int
data PBMfile= PBM Int Int [[RGBdata]]
And his show functions
instance Show RGBdata where
show (RGB r g b) = (show r)++" "++(show g)++" "++(show b)
instance Show PBMfile where
show (PBM width height l) = "P3\n"++(show width)++" "++(show height)++"\n255\n"++(foldr (++) "" (map myshow l))
myshow [] = "\n"
myshow (h:t) = (show h)++" "++(myshow t)
And his load and apply function
cargarPBM name = readFile name >>= return . rLines . lines
rLines (_:x:_:xs)= (\[a,b]->(PBM (read a) (read b) (rLines' (read a) (concat $map words xs)))) $ words x
rLines' _ []= []
rLines' a x= (rLine (take (a*3) x): rLines' a (drop (a*3) x))
rLine []= []
rLine (r:g:b:xs)= ((RGB (read r) (read g) (read b)):rLine xs)
aplicar funcion origen destino= cargarPBM origen >>= writeFile destino . show . funcion
When i try to do a function, for example
negative :: PBMfile -> [Int]
negative PBM x y z = [1,2,3]
Hugs error
ERROR file:.\haha.hs:32 - Constructor "PBM" must have exactly 3 arguments in pattern
But PBM x y z are not 3 arguments? What am i doing wrong?
Your function definition negative PBM x y z is trying to pattern match against 4 arguments, the first of which is the PBM data constructor. To actually pattern match the data constructor and its arguments, you should be grouping them, i.e. negative (PBM x y z) = .... The show definition in your question is an example of doing it correctly.
For further reading, try http://en.wikibooks.org/wiki/Haskell/Pattern_matching#The_connection_with_constructors.
You need parentheses,
negative :: PBMfile -> [Int]
negative (PBM x y z) = [1,2,3]
otherwise it is parsed as four arguments to negative.

Resources