How to implement Python class in F# - f#

I have the following simple class implementation in Python. I would like to duplicate the functionality in F#...but I am not sure how...
class MyClass(object):
def __init__(self):
pass
def addEvidence(self,dataX,dataY):
newdataX = np.ones([dataX.shape[0],dataX.shape[1]+1])
newdataX[:,0:dataX.shape[1]]=dataX
# build and save the model
self.model_coefs, residuals, rank, s = np.linalg.lstsq(newdataX, dataY)
def query(self,points):
return (self.model_coefs[:-1] * points).sum(axis = 1) + self.model_coefs[-1]
So, in pseudo-code, the class looks like this:
Class()
self.model_coefs = []
self.residuals = []
self.rank = 0
self.addEvidence(dataX,dataY):
x, y, z = f(dataX,dataY)
self.model_coefs <- x
self.residuals <- y
self.rank <- z
self.query(points)
return ([self.model_coefs[i] * points[i] for i in points].sum()) + self.model_coefs[self.model_coefs.length]
And if there is an F-sharpy way to do this, great--The thing is, the entity is kind of a data-bin with a functional wrapper by design, so I'm not sure how it would be done with functions...
Anyhow, here is my try so far (I'm skipping the linear regression for now..)
namespace Learners
type LinearRegressionLearner() =
member this.ModelCoefficients : int [] = [|0;0|]
member this.Residuals : int[] = [||]
member this.Rank = 0
member this.addEvidence dataX dataY = "expletive"
member this.query (points:int[]) =
points |> Array.iteri(fun i x -> x * this.ModelCoefficients.[i])
I get an error here: points |> Array.iteri(fun i x -> x * this.ModelCoefficients.[i])...I guess this.ModelCoefficients.[i] is a unit and doesn't match x, which is an integer??

Array.iteri (as with all iter functions) expects a function that returns unit – yours returns int. Maybe you want Array.mapi instead?

Related

Max and Min of a set of variables in z3py

I have a problem where I want to limit the range of a real variable between the maximum and minimum value of another set of real variables.
s = Solver()
y = Real('y')
Z = RealVector('z', 10)
s.add(And(y >= min(Z), y <= max(Z)))
Is there a way to do this in z3py?
You can use Axel's solution; though that one requires you to create an extra variable and also asserts more constraints than needed. Moreover, it doesn't let you use min and max as simple functions. It might be easier to just program this in a functional way, like this:
# Return minimum of a vector; error if empty
def min(vs):
m = vs[0]
for v in vs[1:]:
m = If(v < m, v, m)
return m
# Return maximum of a vector; error if empty
def max(vs):
m = vs[0]
for v in vs[1:]:
m = If(v > m, v, m)
return m
Another difference is that in the functional style we throw an error if the vector is empty. In the other style, the result will essentially be unconstrained. (i.e., min/max can take any value.) You should consider which semantics is right for your application, in case the vector you're passing might be empty. (At the least, you should change it so it prints out a nicer error message. Currently it'll throw an IndexError: list index out of range error if given an empty vector.)
Now you can say:
s = Solver()
y = Real('y')
Z = RealVector('z', 10)
s.add(And(y >= min(Z), y <= max(Z)))
print (s.check())
print (s.model())
This prints:
sat
[z__7 = -1,
z__0 = -7/2,
z__4 = -5/2,
z__5 = -2,
z__3 = -9/2,
z__2 = -4,
z__8 = -1/2,
y = 0,
z__9 = 0,
z__6 = -3/2,
z__1 = -3]
You could benefit from Hakan Kjellerstrand's collection of useful z3py definitions:
from z3 import *
# Functions written by Hakan Kjellerstrand
# http://hakank.org/z3/
# The following can be used by importing http://www.hakank.org/z3/z3_utils_hakank.py
# v is the maximum value of x
def maximum(sol, v, x):
sol.add(Or([v == x[i] for i in range(len(x))])) # v is an element in x)
for i in range(len(x)):
sol.add(v >= x[i]) # and it's the greatest
# v is the minimum value of x
def minimum(sol, v, x):
sol.add(Or([v == x[i] for i in range(len(x))])) # v is an element in x)
for i in range(len(x)):
sol.add(v <= x[i]) # and it's the smallest
s = Solver()
y = Real('y')
zMin = Real('zMin')
zMax = Real('zMax')
Z = RealVector('z', 10)
maximum(s, zMin, Z)
minimum(s, zMax, Z)
s.add(And(y >= zMin, y <= zMax))
print(s.check())
print(s.model())

Is there a way to return a pair of integers using the let construct in standard ML?

