Using nested functions - functional-programming

I have problem:
Write a function called minimum6 that takes 6 arguments and returns the smallest one.
Example: minimum6 10 20 30 40 50 60 = 10
and this is what i got so far:
let min a b = if a < b then a else b;;
let minimum6 x1 x2 x3 x4 x5 x6 = min (min (min (min (min x1 x2) x3) x4) x5) x6);;
however, i get 'This expression has type int but an expression was expected of type 'a -> 'b' pointing to the first '10'
I'm new to the language, what did i do wrong? was it because i used a function in a function?

You have some parentheses problems. :)
You could also do something more general. Something like:
let rec list_min min = function
| [] -> min
| x::xs -> if x < min then list_min x xs else list_min min xs
let min6 x1 .. x6 = list_min x1 [x2; ...; x6]

Related

Constraint propagation using Projection rule

I've found this example of constraint propagation using projection rule
We have
C = { x1 ≠ x2, x1 ≥ x2 }
< C; x1 ∈ {1,2,3}, x2 ∈ {1,2,3} >
They say that applying propagation rule, does not give any simplification.
I'm not sure why this is the case. Shouldn't we get?
< C; x1 ∈ {2,3}, x2 ∈ {1,2} >
Other steps in the example, make sense that to me, e.g.
< C; x1 ∈ {2}, x2 ∈ {1,2,3} >
produces
< C; x1 ∈ {2}, x2 ∈ {1} >
Note that the constraint in your example is x1 >= x2, and not x1 > x2.
Given that the iniital domains are {1,2,3} for both variables, neither x1 >= x2 nor x1 != x2 can be used to draw any conclusions.

Why does R.predict.svm return a list of the wrong size?

I am trying to use the R type provider to fit and predict a Support Vector Machines model. I was able to fit the model but when I try to predict the returned vector has the same length as the training vector, which it should not have.
I tried the equivalent code directly in R and the returned list has the correct length.
Why is this happening?
Here is an example:
open System
open RDotNet
open RProvider
open RProvider.stats
open RProvider.e1071
// Random number generator
let rng = Random()
let rand () = rng.NextDouble()
// Generate fake X1 and X2
let X1s = [ for i in 0 .. 9 -> 10. * rand () ] // length = 10
let X2s = [ for i in 0 .. 9 -> 5. * rand () ] // length = 10
let Z1s = [ for i in 0 .. 5 -> 10. * rand () ] // length = 6
let Z2s = [ for i in 0 .. 5 -> 5. * rand () ] // length = 6
// Build Ys
let Ys = [0;1;0;1;0;1;0;1;0;1]
let XMat =
["X1", box X1s; "X2", box X2s]
|> namedParams
|> R.cbind
let ZMat =
["Z1", box Z1s; "Z2", box Z2s]
|> namedParams
|> R.cbind
let svm_model =
["x", box XMat; "y", box Ys ; "type", box "C"; "gamma", box 1.0]
|> namedParams
|> R.svm
let svm_predict = R.predict(svm_model, ZMat)
let res =
if svm_predict.Type = RDotNet.Internals.SymbolicExpressionType.IntegerVector then
svm_predict.AsInteger()
|> List.ofSeq
else failwithf "Expecting a Numeric but got a %A" svm_predict.Type
printfn "The predicted values are: %A" res
// The predicted values are: [1; 2; 1; 2; 1; 2; 1; 1; 1; 2]
And here is the original R code:
library(stats)
library(e1071)
// Random number generator
x1 <- 10 * rnorm(10)
x2 <- 5 * rnorm(10)
x = cbind(x1, x2)
z1 <- 10 * rnorm(5)
z2 <- 5 * rnorm(5)
z = cbind(z1, z2)
zs <- c(0,1,0,1,0,1,0,1,0,1)
svm_fit = svm(x=x,y=zs,type="C",gamma=1.0)
svm_pred = predict(svm_fit, z)
print(svm_pred)
1 2 3 4 5
1 0 1 1 1
Levels: 0 1
I suspect the issue might be when passing parameters to the R.predict function. I'm not an expert on SVMs, so I'm not sure what is the result this should give, but when I call it as follows, I get results similar to your R version:
let svm_predict =
namedParams ["object", box svm_model; "newdata", box ZMat ]
|> R.predict
I think what's going on is that the R type provider infers some information about parameter names of the predict function, but is not able to figure out exactly what the second parameter is - and so rather than providing it as newdata, it provides it as something else.

