Elm - producing a list of random number changing with time - random

I am trying to make a column of random numbers changing every second, but I get different error messages:
import Random
main = flow down
[ asText (Random.range 0 100 (every second))
, asText (Random.range 0 100 (every second))
]
gives a parse error. What is wrong with my square bracket [?
Parse error at (line 5, column 1):
unexpected '['
expecting newline, spaces or end of input
Indent Maybe?
Once I indent, the example does compile but I just get <signal> instead of the actual number
main = flow down
[ asText (Random.range 0 100 (every second))
, asText (Random.range 0 100 (every second))
]
lift for signals?
Finally when I tried to use lift it gives me other confusion
main = flow down
[ lift asText (Random.range 0 100 (every second))
, lift asText (Random.range 0 100 (every second))
]
The error message is that I have the wrong type for lift.
Type error on line 5, column 5 to 9:
lift
Expected Type: Signal Element
Actual Type: Element
No flow down just a list
If I forget flow down it still doesn't cooperate:
main = lift asText
[ (Random.range 0 100 (every second))
, (Random.range 0 100 (every second))
]
I get an error message that _List was expected:
Type error between lines 5 and 7:
[Random.range 0 100 (every second),
Random.range 0 100 (every second)]
Expected Type: _List
Actual Type: Signal
?
Am I using Random.range correctly? I have not changed it from the original example:
http://elm-lang.org/edit/examples/Reactive/Randomize.elm
How do I get it to cooprate with lift and flow down ?

Here's an answer that works with 0.15 [EDIT: and 0.16], currently the latest version of Elm. Since Joe's answer was written, the Random library has been overhauled completely to use a pure random number generator. The pseudorandom numbers are deterministic: every run is always the same, unless you change the initial seed.
We start with imports: boring but necessary, and then define some constants using the Random library.
import Graphics.Element exposing (flow, down, show, Element)
import Time exposing (fps)
import Random
gen = Random.int 0 100
gen2 = Random.pair gen gen
seed0 = Random.initialSeed 42
Next we define a state type, containing the random seed and the numbers to display. I assumed we want two; for a list of constant length, use Random.list n gen. We also define an initial state using the record constructor syntax (and two "random" numbers).
type alias State = {seed : Random.Seed, first : Int, second : Int}
state0 = State seed0 36 89
Now we define a step function to be run once a second. Here we peel off two random numbers and store them, along with the new seed. Notice that we use a new seed each time, chained one to the next.
step : a -> State -> State
step _ state =
let
((first, second), seed') = Random.generate gen2 state.seed
in
State seed' first second
Now we use foldp to introduce state, to actually run that step function.
state : Signal State
state = Signal.foldp step state0 (fps 1)
We define a pure render function. No signals here.
render : State -> Element
render state =
flow down [show state.first, show state.second]
And finally we map (formerly lift) the render function on to the state.
main = Signal.map render state
If you concatenate the gray boxes and remove the interstitial comments, you will get a working Elm 0.15 program. But be advised that it appears to be CPU-intensive.

A couple things are going on here:
Just as you expected, in the first part you have an indentation problem that the compiler doesn't like.
The next example, works because the two things in the list are in fact signals. But, that is not what you wanted. Instead, you want to print out the symbols.
Here is a simple example lifting Random.range:
import Random
main = asText <~ (Random.range 0 10 (every second))
This will display a value between 0 and 1 every second. This has to do with the way lift works. Its type is (a -> b) -> Signal a -> Signal b. Everytime the signal of the second argument changes, it runs the specified function with the value.
So, the compilation error on the third thing ou are trying is complaining that the function flow is expecting the contents of your list to be Element but they are actually Signal Element.
The last thing you have there doesn't work because lift is expecting a Signal as its second argument but you are giving it a [Signal] instead.
You really want something like this:
import Random
main = lift2 randomcolumn (Random.range 0 100 (every second)) (Random.range 0 100 (every second))
randomcolumn x y = flow down [asText x,
asText y]
http://share-elm.com/sprout/53d28d73e4b07afa6f983534
Hope this helps!

Related

Count the maximum number of condition A within condition B, for a specific lookback

I have a piece of code that counts the number of condition A and it resets to 0 when condition B happens.
For example, each time the price crossover the sma(close,14) (this is condition A), the counter increases. Starts at 0, and counts.
But then, when the price crossover the sma(close, 50) (this is condition B), the counter goes back to 0.
When plotting this oscillator, the results shows a line that goes from 0 to count A and then resets when condition B happens.
What I am trying to do is to count the maximum number of condition A within a specific lookback range.
For example, with the last 250 bars, the first wave had 5 times condition A, the second wave had 13 times condition A and the third wave had 2 times the condition A.
I am trying to count the max number of crosses within each wave for the lookback period. In this example, 13 times.
I tried with counters, different sums combination, and ended up trying with arrays but I can't seem to make it happen with the arrays.
I do think there is a way if i could store the counts of each wave into an array, and create new arrays for each new wave within the lookback, but I'm having a hard time to code it.
Any help greatly appreciated!
sma14 = sma(close,14)
sma50 = sma(close,50)
condition_A = crossover(close,sma14)
condition_B = crossover(close,sma50)
if condition_B
counter := 0
if condition_A
counter := counter + 1
if condition_A and condition_B
counter := 0
For i=0 to i_lookback
Count if?

How many times does a zero occur on an odometer

I am solving how many times a zero occus on an odometer. I count +1 everytime I see a zero.
10 -> +1
100-> +2 because in 100 I see 2 zero's
10004 -> +3 because I see 3 zero's
So I get,
1 - 100 -> +11
1 - 500 -> +91
1 - 501 -> +92
0 - 4294967295-> +3825876150
I used rubydoctest for it. I am not doing anything with begin_number yet. Can anyone explain how to calculate it without a brute force method?
I did many attempts. They go well for numbers like 10, 1000, 10.000, 100.000.000, but not for numbers like 522, 2280. If I run the rubydoctest, it will fail on # >> algorithm_count_zero(1, 500)
# doctest: algorithm_count_zero(begin_number, end_number)
# >> algorithm_count_zero(1, 10)
# => 1
# >> algorithm_count_zero(1, 1000)
# => 192
# >> algorithm_count_zero(1, 10000000)
# => 5888896
# >> algorithm_count_zero(1, 500)
# => 91
# >> algorithm_count_zero(0, 4294967295)
# => 3825876150
def algorithm_count_zero(begin_number, end_number)
power = Math::log10(end_number) - 1
if end_number < 100
return end_number/10
else
end_number > 100
count = (9*(power)-1)*10**power+1
end
answer = ((((count / 9)+power)).floor) + 1
end
end_number = 20000
begin_number = 10000
puts "Algorithm #{algorithm_count_zero(begin_number, end_number)}"
As noticed in a comment, this is a duplicate to another question, where the solution gives you correct guidelines.
However, if you want to test your own solution for correctness, i'll put in here a one-liner in the parallel array processing language Dyalog APL (which i btw think everyone modelling mathemathics and numbers should use).
Using tryapl.org you'll be able to get a correct answer for any integer value as argument. Tryapl is a web page with a backend that executes simple APL code statements ("one-liners", which are very typical to the APL language and it's extremely compact code).
The APL one-liner is here:
{+/(c×1+d|⍵)+d×(-c←0=⌊(a|⍵)÷d←a×+0.1)+⌊⍵÷a←10*⌽⍳⌈10⍟⍵} 142857
Copy that and paste it into the edit row at tryapl.org, and press enter - you will quickly see an integer, which is the answer to your problem. In the code row above, you can see the argument rightmost; it is 142857 this time but you can change it to any integer.
As you have pasted the one-liner once, and executed it with Enter once, the easiest way to get it back for editing is to press [Up arrow]. This returns the most recently entered statement; then you can edit the number sitting rightmost (after the curly brace) and press Enter again to get the answer for a different argument.
Pasting teh code row above will return 66765 - that many zeroes exist for 142857.
If you paste this 2 characters shorter row below, you will see the individual components of the result - the sum of these components make up the final result. You will be able to see a pattern, which possibly makes it easier to understand what happens.
Try for example
{(c×1+d|⍵)+d×(-c←0=⌊(a|⍵)÷d←a×+0.1)+⌊⍵÷a←10*⌽⍳⌈10⍟⍵} 1428579376
0 100000000 140000000 142000000 142800000 142850000 142857000 142857900 142857930 142857937
... and see how the intermediate results contain segments of the argument 1428579376, starting from left! There are as many intermediate results as there are numbers in the argument (10 this time).
The result for 1428579376 will be 1239080767, ie. the sum of the 10 numbers above. This many zeroes appear in all numbers between 1 and 1428579376 :-).
Consider each odometer position separately. The position x places from the far right changes once every 10^x times. By looking at the numbers to its right, you know how long it will be until it next changes. It will then hold each value for 10^x times before changing, until it reaches the end of the range you are considering, when it will hold its value at that time for some number of times that you can work out given the value at the very end of the range.
Now you have a sequence of the form x...0123456789012...y where you know the length and you know the values of x and y. One way to count the number of 0s (or any other digit) within this sequence is to clip off the prefix from x.. to just before the first 0, and clip off the suffix from just after the last 9 to y. Look for 0s n in this suffix, and measure the length of the long sequence from prefix to suffix. This will be of a length divisible by 10, and will contain each digit the same number of times.
Based on this you should be able to work out, for each position, how often within the range it will assume each of its 10 possible values. By summing up the values for 0 from each of the odometer positions you get the answer you want.