I am trying to return a pair of sums using the let construct in sml. Every way I have tried will only return one value. I have tried creating a list by using cons (::) and then returning the list, but that gives an error as well.
val t = [(3,4), (4,5), (5,6)];
fun sumPairs(nil) = 0
| sumPairs((x,y)::zs) =
let
val sumFirst = x + sumPairs(zs)
val sumSecond = y + sumPairs(zs)
in
(sumFirst, sumSecond) <how would I return this as a tuple or list?>
end;
sumPairs(t);
The problem is not with (sumFirst, sumSecond) or with let specifically, but with the rest of your code.
The base case and the recursions say that sumPairs produces an int, not a pair of ints.
Because of this, there is a conflict when you try produce a pair.
Your base case should be (0,0), not 0, since it must be a pair.
You also need to deconstruct the result from the recursion since that produces a pair, not an integer.
Like this
fun sumPairs nil = (0, 0)
| sumPairs ((x,y)::zs) =
let
val (sumFirst, sumSecond) = sumPairs zs
in
(x + sumFirst, y + sumSecond)
end;

How to change x,y coordinates in a class

I have an assignment, where I have made to classes, "Drone" and "Airspace".
I need to move the x,y coordinates of all the drones that exists, which I have stored in x.drones in the Airspace class, as a list. However I am having trouble accessing and manipulating the list in x.drones. How can I in a class change the values of a list from another member?
I have given all my code so far down under, it's the method x.flyDrones I need help with.
I have tried to make a for loop, but that doesn't seem to work.
module Drones
type Drone(x1:int, y1:int, x2:int, y2:int, spd:int) =
static let mutable count = 0
static let mutable hinsta = []
let mutable position = (x1,y1)
let mutable destination = (x2,y2)
let mutable speed = spd
do count <-count + 1
let mutable insta = [x1,y1,x2,y2,spd]
do hinsta <- hinsta # insta
static member Count = count
static member Collection = hinsta
member x.fly =
if fst destination - fst position > 0 then position <- (x1+1,y1)
else if snd destination - snd position > 0 then position <- (x1,y1+1)
member x.isFinished =
fst destination - fst position = 0 && snd destination - snd position = 0
type Airspace =
member x.drones = Drone.Collection
member x.droneDist(drone1, drone2) =
let dist = ((fst drone1 - fst drone2),(snd drone1 - snd drone2))
dist
member x.flyDrones =
for drone in x.drones do
member x.addDrone(x1, y1, x2, y2, spd) = new Drone(x1, y1, x2, y2, spd)
//member x.willCollide(time) =
Sorry to disappoint you, OliverVS, but this ain't gonna fly. I believe I can see your intentions, but this needs a complete rewrite rather than a fix. Let me try to give you some advice.
First of all, why do you use classes at all? I wouldn't, but I'll assume the assignment says you should, so let's continue doing that.
The Drone class should be responsible for keeping the information for a single drone, but you have x.drones in Airspace that is set to Drone.Collection, which is not a collection or a list of Drone, but rather a list of int*int*int*int*int that is kept as a static list in the Drone class. That's really messy. Why do the Drone class have statics? The Airspace class should be responsible for keeping a list of Drone, so get rid of all the statics in Drone, and instead find a way to maintain the list of drones in the Airspace class.
The Airspace type has instance members - not static members - yet there is no constructor. You will likely want a default constructor, so it should be Airspace() =, and then you need to instantiate a single Airspace.
You don't need to maintain a count when you can simply find the count of drones by getting the length of the list of drones.
You can solve the entire assignment without using a single static anywhere.
Start member names with capital letter.
Members like x.fly and x.flyDrones are not methods, because they don't have arguments. You need at least the () argument for them to be methods.
x.addDrone correctly creates a new Drone, but it should add it to the list of drones that the Airspace class should have.
The Drone class uses tuples for position and destination, which leads to considerably less readable code with use of fst and snd throughout. Don't do that. In general, use records instead of tuples if the tuples cause confusion. Don't use mysterious names like x1, y1, x2, y2, spd, insta, hinsta, fly.
A few changes will make the Drone class a little better, though I haven't followed all of my own advice here. The point of shadowing the class arguments with mutables of the same name, is 1) indeed that they are mutable which means they can be changed, and 2) block further use of the original arguments, which avoids confusion of any sort, whether it's while writing code or reading code.
type Drone(x1:int, y1:int, x2:int, y2:int, speed:int) =
let mutable x1 = x1
let mutable y1 = y1
let mutable x2 = x2
let mutable y2 = y2
let mutable speed = speed
member _.X1 = x1
member _.Y1 = y1
member _.X2 = x2
member _.Y2 = y2
member _.Speed = speed
member _.Fly() =
if x2 - x1 > 0 then x1 <- x1 + 1
elif y2 - y1 > 0 then y1 <- y1 + 1
member _.IsFinished = x2 - x1 = 0 && y2 - y1 = 0

