How to change x,y coordinates in a class - f#

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

Related

How to implement Python class in 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?

How to use f# constraints for generic calculation functions?

type Point<'t> =
val X : 't
val Y : 't
new(x : 't,y : 't) = { X = x; Y = y }
let clampedSubtract (p1:Point<_>) (p2:Point<_>) =
Point( max (p2.X - p1.X) 0, max (p2.Y - p1.Y) 0 )
If you look at the code above, you will notice, that the function is not implemented as generic as it should be.
First, using the 0 in the max expressions clamps the type to int. But it should be the type of whatever type Point<'t> has and not Point<int>.
But even more important, this function can only work as expected, if signed types are used for `t.
This raises a few questions of mine:
Is there a way to obtain the neutral element (zero) from a generic (number) type?
How can I express a restriction such as "only signed number"?
Is there a way to extend type constraint system in F#?
Thanks, in advance.
The solution to the first question as already answered is to use an inline function together with GenericZero and that's all.
Regarding the signed restriction, actually there's an easy way to restrict it to signed types. Use somewhere the generic unary negation which is defined only for signed types:
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X + -p1.X) zero, max (p2.Y + -p1.Y) zero )
let result1 = clampedSubtract (Point(4 , 5 )) (Point(4 , 5 ))
let result2 = clampedSubtract (Point(4y , 5y )) (Point(4y , 5y ))
let result3 = clampedSubtract (Point(4uy, 5uy)) (Point(4uy, 5uy)) // doesn't compile
In general, if you want to restrict any generic function to signed types you can define this function:
let inline whenSigned x = ignore (-x)
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
whenSigned p1.X
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X - p1.X) zero, max (p2.Y - p1.Y) zero )
Finally regarding your third question it's not very clear to me what do you mean with extending the type system. You can create static constraints by yourself, in that sense the system is already extensible.
I did a project sometime ago to emulate some Haskell types, part of the code of that project is still in a module in FsControl there you can have an idea to what level you can play with those constraints.
This makes it generic:
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X - p1.X) zero, max (p2.Y - p1.Y) zero )
But there's no way to constrain it to signed primitive types.

F# Interactive Pass ParamArray of Functions

I'm trying to expand on James Hugard's post How do I plot a data series in F#? and I'm running into a glitch when using a variable number of function arguments. If I specifically name out the functions for Hugard's LineChartForm like in this example, the code works as expected when loaded into the F# Interactive Interpreter:
(* This code is based off of a Stack Overflow post by
James Hugard #
https://stackoverflow.com/questions/3276357/how-do-i-plot-a-data-series-in-f
*)
module HuggardPlot
#r "System.Windows.Forms.DataVisualization"
open System.Windows.Forms
open System.Windows.Forms.DataVisualization.Charting
type LineChartForm( title, minX, maxX, func1, func2) =
inherit Form( Text=title )
let chart = new Chart(Dock=DockStyle.Fill)
let area = new ChartArea(Name="Area1")
(* Add the first plot Hugard style *)
let series = new Series()
do series.ChartType <- SeriesChartType.Line
do for i in minX .. maxX do
series.Points.AddXY(i, func1(i)) |> ignore
do series.ChartArea <- "Area1"
do chart.Series.Add( series )
(* Add the second plot Hugard style *)
let series2 = new Series()
do series2.ChartType <- SeriesChartType.Line
do for i in minX .. maxX do
series2.Points.AddXY(i, func2(i)) |> ignore
do series2.ChartArea <- "Area1"
do chart.Series.Add( series2 )
(* Add area1 to the plot *)
do chart.ChartAreas.Add(area)
do base.Controls.Add( chart )
(* Convenience method to make it easier to plot functions *)
let plotTwoFunctions minX maxX f1 f2 =
let LCF = new LineChartForm("lines", minX, maxX, f1, f2);
LCF.Show();
On the other hand, if I try to use the technique in the Parameter Arrays section of http://msdn.microsoft.com/en-us/library/dd233213.aspx to pass a variable number of functions via a ParamArray with the following code:
(* This code is based off of a Stack Overflow post by
James Hugard #
https://stackoverflow.com/questions/3276357/how-do-i-plot-a-data-series-in-f
*)
module HuggardPlot
#r "System.Windows.Forms.DataVisualization"
open System
open System.Windows.Forms
open System.Windows.Forms.DataVisualization.Charting
type LineChartForm(
title,
minX,
maxX,
[<ParamArray>] funcs: Object[]) =
inherit Form( Text=title )
let chart = new Chart(Dock=DockStyle.Fill)
let area = new ChartArea(Name="Area1")
do for func in funcs do
(* Add the first plot Hugard style *)
let series = new Series()
do series.ChartType <- SeriesChartType.Line
do for i in minX .. maxX do
series.Points.AddXY(i, func(i)) |> ignore
do series.ChartArea <- "Area1"
do chart.Series.Add( series )
(* Add area1 to the plot *)
do chart.ChartAreas.Add(area)
do base.Controls.Add( chart )
(* Convenience method to make it easier to plot functions *)
let plotTwoFunctions minX maxX f1 f2 =
let LCF = new LineChartForm("lines", minX, maxX, f1, f2);
LCF.Show();
I get an error on line 27 series.Points.AddXY(i, func(i)) |> ignore stating "This value is not a function and cannot be applied" with a red squiggly under "func".
I suspect this has something to do with the fact that I am using [<ParamArray>] funcs: Object[] as a parameter definition to Mr. Hugard's LineChartForm Type.
What should I change [<ParamArray>] funcs: Object[] to so line 27 of the second code example will recognize "func" as a function?
If you want to create a method that takes params array of functions, then you need to define the parameter as [<ParamArray>] funcs: (float -> float)[]. In your original version, the type was Object[] meaning that individual elements of the array were objects - if you change the type of elements to functions, then F# will recognize that you can call them.
However, if you're simply interested in charting F# data, then there is already a good wrapper for the WinForms DataVisualization library called F# Chart and available on GitHub. There is also a comprehensive documentation available on MSDN (if you use the latest version of the library, then FSharpChart has been renamed to just Chart).
To create a plot comparing two functions over a specified range, you can simply write:
let plotTwoFunctions minX maxX f1 f2 =
Chart.Combine
[ Chart.Line [ for x in minX .. maxX -> x, f1 x ]
Chart.Line [ for x in minX .. maxX -> x, f2 x ] ]
This creates two individual line charts (with data generated by the two functions) and then combines them into a single chart using Chart.Combine.

F#/"Accelerator v2" DFT algorithm implementation probably incorrect

I'm trying to experiment with software defined radio concepts. From this article I've tried to implement a GPU-parallelism Discrete Fourier Transform.
I'm pretty sure I could pre-calculate 90 degrees of the sin(i) cos(i) and then just flip and repeat rather than what I'm doing in this code and that that would speed it up. But so far, I don't even think I'm getting correct answers. An all-zeros input gives a 0 result as I'd expect, but all 0.5 as inputs gives 78.9985886f (I'd expect a 0 result in this case too). Basically, I'm just generally confused. I don't have any good input data and I don't know what to do with the result or how to verify it.
This question is related to my other post here
open Microsoft.ParallelArrays
open System
// X64MulticoreTarget is faster on my machine, unexpectedly
let target = new DX9Target() // new X64MulticoreTarget()
ignore(target.ToArray1D(new FloatParallelArray([| 0.0f |]))) // Dummy operation to warm up the GPU
let stopwatch = new System.Diagnostics.Stopwatch() // For benchmarking
let Hz = 50.0f
let fStep = (2.0f * float32(Math.PI)) / Hz
let shift = 0.0f // offset, once we have to adjust for the last batch of samples of a stream
// If I knew that the periodic function is periodic
// at whole-number intervals, I think I could keep
// shift within a smaller range to support streams
// without overflowing shift - but I haven't
// figured that out
//let elements = 8192 // maximum for a 1D array - makes sense as 2^13
//let elements = 7240 // maximum on my machine for a 2D array, but why?
let elements = 7240
// need good data!!
let buffer : float32[,] = Array2D.init<float32> elements elements (fun i j -> 0.5f) //(float32(i * elements) + float32(j)))
let input = new FloatParallelArray(buffer)
let seqN : float32[,] = Array2D.init<float32> elements elements (fun i j -> (float32(i * elements) + float32(j)))
let steps = new FloatParallelArray(seqN)
let shiftedSteps = ParallelArrays.Add(shift, steps)
let increments = ParallelArrays.Multiply(fStep, steps)
let cos_i = ParallelArrays.Cos(increments) // Real component series
let sin_i = ParallelArrays.Sin(increments) // Imaginary component series
stopwatch.Start()
// From the documentation, I think ParallelArrays.Multiply does standard element by
// element multiplication, not matrix multiplication
// Then we sum each element for each complex component (I don't understand the relationship
// of this, or the importance of the generalization to complex numbers)
let real = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, cos_i))).[0]
let imag = target.ToArray1D(ParallelArrays.Sum(ParallelArrays.Multiply(input, sin_i))).[0]
printf "%A in " ((real * real) + (imag * imag)) // sum the squares for the presence of the frequency
stopwatch.Stop()
printfn "%A" stopwatch.ElapsedMilliseconds
ignore (System.Console.ReadKey())
I share your surprise that your answer is not closer to zero. I'd suggest writing naive code to perform your DFT in F# and seeing if you can track down the source of the discrepancy.
Here's what I think you're trying to do:
let N = 7240
let F = 1.0f/50.0f
let pi = single System.Math.PI
let signal = [| for i in 1 .. N*N -> 0.5f |]
let real =
seq { for i in 0 .. N*N-1 -> signal.[i] * (cos (2.0f * pi * F * (single i))) }
|> Seq.sum
let img =
seq { for i in 0 .. N*N-1 -> signal.[i] * (sin (2.0f * pi * F * (single i))) }
|> Seq.sum
let power = real*real + img*img
Hopefully you can use this naive code to get a better intuition for how the accelerator code ought to behave, which could guide you in your testing of the accelerator code. Keep in mind that part of the reason for the discrepancy may simply be the precision of the calculations - there are ~52 million elements in your arrays, so accumulating a total error of 79 may not actually be too bad. FWIW, I get a power of ~0.05 when running the above single precision code, but a power of ~4e-18 when using equivalent code with double precision numbers.
Two suggestions:
ensure you're not somehow confusing degrees with radians
try doing it sans-parallelism, or just with F#'s asyncs for parallelism
(In F#, if you have an array of floats
let a : float[] = ...
then you can 'add a step to all of them in parallel' to produce a new array with
let aShift = a |> (fun x -> async { return x + shift })
|> Async.Parallel |> Async.RunSynchronously
(though I expect this might be slower that just doing a synchronous loop).)

Unwrapping nested loops in F#

I've been struggling with the following code. It's an F# implementation of the Forward-Euler algorithm used for modelling stars moving in a gravitational field.
let force (b1:Body) (b2:Body) =
let r = (b2.Position - b1.Position)
let rm = (float32)r.MagnitudeSquared + softeningLengthSquared
if (b1 = b2) then
VectorFloat.Zero
else
r * (b1.Mass * b2.Mass) / (Math.Sqrt((float)rm) * (float)rm)
member this.Integrate(dT, (bodies:Body[])) =
for i = 0 to bodies.Length - 1 do
for j = (i + 1) to bodies.Length - 1 do
let f = force bodies.[i] bodies.[j]
bodies.[i].Acceleration <- bodies.[i].Acceleration + (f / bodies.[i].Mass)
bodies.[j].Acceleration <- bodies.[j].Acceleration - (f / bodies.[j].Mass)
bodies.[i].Position <- bodies.[i].Position + bodies.[i].Velocity * dT
bodies.[i].Velocity <- bodies.[i].Velocity + bodies.[i].Acceleration * dT
While this works it isn't exactly "functional". It also suffers from horrible performance, it's 2.5 times slower than the equivalent c# code. bodies is an array of structs of type Body.
The thing I'm struggling with is that force() is an expensive function so usually you calculate it once for each pair and rely on the fact that Fij = -Fji. But this really messes up any loop unfolding etc.
Suggestions gratefully received! No this isn't homework...
Thanks,
Ade
UPDATED: To clarify Body and VectorFloat are defined as C# structs. This is because the program interops between F#/C# and C++/CLI. Eventually I'm going to get the code up on BitBucket but it's a work in progress I have some issues to sort out before I can put it up.
[StructLayout(LayoutKind.Sequential)]
public struct Body
{
public VectorFloat Position;
public float Size;
public uint Color;
public VectorFloat Velocity;
public VectorFloat Acceleration;
'''
}
[StructLayout(LayoutKind.Sequential)]
public partial struct VectorFloat
{
public System.Single X { get; set; }
public System.Single Y { get; set; }
public System.Single Z { get; set; }
}
The vector defines the sort of operators you'd expect for a standard Vector class. You could probably use the Vector3D class from the .NET framework for this case (I'm actually investigating cutting over to it).
UPDATE 2: Improved code based on the first two replies below:
for i = 0 to bodies.Length - 1 do
for j = (i + 1) to bodies.Length - 1 do
let r = ( bodies.[j].Position - bodies.[i].Position)
let rm = (float32)r.MagnitudeSquared + softeningLengthSquared
let f = r / (Math.Sqrt((float)rm) * (float)rm)
bodies.[i].Acceleration <- bodies.[i].Acceleration + (f * bodies.[j].Mass)
bodies.[j].Acceleration <- bodies.[j].Acceleration - (f * bodies.[i].Mass)
bodies.[i].Position <- bodies.[i].Position + bodies.[i].Velocity * dT
bodies.[i].Velocity <- bodies.[i].Velocity + bodies.[i].Acceleration * dT
The branch in the force function to cover the b1 == b2 case is the worst offender. You do't need this if softeningLength is always non-zero, even if it's very small (Epsilon). This optimization was in the C# code but not the F# version (doh!).
Math.Pow(x, -1.5) seems to be a lot slower than 1/ (Math.Sqrt(x) * x). Essentially this algorithm is slightly odd in that it's perfromance is dictated by the cost of this one step.
Moving the force calculation inline and getting rid of some divides also gives some improvement, but the performance was really being killed by the branching and is dominated by the cost of Sqrt.
WRT using classes over structs: There are cases (CUDA and native C++ implementations of this code and a DX9 renderer) where I need to get the array of bodies into unmanaged code or onto a GPU. In these scenarios being able to memcpy a contiguous block of memory seems like the way to go. Not something I'd get from an array of class Body.
I'm not sure if it's wise to rewrite this code in a functional style. I've seen some attempts to write pair interaction calculations in a functional manner and each one of them was harder to follow than two nested loops.
Before looking at structs vs. classes (I'm sure someone else has something smart to say about this), maybe you can try optimizing the calculation itself?
You're calculating two acceleration deltas, let's call them dAi and dAj:
dAi = r*m1*m2/(rm*sqrt(rm)) / m1
dAj = r*m1*m2/(rm*sqrt(rm)) / m2
[note: m1 = bodies.[i].mass, m2=bodies.[j].mass]]
The division by mass cancels out like this:
dAi = rm2 / (rmsqrt(rm))
dAj = rm1 / (rmsqrt(rm))
Now you only have to calculate r/(rmsqrt(rm)) for each pair (i,j).
This can be optimized further, because 1/(rmsqrt(rm)) = 1/(rm^1.5) = rm^-1.5, so if you let r' = r * (rm ** -1.5), then Edit: no it can't, that's premature optimization talking right there (see comment). Calculating r' = 1.0 / (r * sqrt r) is fastest.
dAi = m2 * r'
dAj = m1 * r'
Your code would then become something like
member this.Integrate(dT, (bodies:Body[])) =
for i = 0 to bodies.Length - 1 do
for j = (i + 1) to bodies.Length - 1 do
let r = (b2.Position - b1.Position)
let rm = (float32)r.MagnitudeSquared + softeningLengthSquared
let r' = r * (rm ** -1.5)
bodies.[i].Acceleration <- bodies.[i].Acceleration + r' * bodies.[j].Mass
bodies.[j].Acceleration <- bodies.[j].Acceleration - r' * bodies.[i].Mass
bodies.[i].Position <- bodies.[i].Position + bodies.[i].Velocity * dT
bodies.[i].Velocity <- bodies.[i].Velocity + bodies.[i].Acceleration * dT
Look, ma, no more divisions!
Warning: untested code. Try at your own risk.
I'd like to play arround with your code, but it's difficult since the definition of Body and FloatVector is missing and they also seem to be missing from the orginal blog post you point to.
I'd hazard a guess that you could improve your performance and rewrite in a more functional style using F#'s lazy computations:
http://msdn.microsoft.com/en-us/library/dd233247(VS.100).aspx
The idea is fairly simple you wrap any expensive computation that could be repeatedly calculated in a lazy ( ... ) expression then you can force the computation as many times as you like and it will only ever be calculated once.

Resources