PID controller - intuition for when error=0

I have simulated a PID controller with an input parameter that affects the output, and set Kp=0.2, Kp=0.5, Kd=0 which seemed to work best the values I expect in reality.
However one thing I could not figure out is the intuition of how the controller starts when the error is 0. I, for example, my target is 2, the output is 2, and the input variable is, say, 4 - the controller would setthe next input to be 0 - although 4 is a perfect value.
Is there some way that is theoretically sound to make the first steps of the algorithm take into account some "initial guess" and not go way off at the beginning of the process?
The only state in a PID controller is the current value of the integral, and it can be helpful to set this up to a nonzero value if you have some additional information about the likely steady state error.
In practice, you may simply want to use the PID controller a few times and see what value the integral typically takes, and use that as the starting value.
If you have some additional information, such as knowing that the correct output is y for an input of x, then you can invert the formula to find the correct integral as follows:
output = input * Kp + Integral * Ki
=> y = x * Kp + Integral * Ki
=> Integral = ( y - x * Kp) / Ki

How can I get a random value in a range determined by a signal?

First some code:
import Random
import Window
writeRandom x = lift asText (Random.range 0 x <| every second)
upperLimit = 300
-- upperLimit = Window.width -- How can i use this instead?
main = writeRandom upperLimit
Ultimately I'm trying to get random points on the screen, but I can't figure out how to pass Window.height and Window.width to Random.range. I don't think I can 'lift' Random.range, since it already returns a signal. If I try I get a type error:
Type Error: 'main' must have type Element or (Signal Element).
Instead 'main' has type:
Signal (Signal Element)
And I'm not sure that the opposite of lift (lower?) exists, or even makes sense.
Thanks
You are correct in supposing that an opposite of lower doesn't make sense.
In this particular case, the builtin Random library is builtin because it's a wrapper around a native JavaScript call. This is the reason for the Signal return type, to keep the code pure. And even then, it's not completely well-behaved.
To get the kind of random range you want, you'll need a different random number generator. There is a community library that was published only a few days ago, that'll probably answer your needs. You can check it out of GitHub yourself, or use the elm-get tool.
Your code would become something like (untested!):
import Window
import Generator
import Generator.Standard as GStd
randomSeed = 12346789
writeRandom : Signal Int -> Signal Element
writeRandom x =
let update high (_, gen) = Generator.int32Range (0,high) gen
start = (0, GStd.generator randomSeed)
input = sampleOn (every second) x
result = fst <~ foldp update start input
in lift asText result
upperLimit = Window.width
main = writeRandom upperLimit
In writeRandom, you use foldp to keep the latest random-number generator. In update you use this to get a new random number and a new generator for the next time. The input of x is updated every second by using sampleOn (every second). The fst <~ part is to remove the random number generator, since you only want the random number.

