Implementing an IObservable to compute digits of Pi - asynchronous

This is an academic exercise, I'm new to Reactive Extensions and trying to get my head around the technology. I set myself a goal of making an IObservable that returns successive digits of Pi (I happen to be really interested in Pi right at the moment for unrelated reasons). Reactive Extensions contains operators for making observables, the guidance they give is that you should "almost never need to create your own IObsevable". But I can't see how I can do this with the ready-made operators and methods. Let me elucidate a bit more.
I was planning to use an algorithm that would involve the expansion of a Taylor series for Arctan. To get the next digit of Pi, I'd expand a few more terms in the series.
So I need the series expansion going on asynchronously, occasionally throwing out the next computed digit to the IObserver. I obviosly don't want to restart the computation from scratch for each new digit.
Is there a way to implement this behaviour using RX's built-in operators, or am I going to have to code an IObservable from scratch? What strategy suggests itself?

For something like this, the simplest method would be to use a Subject. Subject is both an IObservable and IObserver, which sounds a bit strange but it allows you to use them like this:
class PiCalculator
{
private readonly Subject<int> resultStream = new Subject<int>();
public IObservable<int> ResultStream
{
get { return resultStream; }
}
public void Start()
{
// Whatever the algorithm actually is
for (int i = 0; i < 1000; i++)
{
resultStream.OnNext(i);
}
}
}
So inside your algorithm, you just call OnNext on the subject whenever you want to produce the next value.
Then to use it, you just need something like:
var piCalculator = new PiCalculator();
piCalculator.ResultStream.Subscribe(n => Console.WriteLine((n)));
piCalculator.Start();

Simplest way is to create an Enumerable and then convert it:
IEnumerable<int> Pi()
{
// algorithm here
for (int i = 0; i < 1000; i++)
{
yield return i;
}
}
Usage (for a cold observable, that is every new 'subscription' starts creating Pi from scratch):
var cold = Pi().ToObservable(Scheduler.ThreadPool);
cold.Take(5).Subscribe(Console.WriteLine);
If you want to make it hot (everyone shares the same underlying calculation), you can just do this:
var hot = cold.Publish().RefCount();
Which will start the calculation after the first subscriber, and stop it when they all disconnect. Here's a simple test:
hot.Subscribe(p => Console.WriteLine("hot1: " + p));
Thread.Sleep(5);
hot.Subscribe(p => Console.WriteLine("hot2: " + p));
Which should show hot1 printing only for a little while, then hot2 joining in after a short wait but printing the same numbers. If this was done with cold, the two subscriptions would each start from 0.

Related

Java 7 => Java 8 : for to foreach on a Map with calculation

I begin with Java 8 and i have a migration project. I have read a lot of documentation and tutorial to use foreach or streams but i have a little last problem. I don't find the answer, just tutorial easy example.
I'm trying to transform this loop :
for ( Map.Entry<Neuron, Double> entry: this.entries.entrySet() ) {
value += entry.getKey().getExitValue() * entry.getValue();
}
This solution doesn't match and i know why (anonymous class => final/local var)
this.entries.forEach( (neuron, weight) -> {
value += neuron.getExitValue() * weight;
});
But only with a foreach i don't know how do this simple operation.
I think it's very easy but...
I have try with stream but i have similar problems.
Double sum = entries.entrySet()
.stream()
.forEach( entry-> { ? } );
Thanks you in advance.
As #Holger said in the comments above - in this case it is better to use mapToDoble. However there is still a way to do it using forEach loop. Please note that it is an ugly, dirty trick and it is just for demonstration purposes and it shouldn't be used in production code. As we know only final or effectively final variables can be used with lambda expressions, that's why value += is an illegal expression. Java-8 added a few new classes to java.util.concurrent.atomic one of them is DoubleAdder. You can use it with lambda:
DoubleAdder adder = new DoubleAdder();
stream.forEach(e -> adder.add(e.getKey().getExitValue() * e.getValue()));
System.out.println(adder.sum());
I don't see any cases when this should be used instead of mapToDouble
I introduced a list to stall the values and then do calculation with list.
final List<BigDecimal> valuesList = new ArrayList<>();
otherList.stream().forEach(val-> valuesList.add(map.get(val)));
final BigDecimal lastValue = valuesList.stream().filter(Objects::nonNull).reduce(BigDecimal.ZERO,BigDecimal::add);

