Calculate average from sources that sends data at different time. - java

In my current project, I am going to write a function of calculating average Temperature.
A notatable point of this function is that it receives data from many temperature sources at different time. Could you advise me "How can I write a function with such a behavior?"
For instance, following function receives tempSensorData from many temperature Sensors, which sends temperature data at different time. I need to write a logic of calculating average temperature.
public void calculateRoomAvgTemp(TempStruct tempSensorData) {
// Write logic of calculating Average Temperature.
}

Why don't you just keep a running average? Assuming that your method gets called each time a temperature reading is taken, you can do the following:
private final List<Double> temps = Collections
.synchronizedList(new ArrayList<Double>());
private double currentAverage = 0d;
public void calculateRoomAvgTemp(TempStruct tempSensorData) {
synchronized (this.temps) {
this.temps.add(tempSensorData.temp);
this.currentAverage = 0d;
for (Double temp : this.temps) {
this.currentAverage += temp;
}
this.currentAverage /= this.temps.size();
}
}

can you store past temperatures in a separate field in the class? I noticed that your method is void, therefore doesn't return anything. I'm going to assume you want to store the average in the separate field. Example:
public class TempCalculator {
private double totalTemp = 0;
private int sensors = 0;
private double averageTemp = 0;
public void calculateRoomAvgTemp(TempStruct tempSensorData) {
totalTemp += tempSensorData.getTemp(); // Assuming getTemp() exists
sensors += 1;
averageTemp = totalTemp / sensors;
}
public double getAvgTemp() {
return averageTemp;
}
}
Of course, this can be done with a list if you want to store temperatures used and shaped to your needs. Hope this helps.

one way I could think of - insert values as you receive them into an ArrayList. If you need to calculate the average temperature after each data point that you receive, run through a for loop and average out the data points in the ArrayList to get the required value. One could look into using memoization to avoid running through the loop for all values.
Another option would be to use apache commons math whereby you can use the descriptive statistics option (using a rolling array) to get the mean (average).
I am assuming your code is single threaded. If multithreaded, you could use a thread safe vector (or add locks/synchronization on your own).
Hope this helps.

To calculate the average without keeping all historic values in memory (or a database), use a "moving average". This mathematical tool can give you the new average from the last one plus the current value.

You can create one thread which will calculate the temperature and many which will measure it values from different places. When some measurement is done the thread pushes the result into e.g. LinkedBlockingQueue. It's important to synchronize this operation because many threads might try to push results at the same time. The thread which calculate average temperature would run in a loop, pop new result from the queue, recalculate the temperature and then once again try to pop another result. As far as the queue will be empty the thread would be blocked on reading from it. In this way you would have an asynchronous communication between threads and the average temperature would be recalculated immediately after the measurements are done.

Related

Minimization of number of itererations by adjusting input parameters in Java

I was inspired by this question XOR Neural Network in Java
Briefly, a XOR neural network is trained and the number of iterations required to complete the training depends on seven parameters (alpha, gamma3_min_cutoff, gamma3_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff, gamma4_min_cutoff, gamma4_max_cutoff). I would like to minimize number of iterations required for training by tweaking these parameters.
So, I want to rewrite program from
private static double alpha=0.1, g3min=0.2, g3max=0.8;
int iteration= 0;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( "iterations: " + iteration)
to
for (double alpha = 0.01; alpha < 10; alpha+=0.01){
for (double g3min = 0.01; g3min < 0.4; g3min += 0.01){
//Add five more loops to optimize other parameters
int iteration = 1;
loop {
do_something;
iteration++;
if (error < threshold){break}
}
System.out.println( inputs );
//number of iterations, alpha, cutoffs,etc
//Close five more loops here
}
}
But this brute forcing method is not going to be efficient. Given 7 parameters and hundreds of iterations for each calculation even with 10 points for each parameter translates in billions of operations. Nonlinear fit should do, but those typically require partial derivatives which I wouldn't have in this case.
Is there a Java package for this sort of optimizations?
Thank you in advance,
Stepan
You have some alternatives - depending on the equations that govern the error parameter.
Pick a point in parameter space and use an iterative process to walk towards a minimum. Essentially, add a delta to each parameter and pick whichever reduces the error by the most - rince - repeat.
Pick each pareameter and perform a binary-chop search between its limits to find it's minimum. Will only work if the parameter's effect is linear.
Solve the system using some form of Operations-Research technique to track down a minimum.

Lost on how to find the largest price below the target value from a given menu