Constrained Regression in R

I'm using the R type-provider from F# to access some regression related R functionality. I would like to estimate a regression when there is a constraint on the regression coefficients, so that their weighted average is 0. The weights sum to 1. The below example is simplified as I have dozens of coefficients, with varying weights, I only show the R code below:
y1 <- runif(n = 50,min = 0.02,max=0.05)
y2 <- runif(n=50,min=0.01,max=0.03)
y <- c(x1,x2)
x1 <- c(rep(0,50),rep(1,50))
x2 <- c(rep(1,50),rep(0,50))
lm(y~x1+x2)
This gives the output of
> lm(y~x1+x2)
Call:
lm(formula = y ~ x1 + x2)
Coefficients:
(Intercept) x1 x2
0.03468 -0.01460 NA
as expected. However I would like to place a constraint on x1 and x2, so their weighted average is (0.5 * x1 + 0.5 * x2) = 0. In that case the intercept becomes mean(y) = 0.02737966 and the x1 and x2 coefficients will show the offset from this value (-0.006 and +0.007 respectively). It seems the packages quadprog and mgcvare applicable however I wasn't able to apply the constraints.
Maybe not exactly an answer to your question, since it asks for doing the optimization in R. But maybe the following helps. It uses the NLopt library anyway which I think is what R uses? Let me know if you need help in formulating the MLE but for a linear model with gaussian assumptions and no endogeneity it should be straightforward enough.
Note that even though LN_COBYLA doesn't use user supplied gradients, the match with pattern in cFunc and oFunc ignores it. I tried with LD_LBFGS but that doesn't support AddEqualZeroConstraint().
[EDIT]
Adding complete example you can use as template. Its not idiomatic, and quite ugly, but illustrates the point. However, in this example, the constraints will cause this to degenerate. You need NLOptNet, MathNet.Numerics, Fsharp Charting. Maybe it helps other people looking to do constrained optimization in F#.
open System
open System.IO
open FSharp.Core.Operators
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.Distributions
open DiffSharp.Numerical.Float64
open NLoptNet
let (.*) (m1 : Matrix<float>) (m2 : Matrix<float>) =
m1.Multiply(m2)
let (.+) (m1 : Matrix<float>) (m2 : Matrix<float>) =
m1.Add(m2)
let (.-) (m1 : Matrix<float>) (m2 : Matrix<float>) =
m1.Subtract(m2)
let V = matrix [[1.; 0.5; 0.2]
[0.5; 1.; 0.]
[0.2; 0.; 1.]]
let dat = (DenseMatrix.init 200 3 ( fun i j -> Normal.Sample(0., 1.) )) .* V.Cholesky().Factor
let y = DenseMatrix.init 200 1 (fun i j -> 0.)
let x0 = DenseMatrix.init 200 1 (fun i j -> 0.)
let x1 = DenseMatrix.init 200 1 (fun i j -> 0.)
for i in 0 .. 199 do
y.[i, 0] <- dat.[i, 0]
x0.[i, 0] <- dat.[i, 1]
x1.[i, 0] <- dat.[i, 2]
let ll (th : float array) =
let t1 = x0.Multiply(th.[0]) .+ x1.Multiply(th.[1])
let res = (y .- t1).PointwisePower(2.)
res.ColumnAbsoluteSums().Sum() / 200.
let oFunc (th : float array) (gradvec : float array) =
match gradvec with
| null -> ()
| _ -> (grad ll th).CopyTo(gradvec, 0)
ll th
let cFunc (th : float array) (gradvec : float array) =
match gradvec with
| null -> ()
| _ -> (grad ll th).CopyTo(gradvec, 0)
th.[0] + th.[1]
let fitFunc () =
let solver = new NLoptSolver(NLoptAlgorithm.LN_COBYLA, uint32(2), 1e-7, 100000)
solver.SetLowerBounds([|-10.; -10.;|])
solver.SetUpperBounds([|10.; 10.;|])
//solver.AddEqualZeroConstraint(cFunc)
solver.SetMinObjective(oFunc)
let initialValues = [|1.; 2.;|]
let objReached, finalScore = solver.Optimize(initialValues)
objReached |> printfn "%A"
let fittedParams = initialValues
fittedParams |> printfn "%A"
fittedParams
let fittedParams = fitFunc() |> DenseVector
let yh = DenseMatrix.init 200 1 (fun i j -> 0.)
for i in 0 .. 199 do
yh.[i, 0] <- dat.[i, 1] * fittedParams.[0] + dat.[i, 2] * fittedParams.[1]
Chart.Combine([Chart.Line(y.Column(0), Name="y")
Chart.Line(yh.Column(0), Name="yh")
|> Chart.WithLegend(Title="Model", Enabled=true)] )
|> Chart.Show