How should I Parse and Delay a Hot Reactive Extensions IConnectableObservable<T> stream?

I am unable to implement this, so unfortunately I have no Rx code to show where I am at. I will explain what i would like t do, and hopefully someone out there with enough expertise might be able to guide me in the right direction.
Let us say that I have a collection of List TimeObjects that I pulled from a database. TimeObject has this form.
public class TimeObject
{
public DateTime time{get;set;}
public decimal price{get;set;}
}
What I want to do is produce a Hot IConnectableObservable stream, where each element is separated by a variable time delay.
The variable time delay is equal to the difference between the time of the current and the next TimeObject.
For example, if the stream is this:
s1, s2, s3, ...sN, where each 's' represents an element of TimeObject
Then, the time delay before s2 is pushed out to the stream is (s2.time - s1.time),
the time delay before s3 is pushed out to the stream is (s3.time - s2.time) and so on.
Is this at all possible, and if so, what should my implementation look like?
I have included a for loop that accomplishes the same task using a classical approach.
FireEvent(TimeObject[0]); //Post the first element as an event
for(int _counter = 0; _counter < TimeObject.Count; _counter++)
{
if ( _counter + 1 < TimeObject.Count )
{
TimeObject timeObjectA = TimeObject[_counter];
TimeObject timeObjectB = TimeObject[_counter + 1];
int millisecondsDelay = (timeObjectB.time - timeObjectA.time).Milliseconds;
Thread.Sleep(millisecondsDelay);
FireEvent(timeObjectB); //this posts the latest tick as an event with variable time delay.
}
What I would like is for this to be converted into an Observable stream.
Thanks.
Try this:
var observable =
Observable
.Generate(
1,
x => x < timeObjects.Count,
x => x + 1, x => timeObjects[x],
x => timeObjects[x].time.Subtract(timeObjects[x - 1].time)))
.StartWith(timeObjects[0]);
Now, this is a regular cold observable. You could make it hot by calling .Publish(). Why do you need it hot?
It also requires your list to have at least two elements

Function to generate randomly incrementing number over time

