I am currently trying to make use functions to create:
0 V12 V13 V14
V21 0 V23 V24
V31 V32 0 V34
V41 V42 V43 0
A way that I found to do this was to use theses equations:
(2*V1 - 1)*(2*V2-1) = for spot V(1,2) in the Matrix
(2*V1 - 1)*(2*V3-1) = for spot V(1,3) in the Matrix
etc
Thus far I have:
let singleState state =
if state = 0.0 then 0.0
else
((2.0 *. state) -. 1.0);;
let rec matrixState v =
match v with
| [] -> []
| hd :: [] -> v
| hd :: (nx :: _ as tl) ->
singleState hd *. singleState nx :: matrixState tl;;
My results come out to be:
float list = [-3.; -3.; -3.; -1.]
When they should be a list of lists that look as follows:
0 -1 1 -1
-1 0 -1 1
1 -1 0 -1
-1 1 -1 0
So instead of it making list of lists it is making just one list. I also have trouble figuring out how to make the diagonals 0.
The signatures should look like:
val singleState : float list -> float list list = <fun>
val matrixState : float list list -> float list list = <fun>
and I am getting
val singleState : float -> float = <fun>
val matrixState : float list -> float list = <fun>
Any ideas?
With some fixing up, your function would make one row of the result. Then you could call it once for each row you need. A good way to do the repeated calling might be with List.map.
Assuming this is mostly a learning exercise, it might be good to first make a matrix like this:
V11 V12 V13 V14
V21 V22 V23 V24
V31 V32 V33 V34
V41 V42 V43 V44
I think this will be a lot easier to calculate.
Then you can replace the diagonal with zeroes. Here's some code that would replace the diagonal:
let replnth r n l =
List.mapi (fun i x -> if i = n then r else x) l
let zerorow row (n, res) =
(n - 1, replnth 0.0 n row :: res)
let zerodiag m =
let (_, res) = List.fold_right zerorow m (List.length m - 1, []) in
res
I would prefer to go with an array for your work.
A nice function to use is then Array.init, it works like so,
# Array.init 5 (fun x -> x);;
- : int array = [|0; 1; 2; 3; 4|]
We note that 5 play the role of the size of our Array.
But as you want a matrix we need to build an Array of Array which is achieve with two call of Array.init, the last one nested into the first one,
# Array.init 3 (fun row -> Array.init 3 (fun col -> row+col));;
- : int array array = [|[|0; 1; 2|]; [|1; 2; 3|]; [|2; 3; 4|]|]
Note, I've called my variable row and col to denote the fact that they correspond to the row index and column index of our matrix.
Last, as your formula use a vector of reference V holding value [|V1;V2;V3;V4|], we need to create one and incorporate call to it into our matrix builder, (The value hold on the cell n of an array tab is accessed like so tab.(n-1))
Which finally lead us to the working example,
let vect = [|1;2;3;4|]
let built_matrix =
Array.init 4 (fun row ->
Array.init 4 (fun col ->
if col=row then 0
else vect.(row)+vect.(col)))
Of course you'll have to adapt it to your convenience in order to match this piece of code according to your requirement.
A side note about syntax,
Repeating Array each time can be avoid using some nice feature of OCaml.
We can locally open a module like so,
let built_matrix =
let open Array in
init 4 (fun row ->
init 4 (fun col ->
if col=row then 0
else vect.(row)+vect.(col)))
Even shorter, let open Array in ... can be write as Array.(...), Below a chunk of code interpreted under the excellent utop to illustrate it (and I going to profit of this opportunity to incorporate a conversion of our matrix to a list of list.)
utop #
Array.(
to_list
## map to_list
## init 4 (fun r ->
init 4 (fun c ->
if r = c then 0
else vect.(r)+ vect.(c))))
;;
- : int list list = [[0; 3; 4; 5]; [3; 0; 5; 6]; [4; 5; 0; 7]; [5; 6; 7; 0]]
I hope it helps
Related
Currently i'm trying
I have a function to calculate the inverse sum of a number
let inverseSum n =
let rec sI n acc =
match n with
| 1 -> acc
| _ -> sI (n - 1) ((1.0 /. float n) +. acc)
in sI n 1.0;;
For example, inverseSum 2 -> 1/2 + 1 = 3/2 = 1.5
I try to test the function with 2 and 5, it's okay:
inverseSum 2;;
inverseSum 5;;
inverseSum 2;;
- : float = 1.5
inverseSum 5;;
- : float = 2.28333333333333321
For the moment, no problem.
After that, I initialize a list which contains all numbers between 1 and 10000 ([1;…;10000])
let initList = List.init 10000 (fun n -> n + 1);;
no problem.
I code a function so that an element of the list becomes the inverse sum of the element
(e.g. [1;2;3] -> [inverseSum 1; inverseSum 2; inverseSum 3])
let rec invSumLst lst =
match lst with
| [] -> []
| h::t -> (inverseSum h) :: invSumLst t;;
and I use it on the list initList:
let invInit = invSumLst initList;;
So far so good, but I start to have doubts from this stage:
I select the elements of invList strictly inferior to 5.0
let listLess5 = List.filter (fun n -> n < 5.0) invInit;;
And I realize the sum of these elements using fold_left:
let foldLess5 = List.fold_left (+.) 0.0 listLess5;;
I redo the last two steps with floats greater than or equal to 5.0
let moreEg5 = List.filter (fun n -> n >= 5.0) invInit;;
let foldMore5 = List.fold_left (+.) 0.0 moreEg5;;
Finally, I sum all the numbers of the list:
let foldInvInit = List.fold_left (+.) 0.0 invInit;;
but at the end when I try to calculate the absolute error between the numbers less than 5, those greater than 5 and all the elements of the list, the result is surprising:
Float.abs ((foldLess5 +. foldMore5) -. foldInvInit);;
Printf.printf "%f\n" (Float.abs ((foldLess5 +. foldMore5) -. foldInvInit));;
Printf.printf "%b\n" ((foldLess5+.foldMore5) = foldInvInit);;
returns:
let foldMore5 = List.fold_left (+.) 0.0 moreEg5;;
val foldMore5 : float = 87553.6762998474733
let foldInvInit = List.fold_left (+.) 0.0 invInit;;
val foldInvInit : float = 87885.8479664799379
Float.abs ((foldLess5 +. foldMore5) -. foldInvInit);;
- : float = 1.45519152283668518e-11
Printf.printf "%f\n" (Float.abs ((foldLess5 +. foldMore5) -. foldInvInit));;
0.000000
- : unit = ()
Printf.printf "%b\n" ((foldLess5+.foldMore5) = foldInvInit);;
false
- : unit = ()
it's probably a rounding problem, but I would like to know where exactly the error comes from?
Because here I am using an interpreter, so I see the error "1.45519152283668518e-11"
But if I used a compiler like ocamlpro, I would just get 0.000000 and false on the terminal and I wouldn't understand anything.
So I would just like to know if the problem comes from one of the functions of the code, or from a rounding made by the Printf.printf function which wrote the result with a "non scientific" notation.
OCaml is showing you the actual results of the operations you performed. The difference between the two sums is caused by the finite precision of floating values.
When adding up a list of large-ish numbers, by the time you reach the end of the list the number is large enough that the lowest-order bits of the new values simply can't be represented. But when adding a list of small-ish numbers, fewer bits are lost.
A system that shows foldLess5 +. foldMore5 as equal to foldInvInit is most likely lying to you for your convenience.
I've got a function that needs to work out the minimum change required to break down a certain amount of money.
A user would enter a value of money and the possible denominations, and it would output how many of each denomination would be needed to make up the money eg.
> coinChange 34 [1, 5, 10, 25, 50, 100]
[4,1,0,1,0,0]
Here is what I have so far:
coinChange :: Integer -> [Integer] -> [Integer]
coinChange _ [] = []
coinChange 0 xs = []
coinChange v xs = do
dropWhile (>v) (reverse xs)
createNewList :: Integer -> [Integer]
createNewList 0 = []
createNewList x = 0 : createNewList (x - 1)
I have a separate function called createNewList which I want to call to set up a new list of 0s at the beginning.
However, because I plan on making coinChange a recursive function when working out how much money is left, if I just call makeNewList in coinChange, at the moment it would reset the list because it would be called every recursion.
So my question is, is there a way to make a function call another function only once, before proceeding with the recursion.
Hope I've made it clear, thanks
In general you are allowed to create local helper functions in Haskell. Maybe this example will inspire you:
prepareData x = if x < 0 then -x else x
mainFunction n =
let recursiveLocalFunction x =
if x < 2 then 1 else x * recursiveLocalFunction (x - 1)
in recursiveLocalFunction (prepareData n)
I need to write a function in OCaml that adds elements of two lists in two different recursions: simple and tail. I made one with simple:
let rec add1 a b =
match (a, b) with
([], []) -> []
| (head1::tail1, []) -> head1 :: add1 tail1 []
| ([], head2::tail2) -> head2 :: add1 [] tail2
| (head1::tail1, head2::tail2) -> head1 + head2 :: add1 tail1 tail2
;;
It works like this:
add1 [1;2;3] [4;5;6;7];;
This return:
int list = [5; 7; 9; 7]
[1+4; 2+5; 3+6; 0+7] : 0 is added to 7 because there are no element on such position in first list.
So, my question is:
How can I make it with tail recursion?
The way to make this tail recursive is to build the result backwards and pass it along in the recursion and reverse it at the end.
let add1 a b =
let rec loop acc = function
| (xs, [])
| ([], xs) -> List.rev_append acc xs
| (x::xs, y::ys) -> loop ((x + y)::acc) (xs, ys)
in
loop [] (a, b)
Note: If one list is longer then the other then you don't need to add 0 to each element. The tail is already the result. So I use List.rev_append to reverse the accumulated values and append the remaining tail in one go.
Note2: List.rev_append can also append the empty list so no match for ([], []) is needed.
Tail recursion consists in having recursive function that simply performs a call to themselves without any other operations.
The following factorial is not tail recursive, because the last statement does not perform a simple call to fact but require a multiplcation :
let rec fact n =
if n = 0 then 1
else n*(fact (n-1))
By using an accumulator you can make this function tail recursive, the last statement performs a call to fact and therefore can be compiled using a jump and not a call :
let rec fact n r =
if n = 0 then r
else fact (n-1) (r*n)
And the usage :
fact 5 1
For you list addition, you can proceed the same way if the 2 lists have the same length at least.
I am learning haskell and i want to print all nodes in tree (depends on height on tree, where height = 0 => leafs). And i thinking, that I create a good function, but i have a problem with show function.
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)
tree4 = Node 1 (Node 2 Empty (Node 0 Empty Empty)) (Node 4 Empty Empty)
tree5 = Empty
heightTree::Tree a -> Integer
heightTree Empty = 0
heightTree (Node x l r) = 1 + max (heightTree l ) (heightTree r)
treeLev::Tree a -> Integer -> [a]
treeLev Empty a = []
treeLev (Node x l r ) a = if a == heightTree l || a == heightTree r then [x] else treeLev l (a-1) ++ treeLev r (a-1)
and when I'm using
*Main> treeLev tree4
<interactive>:105:1:
No instance for (Show (Integer -> [Integer]))
arising from a use of `print'
Possible fix:
add an instance declaration for (Show (Integer -> [Integer]))
In a stmt of an interactive GHCi command: print it
*Main>
Can anyone explain what I'm doing wrong :)?
The error message you give isn't telling you that you can't print the tree, it is telling you that you are trying to print out a function, and it can't do that.
You didn't show us the line with the show or print, so we can't see how to fix it, but that is what the message tell me.
I'm a little stuck on this assignment for OCAML. I'm trying to pass in a function and a value as a parameter into another function. For example, I have function called test that takes in (fun x -> x+x) and 3 as parameters. The function test should output 6, since 3 + 3 = 6. I know I can achieve something similar this by completing:
let func x = x + x;;
let a = func;;
let test a x = (a x);;
This way when I input, test a 5, I will get 10.
But when I change the statement to this, I get only the value I placed in for x. How do I get the (fun a -> a) to take in the value x?
let test a x = ((fun a -> a) x);;
fun a -> a is an anonymous identity function, it will always return its parameter. You could say:
let id = fun a -> a;;
id 3;;
=> 3
id (fun x -> x + x);;
=> (fun x -> x + x)
Note that in your
let test a x = ((fun a -> a) x);;
the first a and the other two as are different variables. The first one is never used again later. You can rewrite this line for easier understanding as:
let test a x = ((fun b -> b) x);;
How do I get the (fun a -> a) to take in the value x?
You are, and that's the problem. You're feeding your x to an identity function, and getting x back. What you want to do is feed the x to your a function, and that's what you did in your first attempt:
let func x = x + x;;
let test a x = a x;;
test func 3;;
=> 6
With functional languages in simple cases it is often helpful to write the expression in a form similar to lambda calculus and do the reductions manually (noting which reductions you are using). You can still use OCaml syntax as a simplified version of lambda calculus
So in the case of your example this would become:
let test a x = ((fun a -> a ) x);;
=> let test a x = ((fun b -> b ) x);; (* Variable renamed (alpha equivalence) *)
=> let test a y = ((fun b -> b ) y);; (* Variable renamed (alpha equivalence) *)
let func x = x + x;;
Note that these steps only serve to make sure, that we will later on have no variables with the same name, referring to different values. These steps can be left out, but I personally like working with unique variables much better.
test func 5
=> test (fun x -> x + x) 5 (* Variable func inserted (beta reduction) *)
=> (fun a y -> ((fun b -> b) y) (fun x -> x + x) 5 (* Variable test inserted *)
=> (fun y -> (fun b -> b) y) 5 (* Variable a inserted *)
=> ((fun b -> b) 5 (* Variable y inserted *)
=> 5 (* Variable b inserted *)
The final result is 5. Attempting this at first will seem very unusual and hard, but get's easier very fast. If you do something like this a couple of time you will get much better at understanding common functional patterns and reasoning about your program structure.
Have a look at this article for more examples on this.
Also note, that with a little more effort, this works backward as well. Although this usually is not as helpful as doing it in the same direction as the compiler.