Generate infinite stream of unique numbers between 0 and 1

Came across this question previously on an interview. The requirements are to write a function that
Generates a number between 0..1
Never returns the same number
Can scale (called every few milliseconds and continuously for years)
Can use only 1mb of heap memory
Does not need to return as a decimal, can render directly to stdout
My idea was hacky at best which involved manipulating a string of the "0.1" then "0.11" then "0.12" etc. Since the requirements did not mention it had to be uniformly distributed, it does not need to be random. Another idea is generate a timestamp of the form yyyyMMddhhmmssSSS (where SSS is msec) then convert that to a string and prefix it with "0." . This way the values will always be unique.
It's a pretty open ended question and I'm curious how other people would tackle it.
Pseudo code that can do what you except guarantee no repeats.
Take your 1 MB allocation.
Randomly set every byte.
Echo to stdout as "0.<bytes as integer string>" (will be very long)
Go to #2
Your "Never returns the same number" is not guaranteed but it is extremely unlikely (1 in 2^8192) assuming a good implementation of Random.
Allocate about a million characters and set them initially to all 0.
Then each call to the function simply increments the number and returns it, something like:
# Gives you your 1MB heap space.
num = new digit/byte/char/whatever[about a million]
# Initialise all digits to zero (1-based arrays).
def init():
for posn ranges from 1 to size(num):
set num[posn] to 0
# Print next value.
def printNext():
# Carry-based add-1-to-number.
# Last non-zero digit stored for truncated output.
set carry to 1
set posn to size(num)
set lastposn to posn
# Keep going until no more carry or out of digits.
while posn is greater than 0 and carry is 1:
# Detect carry and continue, or increment and stop.
if num[posn] is '9':
set num[posn] to '0'
set lastposn to posn minus 1
else:
set num[posn] to num[posn] + 1
set carry to 0
set posn to posn minus one
# Carry set after all digits means you've exhausted all numbers.
if carry is 1:
exit badly
# Output the number.
output "0."
for posn ranges from 1 to lastposn
output num[posn]
The use of lastposn prevents the output of trailing zeros. If you don't care about that, you can remove every line with lastposn in it and run the output loop from 1 to size(num) instead.
Calling this every millisecond will give you about well over 10some--big-number-resulting-in-a-runtime-older-than-the-age-of-the-universe years of run time.
I wouldn't go with your time-based solution because the time may change - think daylight savings or summer time and people adjusting clocks due to drift.
Here's some actual Python code which demonstrates it:
import sys
num = "00000"
def printNext():
global num
carry = 1
posn = len(num) - 1
lastposn = posn
while posn >= 0 and carry == 1:
if num[posn:posn+1] == '9':
num = num[:posn] + '0' + num[posn+1:]
lastposn = posn - 1
else:
num = num[:posn] + chr(ord(num[posn:posn+1]) + 1) + num[posn+1:]
carry = 0
posn = posn - 1
if carry == 1:
print "URK!"
sys.exit(0)
s = "0."
for posn in range (0,lastposn+1):
s = s + num[posn:posn+1];
print s
for i in range (0,15):
printNext()
And the output:
0.00001
0.00002
0.00003
0.00004
0.00005
0.00006
0.00007
0.00008
0.00009
0.0001
0.00011
0.00012
0.00013
0.00014
0.00015
Your method would eventually use more than 1mb of heap memory. Every way you represent numbers, if you are constrained by 1mb of heap then there is only a finite number of values. I would take the maximum ammount of memory possible, and increment the least significant bit by one on each call. That would ensure running as longer as possible before returning a repeted number.
Yes, because there is no random requirement, you have a lot of flexibility.
The idea here I think is very close to that of enumerating all strings over the regular expression [0-9]* with a couple modifications:
the real string starts with the sequence 0.
you cannot end with a 0
So how would you enumerate? One idea is
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 0.11 0.12 0.13 0.14 0.15 ... 0.19 0.21 0.22 ... 0.29 0.31 ... 0.99 0.101 0.102 ...
The only state you need here is an integer I think. Just be clever in skipping those zeros at the end (not difficult really). 1 MB of memory should be fine. It stores a massive massive integer, so I think you would be good here.
(It is different from yours because I generate all one character strings, then all two character strings, then all three character strings, ... so I believe there is no need for state other than the last number generated.)
Then again I may be wrong; I haven't tried this.
ADDENDUM
Okay I will try it. Here is the generator in Ruby
i = 0
while true
puts "0.#{i}" if i % 10 != 0
i += 1
end
Looks okay to me....
If you are programming in C, the nextafter() family of functions are Posix-compatible functions useful for producing the next double after or before any given value. This will give you about 2^64 different values to output, if you output both positive and negative values.
If you are required to print out the values, use the %a or %A format for exact representation. From the printf(3) man page: "For 'a' conversion, the double argument is converted to hexadecimal notation (using the letters abcdef) in the style [-]0xh.hhhhp±d..." "The default precision suffices for an exact representation of the value if an exact representation in base 2 exists..."
If you want to generate random numbers rather than sequentially ascending ones, perhaps do a google search for 64-bit KISS RNG. Implementations in Java, C, Ada, Fortran, et al are available on the web. The period of 64-bit KISS RNG itself is ~ 2^250, but there are not that many 64-bit double-precision numbers, so some numbers will re-appear within 2^64 outputs, but with different neighbor values. On some systems, long doubles have 128-bit values; on others, only 80 or 96. Using long doubles, you could accordingly increase the number of different values output by combining two randoms into each output.
It may be that the point of this question in an interview is to figure out if you can recognize a silly spec when you see it.

Resources