logical calculation of Integer interval

what are the rules to calculate logical op. (AND OR XOR) of two integer intervals ?
Given two intervals [a,b] [c,d] i want to calculate [a,b] xor [c,d]
I assume the result to be multiple ranges
I looked at filib++ and read WIKI but found just Arithmetic op. support
Can anyone educate me
You can find an implementation of “bitwise and”, “bitwise xor” and “bitwise or” between intervals in the latest version of Frama-C, in file src/ai/ival.ml. In fact these functions operate on values of type Ival.t, which represent either a small set of integer values, an interval with congruence information or a floating-point interval. You will only be interested in the case Top _, Top _ (which corresponds to the integer intervals with congruence information). The function compute the result as an Ival.t, possibly over-approximated, but which contains all the values x op y with x in the first interval and y in the second interval.
As the comment says, the algorithm for pos_max_land is optimal for precision but does not have the best complexity with respect to the number of bits of the integers. I only understood this after I was finished with writing the function, and the width of an integer does not go beyond 64 for this usecase, so I didn't bother writing the faster version.
The file src/ai/ival.ml is licensed under the LGPL 2.1. If you do something cool with it, I would be happy to hear about it.
(* [different_bits min max] returns an overapproximation of the mask
of the bits that can be different for different numbers
in the interval [min]..[max] *)
let different_bits min max =
let x = Int.logxor min max in
next_pred_power_of_two x
(* [pos_max_land min1 max1 min2 max2] computes an upper bound for
[x1 land x2] where [x1] is in [min1]..[max1] and [x2] is in [min2]..[max2].
Precondition : [min1], [max1], [min2], [max2] must all have the
same sign.
Note: the algorithm below is optimal for the problem as stated.
It is possible to compute this optimal solution faster but it does not
seem worth the time necessary to think about it as long as integers
are at most 64-bit. *)
let pos_max_land min1 max1 min2 max2 =
let x1 = different_bits min1 max1 in
let x2 = different_bits min2 max2 in
(* Format.printf "pos_max_land %a %a -> %a | %a %a -> %a#."
Int.pretty min1 Int.pretty max1 Int.pretty x1
Int.pretty min2 Int.pretty max2 Int.pretty x2; *)
let fold_maxs max1 p f acc =
let rec aux p acc =
let p = Int.shift_right p Int.one in
if Int.is_zero p
then f max1 acc
else if Int.is_zero (Int.logand p max1)
then aux p acc
else
let c = Int.logor (Int.sub max1 p) (Int.pred p) in
aux p (f c acc)
in aux p acc
in
let sx1 = Int.succ x1 in
let n1 = fold_maxs max1 sx1 (fun _ y -> succ y) 0 in
let maxs1 = Array.make n1 sx1 in
let _ = fold_maxs max1 sx1 (fun x i -> Array.set maxs1 i x; succ i) 0 in
fold_maxs max2 (Int.succ x2)
(fun max2 acc ->
Array.fold_left
(fun acc max1 -> Int.max (Int.logand max1 max2) acc)
acc
maxs1)
(Int.logand max1 max2)
let bitwise_or v1 v2 =
if is_bottom v1 || is_bottom v2
then bottom
else
match v1, v2 with
Float _, _ | _, Float _ -> top
| Set s1, Set s2 ->
apply2_v Int.logor s1 s2
| Set s, v | v, Set s when Array.length s = 1 && Int.is_zero s.(0) -> v
| Top _, _ | _, Top _ ->
( match min_and_max v1 with
Some mn1, Some mx1 when Int.ge mn1 Int.zero ->
( match min_and_max v2 with
Some mn2, Some mx2 when Int.ge mn2 Int.zero ->
let new_max = next_pred_power_of_two (Int.logor mx1 mx2) in
let new_min = Int.max mn1 mn2 in (* Or can only add bits *)
inject_range (Some new_min) (Some new_max)
| _ -> top )
| _ -> top )
let bitwise_xor v1 v2 =
if is_bottom v1 || is_bottom v2
then bottom
else
match v1, v2 with
| Float _, _ | _, Float _ -> top
| Set s1, Set s2 -> apply2_v Int.logxor s1 s2
| Top _, _ | _, Top _ ->
(match min_and_max v1 with
| Some mn1, Some mx1 when Int.ge mn1 Int.zero ->
(match min_and_max v2 with
| Some mn2, Some mx2 when Int.ge mn2 Int.zero ->
let new_max = next_pred_power_of_two (Int.logor mx1 mx2) in
let new_min = Int.zero in
inject_range (Some new_min) (Some new_max)
| _ -> top )
| _ -> top )

