I'd like to rewrite this Parallel.For loop using a PLINQ method AsParallel(). As far as I have seen, AsParallel() requires passing an entire sequence to it, eg create Array A, then call A.AsParallel().ForAll or A.AsParallel().Select . Is there a way to make AsParallel() work on a range - in this case, from low to high?
for k = 2 to m+n do
let low = max 1 (k-m)
let high = min (k-1) n
Parallel.For(low, high + 1, (fun j ->
One way to do this would be to use ParallelEnumerable.Range():
ParallelEnumerable.Range(low, high-low+1).Select(fun i -> let a = A.[i] in …)
You can use ParallelEnumerable.Skip and .Take to skip a number of elements, then take a certain number, which essentially allows you to query a range.
This will be A.AsParallel().Skip(low).Take(high-low+1).Select(...
Related
I am building a genetic algorithm that does a time series forecast in the symbolic regression analysis. I’m trying to get the algorithm to find an equation that will match the underlying trend of the data. (predict monthly beer sales)
The idea is to use lisp like expressions, which writes the equation in a tree. This allows for branch swapping in the crossover/mating stage.
5* (5 +5)
Written as:
X = '(mul 5 (add 5 5))'
Y = parser(X)
y = ['mul', 5, ['add', 5, 5]]
I want to know how to create an initial population set where the individuals represent different expressions automatically. Where there “fitness” is related to how well each equation matches the underlying trend.
For example, one individual could be: '(add 100 (mul x (sin (mul x 3))))'
Where x is time in months.
How do I automatically generate expressions for my population? I have no idea how to do this, any help would be very appreciated.
You can easily solve this problem with recursion and a random number generator random() which returns a (pseudo-)random float between 0 and 1. Here is some pseudocode:
randomExp() {
// Choose a function(like mul or add):
func = getRandomFunction() // Just choose one of your functions randomly.
arg1 = ""
rand1 = random()
// Choose the arguments. You may choose other percentages here depending how deep you want it to be and how many 'x' you want to have.
if(rand1 < 0.2)
arg1 = randomExp() // Here add a new expression
else if(rand1 < 0.5)
arg1 = "x"
else
arg1 = randomConstant() // Get a random constant in a predefined range.
// Do the same for the second argument:
arg2 = ""
…
…
// Put everything together and return it:
return "("+func+" "+arg1+" "+arg2+")"
}
You might want to also limit the recursion depth, as this might return you a theoretically infinitely long expression.
In F#, you can say
let x = {1..5}
and you get the expected {1,2,3,4,5}. But if you say
let y = {5..1}
, you get an empty sequence.
I assume this is done to make it easier to return empty sequences if, i.e., the start and stop are variables and you're already past the limit. But what is the best way to concisely define a decreasing sequence?
Right now I'm doing this:
List.rev {1..10000}
...but there's got to be a better way.
You can specify the increment:
let x = { 5 .. -1 .. 1 }
For learning purposes I am trying out running a simulation as a sequence with F#. Starting from a sequence of random numbers, map is a straightforward way to generate a sequence of states if the states do not depend on the previous states. Where I run into a problem is when I try to do something like:
State(i+1) = F (State(i), random number)
I managed to get something working by using unfold, passing in the random generator along the lines of
let unfold (day:State,rnd:Random) =
let rand = rnd.NextDouble()
let nextDay = NextState day rand
Some (nextDay, (nextDay, rnd))
However, at least to my inexperienced eyes, something about passing around the Random instance seems fishy. Is there a way to achieve something similar but passing in a sequence of random numbers, rather than the generator?
I think your hunch about passing around a Random instance as being fishy is fair: when mutable state is useful it's a good idea to isolate it, so that you benifit from purity as much as possible.
We can isolate the state here by creating a sequence which yields a different set of random numbers upon each iteration
open System
let rndSeq =
seq {
//note that by putting rnd inside seq expression here, we ensure that each iteration of the sequence
//yields a different sequnce of random numbers
let rnd = new Random()
while true do yield rnd.NextDouble()
}
then, you can use Seq.scan to iterate the random sequence by mapping elements using a function which is informed by the previous element which was mapped.
let runSimulation inputSeq initialState =
inputSeq
|> Seq.scan
(fun (previousState:State) (inputElement:float) -> NextState previousState inputElement)
initialState
runSimulation rndSeq initialState //run the simulation using a random sequence of doubles greater than or equal to 0.0 and less than 1
You can see as an added bonus here that your simulated input and simulation implementation are no longer bound together, you can run your simulation using any input sequence.
I'd agree with BrokenGlass that using a global Random instance feels allright in this case. This is a reasonably localized use of mutable state, so it shouldn't be confusing.
As an alternative to unfold, you can consider writing the computation explicitly:
let simulationStates =
let rnd = new Random()
let rec generate (day:State) = seq {
let rand = rnd.NextDouble()
let nextDay = NextState day rand
yield nextDay
yield! generate nextDay }
generate InitialState
Note that the rnd value is local variable with a scope limited only to the definition of simulationStates. This is quite nice way to keep mutable state separate from the rest of the program.
The version using unfold is probably more succinct; this one may be easier to read, so it depends on your personal style preferences.
Might be against the spirit, but I would just use a global Random instance in this case - alternatively you could define a sequence of random numbers like this:
let randomNumbers =
seq {
let rnd = new Random();
while true do
yield rnd.NextDouble();
}
I need a base converter function for Lua. I need to convert from base 10 to base 2,3,4,5,6,7,8,9,10,11...36 how can i to this?
In the string to number direction, the function tonumber() takes an optional second argument that specifies the base to use, which may range from 2 to 36 with the obvious meaning for digits in bases greater than 10.
In the number to string direction, this can be done slightly more efficiently than Nikolaus's answer by something like this:
local floor,insert = math.floor, table.insert
function basen(n,b)
n = floor(n)
if not b or b == 10 then return tostring(n) end
local digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
local t = {}
local sign = ""
if n < 0 then
sign = "-"
n = -n
end
repeat
local d = (n % b) + 1
n = floor(n / b)
insert(t, 1, digits:sub(d,d))
until n == 0
return sign .. table.concat(t,"")
end
This creates fewer garbage strings to collect by using table.concat() instead of repeated calls to the string concatenation operator ... Although it makes little practical difference for strings this small, this idiom should be learned because otherwise building a buffer in a loop with the concatenation operator will actually tend to O(n2) performance while table.concat() has been designed to do substantially better.
There is an unanswered question as to whether it is more efficient to push the digits on a stack in the table t with calls to table.insert(t,1,digit), or to append them to the end with t[#t+1]=digit, followed by a call to string.reverse() to put the digits in the right order. I'll leave the benchmarking to the student. Note that although the code I pasted here does run and appears to get correct answers, there may other opportunities to tune it further.
For example, the common case of base 10 is culled off and handled with the built in tostring() function. But similar culls can be done for bases 8 and 16 which have conversion specifiers for string.format() ("%o" and "%x", respectively).
Also, neither Nikolaus's solution nor mine handle non-integers particularly well. I emphasize that here by forcing the value n to an integer with math.floor() at the beginning.
Correctly converting a general floating point value to any base (even base 10) is fraught with subtleties, which I leave as an exercise to the reader.
you can use a loop to convert an integer into a string containting the required base. for bases below 10 use the following code, if you need a base larger than that you need to add a line that mapps the result of x % base to a character (usign an array for example)
x = 1234
r = ""
base = 8
while x > 0 do
r = "" .. (x % base ) .. r
x = math.floor(x / base)
end
print( r );
I have pieces of code like this in a project and I realize it's not
written in a functional way:
let data = Array.zeroCreate(3 + (int)firmwareVersions.Count * 27)
data.[0] <- 0x09uy //drcode
data.[1..2] <- firmwareVersionBytes //Number of firmware versions
let mutable index = 0
let loops = firmwareVersions.Count - 1
for i = 0 to loops do
let nameBytes = ASCIIEncoding.ASCII.GetBytes(firmwareVersions.[i].Name)
let timestampBytes = this.getTimeStampBytes firmwareVersions.[i].Timestamp
let sizeBytes = BitConverter.GetBytes(firmwareVersions.[i].Size) |> Array.rev
data.[index + 3 .. index + 10] <- nameBytes
data.[index + 11 .. index + 24] <- timestampBytes
data.[index + 25 .. index + 28] <- sizeBytes
data.[index + 29] <- firmwareVersions.[i].Status
index <- index + 27
firmwareVersions is a List which is part of a csharp library.
It has (and should not have) any knowledge of how it will be converted into
an array of bytes. I realize the code above is very non-functional, so I tried
changing it like this:
let headerData = Array.zeroCreate(3)
headerData.[0] <- 0x09uy
headerData.[1..2] <- firmwareVersionBytes
let getFirmwareVersionBytes (firmware : FirmwareVersion) =
let nameBytes = ASCIIEncoding.ASCII.GetBytes(firmware.Name)
let timestampBytes = this.getTimeStampBytes firmware.Timestamp
let sizeBytes = BitConverter.GetBytes(firmware.Size) |> Array.rev
Array.concat [nameBytes; timestampBytes; sizeBytes]
let data =
firmwareVersions.ToArray()
|> Array.map (fun f -> getFirmwareVersionBytes f)
|> Array.reduce (fun acc b -> Array.concat [acc; b])
let fullData = Array.concat [headerData;data]
So now I'm wondering if this is a better (more functional) way
to write the code. If so... why and what improvements should I make,
if not, why not and what should I do instead?
Suggestions, feedback, remarks?
Thank you
Update
Just wanted to add some more information.
This is part of some library that handles the data for a binary communication
protocol. The only upside I see of the first version of the code is that
people implementing the protocol in a different language (which is the case
in our situation as well) might get a better idea of how many bytes every
part takes up and where exactly they are located in the byte stream... just a remark.
(As not everybody understand english, but all our partners can read code)
I'd be inclined to inline everything because the whole program becomes so much shorter:
let fullData =
[|yield! [0x09uy; firmwareVersionBytes; firmwareVersionBytes]
for firmware in firmwareVersions do
yield! ASCIIEncoding.ASCII.GetBytes(firmware.Name)
yield! this.getTimeStampBytes firmware.Timestamp
yield! BitConverter.GetBytes(firmware.Size) |> Array.rev|]
If you want to convey the positions of the bytes, I'd put them in comments at the end of each line.
I like your first version better because the indexing gives a better picture of the offsets, which are an important piece of the problem (I assume). The imperative code features the byte offsets prominently, which might be important if your partners can't/don't read the documentation. The functional code emphasises sticking together structures, which would be OK if the byte offsets are not important enough to be mentioned in the documentation either.
Indexing is normally accidental complexity, in which case it should be avoided. For example, your first version's loop could be for firmwareVersion in firmwareVersion instead of for i = 0 to loops.
Also, like Brian says, using constants for the offsets would make the imperative version even more readable.
How often does the code run?
The advantage of 'array concatenation' is that it does make it easier to 'see' the logical portions. The disadvantage is that it creates a lot of garbage (allocating temporary arrays) and may also be slower if used in a tight loop.
Also, I think perhaps your "Array.reduce(...)" can just be "Array.concat".
Overall I prefer the first way (just create one huge array), though I would factor it differently to make the logic more apparent (e.g. have a named constant HEADER_SIZE, etc.).
While we're at it, I'd probably add some asserts to ensure that e.g. nameBytes has the expected length.