I'm trying to make a fake download count. It should increment randomly over time. Some download-count-like patterns would be nice.
Is this possible without using a database, or storing a counter anywhere?
My idea is to check the number of seconds that have passed since my app was released. Then just throw that into a formula which spits out the fake download count. Users can request to see the download count at any time.
Is there a math function that increments randomly? I could just pass my secondsPassed into there and scale it how I'd like.
Something like this: getDownloadCount(secondsPassed)
Edit: here's an example solution. But it gets worse performance over time.
downloadCount = 0
loop secondsPassed/60 times // Loop one more time for every minute passed
downloadCount += seededRandom(0, 10)
Making a fake download count doesn't sound like a nice thing to do. However in designing secure communication protocols, there are legitimate use cases for monotonically growing functions with some randomness in their values.
I am assuming you have:
A growth model given as a monotonically growing function providing approximate values for the desired function.
Access to a time stamp, which never decreases.
Ability to store a constant random seed along with the function definition.
No way to store any updated data upon the function being queried.
First you decide on a window length, which will control how much randomness will be in the final output. I expect you will want this to be on the order of one hour or a few.
Figure out which window the current time is within. Evaluate the reference function at the start and end of this window. Consider the rectangle given by start and end time of the window as well as min and maximum value given by the reference function. Feed the corners of this rectangle and your constant seed into a PRNG. Use the PRNG to choose a random point within the rectangle. This point will be on the final curve.
Perform the same computation for one of the neighbor windows. Which neighbor window to use depend on whether the first computed point on the curve is to the left or the right of the current time.
Now that you have two points on the curve (which are reproducible and consistent), you will have to iterate the following procedure.
You are given two points on the final curve. Consider the rectangle given by those corners. Feed the corners and your constant seed into a PRNG. Use that PRNG to chose a random point within the rectangle. This point will be on the final curve. Discard one of the outer points, which is no longer needed.
Since the Y-values are restricted to integers, this procedure will eventually terminate once your two points on the curve have identical Y-coordinate, and you will know, that the function has to be constant between those two points.
You could implement a Morris Counter.
It works like this: start off by setting the counter to 1. Each time you want to increase the count (which could be every iteration of some loop or every time an event happens, but does not need to be determined randomly), then you do a random procedure to determine the effect it has on the counter.
It can have possibly no effect, or it can have the effect of raising the order of magnitude of the count. The probability is based on whether or not n successive fair coin flips all turn up heads, where n is the number of bits needed to encode the current counter value in binary. As a result, once the counter has gotten pretty high, it's very hard to make it go even higher (the state of the counter models a phenomenon where by you are already way overestimating the count, so now you need lots of nothing-happens events to compensate, making the count more accurate).
This is used as a cheap way to store an approximate count of a very large collection, but there's no reason why you can't use it as your randomly increasing counter device.
If you want better accuracy, or you want the count outputs to be more "normal" numbers instead of always powers of 2, then you can just create several Morris Counters, and at each step average together the set of current counts across them all.
You are after a sequence which always increases by a random amount, depending on how long you last requested the sequence.
This can be done through a random sequence that is always seeded the same.
Then we iterate through the same sequence each time to get the graph.
We need a function that increments our counter, store the new Time and Count and return the count.
Ideally we would model the increases as a poisson process, but a linear one here will do.
class Counter {
private static int counter = 0;
private static int time = 0;
private static double rate = 5.0;
private Random r;
public Counter(int seed){
counter = 0;
r = new Random(seed);
}
private int poisson(double rate, int diff){
// We're gonna cheat here and sample uniformly
return r.Next(0, (int)Math.Round(rate * diff));
}
public int getNext(int t){
var diff = t - time;
time = t;
if (diff <= 0) return counter;
counter += this.poisson(rate, diff);
return counter;
}
}
void Main()
{
var c = new Counter(1024);
for(var i = 0; i< 10; i++){
Console.WriteLine(String.Format("||{0}\t|{1}\t||",i,c.getNext(i)));
}
}
This outputs (for example):
||t |hit||
||0 |0 ||
||1 |3 ||
||2 |4 ||
||3 |6 ||
||4 |6 ||
||5 |8 ||
||6 |10 ||
||7 |13 ||
||8 |13 ||
||9 |16 ||
For some deterministic function f, (perhaps f(x) = x, or if your fake app is REALLY awesome f(x) = 2^x), and a random function r which outputs random number that's sometimes negative and sometimes positive.
Your graphing function g could be:
g(x) = f(x) + r
EDIT
How about this: https://gamedev.stackexchange.com/questions/26391/is-there-a-family-of-monotonically-non-decreasing-noise-functions
Well it's not "random" but you could use A*(X/B + SIN(X/B)) (scaled by some number) to introduce some noise. You can adjust A and B to change the scale of the result and how often the "noise" cycles.
Really, any periodic function that has a first derivative within some bounds could work.
as quick solution you can use something like this (code in java):
static long f(final int x) {
long r = 0; // initial counter
long n = 36969L; // seed
for (int i = 0; i <= x; i++) {
n = 69069L * n + 1234567L; // generate Ith random number
r += (n & 0xf); // add random number to counter
}
return r;
}
by playing with numbers 36969L and 0xf you can achieve different results
numbers 69069L and 1234567L are from standard LCG
the main idea - create simple random, with the same seed and for every passed x (number of seconds) replay random additions to counter
A good model for random events like downloads is the Poisson distribution. You need to estimate the average number of downloads in a given time period (hour, say) and then invert the Poisson distribution to get the number of downloads in a time period given a uniformly distributed random number. For extra realism you can vary the average according to time of day, time of week, etc. Sample algorithms are available at http://en.m.wikipedia.org/wiki/Poisson_distribution#Generating_Poisson-distributed_random_variables.
Here is a javascript implementation of a "fake" download-counter that appears the same to everyone. This always returns the same results for everyone each time and doesn't require database or files to do that. It also gracefully handles the case where you don't ask for new data at the same time, it will still look natural next time you request a day.
https://jsfiddle.net/Lru1tenL/1/
Counter = {
time:Date.now(),
count:0,
rate:0.45
};
Counter.seed = function(seed, startTime)
{
this.time = startTime,
this.count = 0,
this.prng = new Math.seedrandom(seed);
this.prng.getRandomInt = function(min, max) {
return Math.floor(this() * (max - min)) + min;
};
};
Counter.getNext = function(t){
var diff = t - this.time;
console.log(diff);
if(diff <= 0) return this.count;
this.time = t;
var max = Math.ceil(diff/100 * this.rate);
console.log("max: " + max);
this.count += this.prng.getRandomInt(0,max);
return this.count;
};
var results = [];
var today = Date.now();
Counter.seed("My Random Seed", today);
for (var i = 0; i < 7; i++) {
if(i === 4)
{
results.push(null);
} else {
var future = today + 86400000 * i;
results.push(Counter.getNext(future));
}
}
console.log(results);
var data = {
labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"],
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: results
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myLineChart = new Chart(ctx).Line(data);
Is the javascript. It creates a counter object that increments when requested based on the time of the previous value asked for. The repeatability comes through a thirdparty library "seedrandom" and the chart is drawn using chartjs.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js">
</script>
<body>
<canvas id="myChart" width="600" height="400"></canvas>
</body>
</html>
You can use Unix timestamp. Something like:
Downloads = constant + ( unix time / another constant )
You can vary both constants to get a reasonable number.
P.S: Thats if you want a linear function, otherwise you can do:
Downloads = (unix time) ^ constant
and so on.

Using GraphView Library for functions to display multiple graphs

I'm currently developing an android app for reading out multiple sensor values via Bluetooth and display them in a graph. When I stumbled upon jjoe64's GraphViewLibrary, I knew this would fit my purposes perfectly. But now I'm kind of stuck. Basically, I wrote a little function that would generate and display the values of three sensors in 3 different graphs one under the other. This works just fine when the activity is started first, all three graphs a nicely rendered and displayed. But when I want to update the graphs with different values using the resetData()-method to render the new values in each graph, only the last of the three graphs is updated. Obviously, because it's the last graph generated using this rather simple function. My question is: Is there any other elegant way to use a function like mine for generating and updating all three graphs one after the other? I already tried to set the GraphView variable back to null and different combinations of removing and adding the view. Passing the function a individual GraphView-variable like graphView1, graphView2... does also not work.
Here is the function:
private GraphView graphView;
private GraphViewSeries graphViewSerie;
private Boolean graphExisting = false;
...
public void makeGraphs (float[] valueArray, String heading, int graphId) {
String graphNumber = "graph"+graphId;
int resId = getResources().getIdentifier(graphNumber,"id", getPackageName());
LinearLayout layout = (LinearLayout) findViewById(resId);
int numElements = valueArray.length;
GraphViewData[] data = new GraphViewData[numElements];
for (int c = 0; c<numElements; c++) {
data[c] = new GraphViewData(c+1, valueArray[c]);
Log.i(tag, "GraphView Graph"+graphId+": ["+(c+1)+"] ["+valueArray[c]+"].");
}
if (!graphExisting) {
// init temperature series data
graphView = new LineGraphView(
this // context
, heading // heading
);
graphViewSerie = new GraphViewSeries(data);
graphView.addSeries(graphViewSerie);
((LineGraphView) graphView).setDrawBackground(true);
graphView.getGraphViewStyle().setNumHorizontalLabels(numElements);
graphView.getGraphViewStyle().setNumVerticalLabels(5);
graphView.getGraphViewStyle().setTextSize(10);
layout.addView(graphView);
}
else {
//graphViewSerie = new GraphViewSeries(data);
//graphViewSerie.resetData(data);
graphViewSerie.resetData(new GraphViewData[] {
new GraphViewData(1, 1.2f)
, new GraphViewData(2, 1.4f)
, new GraphViewData(2.5, 1.5f) // another frequency
, new GraphViewData(3, 1.7f)
, new GraphViewData(4, 1.3f)
, new GraphViewData(5, 1.0f)
});
}
And this is the function-call depending on an previously generated array (which is being monitored to be filled with the right values):
makeGraphs(graphData[0], "TempHistory", 1);
makeGraphs(graphData[1], "AirHistory", 2);
makeGraphs(graphData[2], "SensHistory", 3);
graphExisting = true;
Any help and / or any feedback in general is greatly appreciated! Lots of thanks in advance!
EDIT / UPDATE:
Thanks to jjoe64's answer I was able to modify the function to work properly. I was clearly having a mistake in my thinking, since I thought I'd also be changing a GraphViewSeries-object I would handle my function as additional parameter (which I tried before). Of course this does not work. However, with this minor Improvements I managed to make this work using a Graphviewseries Array. To give people struggling with a similar problem an idea of what I had to change, here the quick-and-dirty draft of the solution.
I just changed
private GraphViewSeries graphViewSerie;
to
private GraphViewSeries graphViewSerie[] = new GraphViewSeries[3];
and access the right Series using the already given parameter graphId within the function (if-clause) like this:
int graphIndex = graphId - 1;
graphViewSerie[graphIndex] = new GraphViewSeries(data);
In the else-clause I'm updating the series likewise by calling
graphViewSerie[graphIndex].resetData(data);
So, once again many thanks for your support, jjoe64. I'm sorry I wasn't able to update the question earlier, but I did not find time for it.
of course it is not working correct, because you save always the latest graphseries-object in the member graphViewSerie.
First you have to store the 3 different graphviewseries (maybe via array or map) and then you have to access the correct graphviewseries-object in the else clause.

Is there a version of the removeElement function in Go for the vector package like Java has in its Vector class?

I am porting over some Java code into Google's Go language and I converting all code except I am stuck on just one part after an amazingly smooth port. My Go code looks like this and the section I am talking about is commented out:
func main() {
var puzzleHistory * vector.Vector;
puzzleHistory = vector.New(0);
var puzzle PegPuzzle;
puzzle.InitPegPuzzle(3,2);
puzzleHistory.Push(puzzle);
var copyPuzzle PegPuzzle;
var currentPuzzle PegPuzzle;
currentPuzzle = puzzleHistory.At(0).(PegPuzzle);
isDone := false;
for !isDone {
currentPuzzle = puzzleHistory.At(0).(PegPuzzle);
currentPuzzle.findAllValidMoves();
for i := 0; i < currentPuzzle.validMoves.Len(); i++ {
copyPuzzle.NewPegPuzzle(currentPuzzle.holes, currentPuzzle.movesAlreadyDone);
copyPuzzle.doMove(currentPuzzle.validMoves.At(i).(Move));
// There is no function in Go's Vector that will remove an element like Java's Vector
//puzzleHistory.removeElement(currentPuzzle);
copyPuzzle.findAllValidMoves();
if copyPuzzle.validMoves.Len() != 0 {
puzzleHistory.Push(copyPuzzle);
}
if copyPuzzle.isSolutionPuzzle() {
fmt.Printf("Puzzle Solved");
copyPuzzle.show();
isDone = true;
}
}
}
}
If there is no version available, which I believe there isn't ... does anyone know how I would go about implementing such a thing on my own?
How about Vector.Delete( i ) ?
Right now Go doesn't support generic equality operators. So you'll have to write something that iterates over the vector and removes the correct one.

Resources