How do variables in pattern matching allow parameter omission?

I'm doing some homework but I've been stuck for hours on something.
I'm sure it's really trivial but I still can't wrap my head around it after digging through the all documentation available.
Can anybody give me a hand?
Basically, the exercise in OCaml programming asks to define the function x^n with the exponentiation by squaring algorithm.
I've looked at the solution:
let rec exp x = function
0 -> 1
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| n when n mod 2 <> 0 -> let y = exp x ((n-1)/2) in y*y*x
;;
What I don't understand in particular is how the parameter n can be omitted from the fun statement and why should it be used as a variable for a match with x, which has no apparent link with the definition of exponentiation by squaring.
Here's how I would do it:
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
Your version is syntaxically correct, yields a good answer, but is long to execute.
In your code, exp is called recursively twice, thus yielding twice as much computation, each call yielding itself twice as much computation, etc. down to n=0. In the solution, exp is called only once, the result is storred in the variable y, then y is squared.
Now, about the syntax,
let f n = match n with
| 0 -> 0
| foo -> foo-1
is equivalent to:
let f = function
| 0 -> 0
| foo -> foo-1
The line let rec exp x = function is the begging of a function that takes two arguments: x, and an unnammed argument used in the pattern matching. In the pattern matching, the line
| n when n mod 2 = 0 ->
names this argument n. Not that a different name could be used in each case of the pattern matching (even if that would be less clear):
| n when n mod 2 = 0 -> let y = exp x (n/2) in y*y
| p when p mod 2 <> 0 -> let y = exp x ((p-1)/2) in y*y*x
The keyword "function" is not a syntaxic sugar for
match x with
but for
fun x -> match x with
thus
let rec exp x = function
could be replaced by
let rec exp x = fun y -> match y with
which is of course equivalent with your solution
let rec exp x y = match y with
Note that i wrote "y" and not "n" to avoid confusion. The n variable introduced after the match is a new variable, which is only related to the function parameter because it match it. For instance, instead of
let y = x in ...
you could write :
match x with y -> ...
In this match expression, the "y" expression is the "pattern" matched. And like any pattern, it binds its variables (here y) with the value matched. (here the value of x) And like any pattern, the variables in the pattern are new variables, which may shadow previously defined variables. In your code :
let rec exp x n = match n with
0 -> 1
| n when (n mod 2) = 1 -> (exp x ((n-1)/2)) * (exp x ((n-1)/2)) * x
| n when (n mod 2) = 0 -> (exp x (n/2)) * (exp x (n/2))
;;
the variable n in the two cases shadow the parameter n. This isn't a problem, though, since the two variable with the same name have the same value.

Resources