Efficient way to extract and collect a random subsample of a generator in Julia

Consider a generator in Julia that if collected will take a lot of memory
g=(x^2 for x=1:9999999999999999)
I want to take a random small subsample (Say 1%) of it, but I do not want to collect() the object because will take a lot of memory
Until now the trick I was using was this
temp=collect((( rand()>0.01 ? nothing : x ) for x in g))
random_sample= temp[temp.!=nothing]
But this is not efficient for generators with a lot of elements, collecting something with so many nothing elements doesnt seem right
Any idea is highly appreciated. I guess the trick is to be able to get random elements from the generator without having to allocate memory for all of it.
Thank you very much
You can use a generator with if condition like this:
[v for v in g if rand() < 0.01]
or if you want a bit faster, but more verbose approach (I have hardcoded 0.01 and element type of g and I assume that your generator supports length - otherwise you can remove sizehint! line):
function collect_sample(g)
r = Int[]
sizehint!(r, round(Int, length(g) * 0.01))
for v in g
if rand() < 0.01
push!(r, v)
end
end
r
end
EDIT
Here you have examples of self avoiding sampler and reservoir sampler giving you fixed output size. The smaller fraction of the input you want to get the better it is to use self avoiding sampler:
function self_avoiding_sampler(source_size, ith, target_size)
rng = 1:source_size
idx = rand(rng)
x1 = ith(idx)
r = Vector{typeof(x1)}(undef, target_size)
r[1] = x1
s = Set{Int}(idx)
sizehint!(s, target_size)
for i = 2:target_size
while idx in s
idx = rand(rng)
end
#inbounds r[i] = ith(idx)
push!(s, idx)
end
r
end
function reservoir_sampler(g, target_size)
r = Vector{Int}(undef, target_size)
for (i, v) in enumerate(g)
if i <= target_size
#inbounds r[i] = v
else
j = rand(1:i)
if j < target_size
#inbounds r[j] = v
end
end
end
r
end

Adding Overloaded Constructors to Implicit F# Type

I have created the following type using implicit type construction:
open System
type Matrix(sourceMatrix:double[,]) =
let rows = sourceMatrix.GetUpperBound(0) + 1
let cols = sourceMatrix.GetUpperBound(1) + 1
let matrix = Array2D.zeroCreate<double> rows cols
do
for i in 0 .. rows - 1 do
for j in 0 .. cols - 1 do
matrix.[i,j] <- sourceMatrix.[i,j]
//Properties
///The number of Rows in this Matrix.
member this.Rows = rows
///The number of Columns in this Matrix.
member this.Cols = cols
///Indexed Property for this matrix.
member this.Item
with get(x, y) = matrix.[x, y]
and set(x, y) value =
this.Validate(x,y)
matrix.[x, y] <- value
//Methods
/// Validate that the specified row and column are inside of the range of the matrix.
member this.Validate(row, col) =
if(row >= this.Rows || row < 0) then raise (new ArgumentOutOfRangeException("row is out of range"))
if(col >= this.Cols || col < 0) then raise (new ArgumentOutOfRangeException("column is out of range"))
However now I need to add the following overloaded constructor to this type (which is in C# here):
public Matrix(int rows, int cols)
{
this.matrix = new double[rows, cols];
}
The problem that I have is that it seems any overloaded constructors in an implicit type must have a parameter list that is a subset of the first constructor. Obviously the constructor I want to add does not meet this requirement. Is there any way to do this using implicit type construction? Which way should I do this? I'm pretty new to F# so if you could show the whole type with your changes in it I would greatly appreciate it.
Thanks in advance,
Bob
P.S. If you have any other suggestions to make my class more in the functional style please feel free to comment on that as well.
I would probably just do this:
type Matrix(sourceMatrix:double[,]) =
let matrix = Array2D.copy sourceMatrix
let rows = (matrix.GetUpperBound 0) + 1
let cols = (matrix.GetUpperBound 1) + 1
new(rows, cols) = Matrix( Array2D.zeroCreate rows cols )
unless we are talking about very large arrays which are created very often (i.e. copying the empty array becomes a performance bottleneck).
If you want to emulate the C# version, you need an explicit field that can be accessed from both constructors, like so:
type Matrix(rows,cols) as this =
[<DefaultValue>]
val mutable matrix : double[,]
do this.matrix <- Array2D.zeroCreate rows cols
new(source:double[,]) as this =
let rows = source.GetUpperBound(0) + 1
let cols = source.GetUpperBound(1) + 1
Matrix(rows, cols)
then
for i in 0 .. rows - 1 do
for j in 0 .. cols - 1 do
this.matrix.[i,j] <- source.[i,j]
BTW, there is also a matrix type in the F# PowerPack.

Resources