I am trying to create a method called selectFood that takes the amount of money I have as a parameter, outputs the selections on the screen and returns the percentage tip I will be leaving rounded to one decimal place.
I have the possible costs without tip done through recursion but I need to compare them and find the larger one. Please help
public static void selectFood(double money){
/*String[]menu={"Bandera Pizza Bread","Boston's Pizza Bread","Garlic Twist Bread","Single Order",
"Sun-Dried Tomato Bruschetta","Three Cheese Toast","Double Order wings","Starter Size wings",
"Cactus Nachos","Baked Ravioli Bites","Southwest Quesadilla"};
*/
double[]itemCost={6.49,5.35,7.49,5.35,6.99,6.35,16.49,8.99,10.29,8.49,9.25};
possibilities(itemCost.length,"",itemCost,money);
//selectFood(n,itemCost,0);
}
public static void possibilities(int length,String sofar,double[]itemCost,double money){
if(length==0){
//selectFood(sofar,itemCost,money,0);
float totCost=0;
double target=money/1.15;
double minTip=money-target;
char[]sofarList=sofar.toCharArray();
for(int i=0;i<sofarList.length;i++){
if(sofarList[i]=='1'){
totCost+=itemCost[i];
}
}
if(totCost<target){
System.out.println(totCost);
}
}
else{
possibilities(length-1,sofar+"0",itemCost,money);
possibilities(length-1,sofar+"1",itemCost,money);
}
}
Right now I get back
0.0
8.49
6.35
6.99
5.35
7.49
5.35
6.49
To find the largest value below the target value, you need a variable to hold the current maximum in each iteration you are making thru recursion.
I changed the logic of your program to keep track of the current maximum value
public static void possibilities(int length,String sofar,double[]itemCost,double money){
if(length==0){
//selectFood(sofar,itemCost,money,0);
float totCost=0;
double target=money/1.15;
double minTip=money-target;
char[]sofarList=sofar.toCharArray();
for(int i=0;i<sofarList.length;i++){
if(sofarList[i]=='1'){
totCost+=itemCost[i];
}
}
if(totCost<target && totCost>max){
max = totCost;
System.out.println(totCost);
for(int i=0;i<sofarList.length;i++){
System.out.print(sofarList[i]);
}
System.out.println("\n");
}
}
else{
possibilities(length-1,sofar+"0",itemCost,money);
possibilities(length-1,sofar+"1",itemCost,money);
}
}
and you need to declare the variable max as static inside your class
static double max=0;
I added print statement to show the maximum value chosen in each feasible iteration.
After the end of all iterations the maximum value is stored in the max variable and to keep track of the menu list we need to add one more static variable as given below
static String menulist=null;
and we need to assign the value inside the method possibilities
if(totCost<target && totCost>max){
max = totCost;
menulist = sofarList;
}
The trouble you probably have with your method (besides it being relatively hard to understand) is, that your method is not actually computing a value (well... not returning any at least), but it is printing something to System.out. Generally, your methods should either compute something or alter state (e.g., perform I/O), but not both.
A simple fix would be to store totCost in an instance variable instead of printing it. That is, you can change your lines:
if(totCost < target){
System.out.println(totCost);
}
to
if(totCost < target && highestPrice < totCost){
highestPrice = totCost;
}
where highestPrice is an instance variable. Now you can access highestPrice from the selectFood method.
Note that this is a hack rathar than a clean solution! Your code would be much cleaner if your possibilities method would return the value it computes as the regular return value.
Rethink how you would recursivly compute the cost:
You are given a set (in your case, an array) of prices, and a budget.
For each price you can either take the item and pay the price, or you can not take the item and keep the money
If you have only one item in the list, the most expensive combination you can make is either 0, if you cannot afford the item, or the value of the item, if you can.
The last point is your base-case (not considering that you could also have an empty array). So you have for a base case
double possibilities(double[] items, double money){
if (items.length == 1 && items[0] < money / 1.15) return items[0]; else return 0;
A side note here: Don't put magic numbers (e.g., 1.15) in your code. They do not convey any meaning.
Now for the general case where items.length>1: We can either take the first item, or we can not take it. If we do take it, then we will have less money to spend on the remaining items. Also, we can only take it, if we can afford it, i.e., if money>items[0]. With the remaining money and the remaining items we call the method recursivly and take the bigger value.
if(items.length > 1)
if (items[0] < money / 1.15)
double totCostWithItem0 = items[0] + possibilities(/* items[1 to length], money - items[0] */)
double totCostWithoutItem0 = possibilities(/* items[1 to length], money */)
return totCostWithItem0 > totCostWithoutItem0 ? totCostWithItem0 : totCostWithoutItem0;
else // cannot afford it
return possibilities(/* items[1 to length], money */
Sorry for being so sloppy with the code here. Because you are working with arrays, you need to copy items 1 to length in a new array in order to pass it in the recursive call. Also... I am not quite sure what the division by 1.15 is supposed to do, so you may need to adjust the money you are recursively passing.

Simulate counting over N sensors with java

I need to simulate in Java N sensors that send to me an obsvertation at random time. Where an observation contain more value like:
timestamp - temperature - umiditiy - ...
When i receive an observation from anyone (the time of observation is random for all sensor) of the N sensors i need to call a rutine R that refresh a data structure (in common between all sensors) with some counting.
I need to syncronyze the R call, if i call R first time for call R second time i need R first time to finish his work.
All my observation are actually stored in a CSV file, one file for sensor. But i need to simulate a "online streaming".
How i can make that in Java? If i make N threads (one for sensor) that read his CSV file, i can't read the observation in right temporal order over all CSV.
For example, if i have this 2 csv:
Csv1:
18:00 - low - low
19:00 - low - high
Csv2
18:03 - high - low
I need first to refresh my counting with obsvervation at time 18:00 in csv1, then with obsvervation at time 18:0 in csv2 and finally with observation at time 19:00 in csv2.
EDIT1: I have make a test with SynchronousQueue because I need to syncronyze my N thread, my problem is when one thread do something on counting structure other thread can't access to it.
I have find this example:
package threadTest;
import java.util.concurrent.SynchronousQueue;
public class SynchronousQueueTest
{
private SynchronousQueue sq = new SynchronousQueue(true);
class PutThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("PUT");
//sq.put("A");
sq.put("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TakeThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("TAKE");
System.out.println(sq.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
new Thread((new SynchronousQueueTest()).new PutThread()).start();
new Thread((new SynchronousQueueTest()).new TakeThread()).start();
}
}
But i have not the expected result. The output is only this:
PUT
TAKE
But i'm expected 1000 PUT and 1000 TAKE alternate. What is the problem?
Ha. That sounds so much like what I do usually when preparing stock tick data for back test.
Normally you massage the CSV files to be at least internally time ordered. Then you can either read them and combine at beginning - or if you have multiple readers you need to put the data into a PriorityQueue based structure, say, DelayQueue. Have your simulation data structure wrap the actual data and implement Delayed interface so you know how much delay you need. This is all you need from reading side.
From publishing side, use just 1 thread and publish to the time you needed - then schedule the next round with delay like 1ms or so. That's usually enough.
From subscriber side, the subscriber is blind and just take the data as if it's from real.
BTW, if you are really doing back testing or so, you might want to write up your own time service class which can simulate a faster tick of the data.

Echo/delay algorithm just causes noise/static?

There have been other questions and answers on this site suggesting that, to create an echo or delay effect, you need only add one audio sample with a stored audio sample from the past. As such, I have the following Java class:
public class DelayAMod extends AudioMod {
private int delay = 500;
private float decay = 0.1f;
private boolean feedback = false;
private int delaySamples;
private short[] samples;
private int rrPointer;
#Override
public void init() {
this.setDelay(this.delay);
this.samples = new short[44100];
this.rrPointer = 0;
}
public void setDecay(final float decay) {
this.decay = Math.max(0.0f, Math.min(decay, 0.99f));
}
public void setDelay(final int msDelay) {
this.delay = msDelay;
this.delaySamples = 44100 / (1000/this.delay);
System.out.println("Delay samples:"+this.delaySamples);
}
#Override
public short process(short sample) {
System.out.println("Got:"+sample);
if (this.feedback) {
//Delay should feed back into the loop:
sample = (this.samples[this.rrPointer] = this.apply(sample));
} else {
//No feedback - store base data, then add echo:
this.samples[this.rrPointer] = sample;
sample = this.apply(sample);
}
++this.rrPointer;
if (this.rrPointer >= this.samples.length) {
this.rrPointer = 0;
}
System.out.println("Returning:"+sample);
return sample;
}
private short apply(short sample) {
int loc = this.rrPointer - this.delaySamples;
if (loc < 0) {
loc += this.samples.length;
}
System.out.println("Found:"+this.samples[loc]+" at "+loc);
System.out.println("Adding:"+(this.samples[loc] * this.decay));
return (short)Math.max(Short.MIN_VALUE, Math.min(sample + (int)(this.samples[loc] * this.decay), (int)Short.MAX_VALUE));
}
}
It accepts one 16-bit sample at a time from an input stream, finds an earlier sample, and adds them together accordingly. However, the output is just horrible noisy static, especially when the decay is raised to a level that would actually cause any appreciable result. Reducing the decay to 0.01 barely allows the original audio to come through, but there's certainly no echo at that point.
Basic troubleshooting facts:
The audio stream sounds fine if this processing is skipped.
The audio stream sounds fine if decay is 0 (nothing to add).
The stored samples are indeed stored and accessed in the proper order and the proper locations.
The stored samples are being decayed and added to the input samples properly.
All numbers from the call of process() to return sample are precisely what I would expect from this algorithm, and remain so even outside this class.
The problem seems to arise from simply adding signed shorts together, and the resulting waveform is an absolute catastrophe. I've seen this specific method implemented in a variety of places - C#, C++, even on microcontrollers - so why is it failing so hard here?
EDIT: It seems I've been going about this entirely wrong. I don't know if it's FFmpeg/avconv, or some other factor, but I am not working with a normal PCM signal here. Through graphing of the waveform, as well as a failed attempt at a tone generator and the resulting analysis, I have determined that this is some version of differential pulse-code modulation; pitch is determined by change from one sample to the next, and halving the intended "volume" multiplier on a pure sine wave actually lowers the pitch and leaves volume the same. (Messing with the volume multiplier on a non-sine sequence creates the same static as this echo algorithm.) As this and other DSP algorithms are intended to work on linear pulse-code modulation, I'm going to need some way to get the proper audio stream first.
It should definitely work unless you have significant clipping.
For example, this is a text file with two columns. The leftmost column is the 16 bit input. The second column is the sum of the first and a version delayed by 4001 samples. The sample rate is 22KHz.
Each sample in the second column is the result of summing x[k] and x[k-4001] (e.g. y[5000] = x[5000] + x[999] = -13840 + 9181 = -4659) You can clearly hear the echo signal when playing the samples in the second column.
Try this signal with your code and see if you get identical results.

Java method passing/ordered logic inquiry

Let me first make it clear that this is for an assignment. I'm very new to programming so all guidance is greatly appreciated. The program I have to calculate is a parking fee charge for a $2.00 minimum for 3 hrs or less, .50 cents per additional hr, and charge is capped at $10/ per 24 hr period. Program must display most recent customer charge as well as running total. Constants must be initialized, Math.ceil must be used, and method calculateCharges must be used to solve each cust's charge. I get uber errors when I attempt to run this program, and you'll probably laugh when you see it, but where have I erred? I'm not looking for the answer to be handed to me, just looking for the logic behind how to get to the correctly written program. Please help!
package Parking;
import java.util.Scanner;
public class parking
{
private static final double THREE_HOURS = 2.00;
private static final double PER_HOUR_COST = .50;
private static final double WHOLE_DAY_COST = 10.00;
public static void main (String [] args)
{
double hoursParked = 0;
double cumulativeCharges = 0;
double storage1 = 0;
double storage2 = 0;
Scanner input = new Scanner(System.in);
System.out.print("\nThis program displays the charge for the most recent customer");
System.out.print(" as well as the running total of yesterday's receipts\n");
do
{ System.out.printf("Enter an number between 1-24 for hours parked in garage or -1 to quit:");
hoursParked = input.nextDouble ();
}
while((hoursParked > 0)&&(hoursParked <= 24)&&(hoursParked != -1));
if( hoursParked <= 3)
System.out.printf("Most recent customer's charge was: %.2f\n" , THREE_HOURS);
storage1 += THREE_HOURS;
if(hoursParked >= 18.01)
System.out.printf("Most recent customer's charge was:%.2f\n" , WHOLE_DAY_COST);
storage2 += WHOLE_DAY_COST;
double result = calculateCharges(hoursParked * PER_HOUR_COST);
System.out.printf("Most recent customer charge was:%.2f\n" , result);
cumulativeCharges = storage1 + storage2;
System.out.printf("Running total of yesterday's receipts is:%.2f\n" , cumulativeCharges);
} // end main
public static double calculateCharges (double hoursParked)
{
Math.ceil(hoursParked);
double total = hoursParked * PER_HOUR_COST;
return total;
} // end method calculateCharges
} // end class parking
In your while condition, the third condition is useless because if the value is positive, that necessarily means it is different than -1.
In your function you want to calculate the cost of parking time but you give as parameter a cost instead of a number of hours when you call your function. Is that normal? With that you will calculate the cost of the cost instead of the cost corresponding to a number of hours.
public static double calculateCharges (double hoursParked)
and
double result = calculateCharges(hoursParked * PER_HOUR_COST);
There's a couple things here.
Your while condition is checked at the end of the do loop, it is what allows you to break after reading hoursParked. Thus, the only way you are going to reach the code outside of the do loop (after the while), is if hoursParked is -1.
Secondly, when you do not have braces for your if conditions, you are only executing the first line after it, aka. the System.out.print's. Therefore, your first if condition will execute (printing the string), then storing 2.00 in storage1. Similarly, the second if condition will execute (printing the string), then storing 10.00 in storage2.
Because hoursParked is always -1, you are passing in (-1 * .5) to calculateCharges. You are not storing the result of Math.ceil() so it effectively does nothing. You are then returning (-.5 * .5) = -.25.
cumulativeCharges is just adding 2 + 10 in every case.
Suggestions - make sure you are encapsulating the code you want to execute inside the do loop, and only break after you have done your calculations on hoursParked.

Categories

Resources