I'm currently working on a project where I want to plot some times measured. For this I'm using JFreeChart 1.0.13.
I want to create a Histogram with SimpleHistogramBins and then add data to these bins. Here's the code:
Double min = Collections.min(values);
Double max = Collections.max(values);
Double current = min;
int range = 1000;
double minimalOffset = 0.0000000001;
Double stepWidth = (max-min) / range;
SimpleHistogramDataset dataSet = new SimpleHistogramDataset("");
for (int i = 0; i <= range; i++) {
SimpleHistogramBin bin;
if (i != 0) {
bin = new SimpleHistogramBin(current + minimalOffset, current + stepWidth);
} else {
bin = new SimpleHistogramBin(current, current + stepWidth);
}
dataSet.addBin(bin);
current += stepWidth;
}
for (Double value : values) {
System.out.println(value);
dataSet.addObservation(value);
}
This crashes with Exception in thread "main" java.lang.RuntimeException: No bin. At first I thought this was caused by hitting a gap in the bins, but when I started debugging, the error did not occur. The program ran through and I got a plot. Then I added this:
Thread.sleep(1000);
before
for (Double value : values) {
System.out.println(value);
dataSet.addObservation(value);
}
and again, no error.
This got me thinking that maybe there is some kind of race condition? Does JFreeChart add the bins asynchronously? I would appreciate hints in any direction to why I get this kind of behaviour.
Thanks
If anyone should have the same problem, I found a solution:
Instead of using SimpleHistorgramBin I'm using HistogramBin. This basically reduces my code to a few lines:
HistogramDataset dataSet = new HistogramDataset();
dataSet.setType(HistogramType.FREQUENCY);
dataSet.addSeries("Hibernate", Doubles.toArray(values), 1000);
This approach automatically creates the bins I need and the problem is gone.
Related
I have a program that takes in anywhere from 20,000 to 500,000 velocity vectors and must output these vectors multiplied by some scalar. The program allows the user to set a variable accuracy, which is basically just how many decimal places to truncate to in the calculations. The program is quite slow at the moment, and I discovered that it's not because of multiplying a lot of numbers, it's because of the method I'm using to truncate floating point values.
I've already looked at several solutions on here for truncating decimals, like this one, and they mostly recommend DecimalFormat. This works great for formatting decimals once or twice to print nice user output, but is far too slow for hundreds of thousands of truncations that need to happen in a few seconds.
What is the most efficient way to truncate a floating-point value to n number of places, keeping execution time at utmost priority? I do not care whatsoever about resource usage, convention, or use of external libraries. Just whatever gets the job done the fastest.
EDIT: Sorry, I guess I should have been more clear. Here's a very simplified version of what I'm trying to illustrate:
import java.util.*;
import java.lang.*;
import java.text.DecimalFormat;
import java.math.RoundingMode;
public class MyClass {
static class Vector{
float x, y, z;
#Override
public String toString(){
return "[" + x + ", " + y + ", " + z + "]";
}
}
public static ArrayList<Vector> generateRandomVecs(){
ArrayList<Vector> vecs = new ArrayList<>();
Random rand = new Random();
for(int i = 0; i < 500000; i++){
Vector v = new Vector();
v.x = rand.nextFloat() * 10;
v.y = rand.nextFloat() * 10;
v.z = rand.nextFloat() * 10;
vecs.add(v);
}
return vecs;
}
public static void main(String args[]) {
int precision = 2;
float scalarToMultiplyBy = 4.0f;
ArrayList<Vector> velocities = generateRandomVecs();
System.out.println("First 10 raw vectors:");
for(int i = 0; i < 10; i++){
System.out.print(velocities.get(i) + " ");
}
/*
This is the code that I am concerned about
*/
DecimalFormat df = new DecimalFormat("##.##");
df.setRoundingMode(RoundingMode.DOWN);
long start = System.currentTimeMillis();
for(Vector v : velocities){
/* Highly inefficient way of truncating*/
v.x = Float.parseFloat(df.format(v.x * scalarToMultiplyBy));
v.y = Float.parseFloat(df.format(v.y * scalarToMultiplyBy));
v.z = Float.parseFloat(df.format(v.z * scalarToMultiplyBy));
}
long finish = System.currentTimeMillis();
long timeElapsed = finish - start;
System.out.println();
System.out.println("Runtime: " + timeElapsed + " ms");
System.out.println("First 10 multiplied and truncated vectors:");
for(int i = 0; i < 10; i++){
System.out.print(velocities.get(i) + " ");
}
}
}
The reason it is very important to do this is because a different part of the program will store trigonometric values in a lookup table. The lookup table will be generated to n places beforehand, so any velocity vector that has a float value to 7 places (i.e. 5.2387471) must be truncated to n places before lookup. Truncation is needed instead of rounding because in the context of this program, it is OK if a vector is slightly less than its true value, but not greater.
Lookup table for 2 decimal places:
...
8.03 -> -0.17511085919
8.04 -> -0.18494742685
8.05 -> -0.19476549993
8.06 -> -0.20456409661
8.07 -> -0.21434223706
...
Say I wanted to look up the cosines of each element in the vector {8.040844, 8.05813164, 8.065688} in the table above. Obviously, I can't look up these values directly, but I can look up {8.04, 8.05, 8.06} in the table.
What I need is a very fast method to go from {8.040844, 8.05813164, 8.065688} to {8.04, 8.05, 8.06}
The fastest way, which will introduce rounding error, is going to be to multiply by 10^n, call Math.rint, and to divide by 10^n.
That's...not really all that helpful, though, considering the introduced error, and -- more importantly -- that it doesn't actually buy anything. Why drop decimal points if it doesn't improve efficiency or anything? If it's about making the values shorter for display or the like, truncate then, but until then, your program will run as fast as possible if you just use full float precision.
I want to do the average of 9 textfields and also the sum of them and place them in 2 other textfields by using a button, currently this code doesnt displays anything in the other textfiels. If i put anything, for example "A" instead of "%.Of" it would display the "A" in the textfield but not the average or the sum. Please i need help with a code that would work, dont mind if i need to change a lot.
This is what im working with:
private void jButton_RankingActionPerformed(java.awt.event.ActionEvent evt) {
double R[] = new double [14];
R[0] = Double.parseDouble(jTextField_Math.getText());
R[1]= Double.parseDouble(jTextField_English.getText());
R[2] = Double.parseDouble(jTextField_Spanish.getText());
R[3] = Double.parseDouble(jTextField_Biology.getText());
R[4] = Double.parseDouble(jTextField_Physics.getText());
R[5] = Double.parseDouble(jTextField_Chemestry.getText());
R[6] = Double.parseDouble(jTextField_PE.getText());
R[7] = Double.parseDouble(jTextField_Humanities.getText());
R[8] = Double.parseDouble(jTextField_Technology.getText());
R[9] = (R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8])/ 9;
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
String Average = String.format("%.Of",R[9]);
jTextField_Average.setText(Average);
String TotalScore = String.format("%.Of",R[10]);
jTextField_TotalScore.setText(TotalScore);
if(R[10]>=50)
{
jTextField_Ranking.setText("Superior");
}
else if (R[10]>=41){
jTextField_Ranking.setText("Alto");
}
else if (R[10]>=34){
jTextField_Ranking.setText("Basico");
}
else if (R[10]<=33){
jTextField_Ranking.setText("Bajo");
Since you mentioned that an A would print, it follows that jButton_RankingActionPerformed is being called. The issue you have is the format string you are using to print the total and average. You have mistakenly chosen the capital letter O rather than the number zero.
Replace this (which contains a capital letter O):
String.format("%.Of",R[9]);
With
1) No decimal will be printed: i.e. 50.2 would be 50
String.format("%.0f",R[9]);
2) Or perhaps you want to see one decimal place like 50.2
String.format("%.1f",R[9]);
Also a very small optimization is:
R[9] = (R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8])/ 9;
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
Could be replaced with:
R[10] = R[0]+R[1]+R[2]+R[3]+R[4]+R[5]+R[6]+R[7]+R[8];
R[9] = R[10] / 9;
or use a loop to calculate R[10]. (to add R[0] to R[8])
I have been trying to use jlibSVM
I want to use it for multi output regression.
for example my :
feature set / inputs will be x1,x2,x3
and outputs/target values will be y1,y2
Is this possible using the libSVM library ?
The API docs are not clear and there is not example app showing the use of jlibsvm so I tried to modify the code inside lexecyexec/svm_train.java
The author has originally just created the app to use one output/target value only .
this is seen in this part where the author tries to read the training file :
private void read_problem() throws IOException
{
BufferedReader fp = new BufferedReader(new FileReader(input_file_name));
Vector<Float> vy = new Vector<Float>();
Vector<SparseVector> vx = new Vector<SparseVector>();
int max_index = 0;
while (true)
{
String line = fp.readLine();
if (line == null)
{
break;
}
StringTokenizer st = new StringTokenizer(line, " \t\n\r\f:");
vy.addElement(Float.parseFloat(st.nextToken()));
int m = st.countTokens() / 2;
SparseVector x = new SparseVector(m);
for (int j = 0; j < m; j++)
{
//x[j] = new svm_node();
x.indexes[j] = Integer.parseInt(st.nextToken());
x.values[j] = Float.parseFloat(st.nextToken());
}
if (m > 0)
{
max_index = Math.max(max_index, x.indexes[m - 1]);
}
vx.addElement(x);
}
I tried to modify it so that the vector vy accepts a sparse vector with 2 values.
The program gets executed but the model file seems to be wrong.
Can anyone please verify if they have used jlibsvm for multiple output svm regression???
If yes can someone please explain how they achieved this ??
If no then does someone know of a similar svm implementation in Java ??
The classic SVM algorithm does not support multi dimensional outputs. One way to work around this would be to have a SVM model for each output dimension.
I was asked to do a multithreaded simulator of a specific algorithm.
One of the tasks was to compare the regular scheduling results with round robin results.
When I was looking for information about the round robin scheduling method I found vary general explanations and some code examples that I couldn’t find any relation between them and scheduling the threads.
For example this code (found here on stack overflow):
public static void RR3(int numProcess, int[] cpuBurst, int[] arrivalTime){
int quantum = 3,time = 0, temp;
int completionTime = 0;
LinkedList <Integer>process = new LinkedList();
for (int i = 0; i < numProcess; i++) {
process.add(i, cpuBurst[i]);
}
while (process.isEmpty() != true){
for (int j = 0; j < quantum; j++) {
System.out.println(process.getFirst());
if(process.peek() == 0 ){
completionTime = completionTime + time;
process.remove();
}
else{
temp = process.pop();
process.push(temp - 1);
time++;
}
}
process.addLast(process.getFirst());
process.removeFirst();
}
double act = (double) completionTime/numProcess;
System.out.println("-----------------RR3-----------------");
System.out.println(" Act = " + act + "ms");
}
I don't see anything but integers that represent the amount of process, time for each etc., but how do I actually manage their behavior? I dont see any call for a process to run or stop.
You already noticed that this is an abstraction. Namely that there is no real work performed. Instead, the work is just "imitated" by a set of Integers that represent the amount of work.
The question about how to run or stop the processes is somewhat hidden in the algorithm itself: The LinkedList stores the "active" processes. They are all started at the beginning. In each turn, they receive a short time slot in which they can do some of their work. When all their work is done, they are removed from the list.
In the simplest form, when the Integer values are replaced by real tasks, you could replace the line
if(process.peek() == 0 ){ ... }
with something like
Task task = process.peek();
if (task.isFinished()) { ... }
Otherwise (in the else case), when there is work to be done, you could replace the lines
temp = process.pop();
process.push(temp - 1);
with something like
Task task = process.peek();
task.doALittleBitOfWork();
The code that you posted was originally part of a question, so one has to assume that there's still something wrong with it, but maybe it is sufficient to get the basic idea.
I'm using libsvm and the documentation leads me to believe that there's a way to output the believed probability of an output classification's accuracy. Is this so? And if so, can anyone provide a clear example of how to do it in code?
Currently, I'm using the Java libraries in the following manner
SvmModel model = Svm.svm_train(problem, parameters);
SvmNode x[] = getAnArrayOfSvmNodesForProblem();
double predictedValue = Svm.svm_predict(model, x);
Given your code-snippet, I'm going to assume you want to use the Java API packaged with libSVM, rather than the more verbose one provided by jlibsvm.
To enable prediction with probability estimates, train a model with the svm_parameter field probability set to 1. Then, just change your code so that it calls the svm method svm_predict_probability rather than svm_predict.
Modifying your snippet, we have:
parameters.probability = 1;
svm_model model = svm.svm_train(problem, parameters);
svm_node x[] = problem.x[0]; // let's try the first data pt in problem
double[] prob_estimates = new double[NUM_LABEL_CLASSES];
svm.svm_predict_probability(model, x, prob_estimates);
It's worth knowing that training with multiclass probability estimates can change the predictions made by the classifier. For more on this, see the question Calculating Nearest Match to Mean/Stddev Pair With LibSVM.
The accepted answer worked like a charm. Make sure to set probability = 1 during training.
If you are trying to drop prediction when the confidence is not met with threshold, here is the code sample:
double confidenceScores[] = new double[model.nr_class];
svm.svm_predict_probability(model, svmVector, confidenceScores);
/*System.out.println("text="+ text);
for (int i = 0; i < model.nr_class; i++) {
System.out.println("i=" + i + ", labelNum:" + model.label[i] + ", name=" + classLoadMap.get(model.label[i]) + ", score="+confidenceScores[i]);
}*/
//finding max confidence;
int maxConfidenceIndex = 0;
double maxConfidence = confidenceScores[maxConfidenceIndex];
for (int i = 1; i < confidenceScores.length; i++) {
if(confidenceScores[i] > maxConfidence){
maxConfidenceIndex = i;
maxConfidence = confidenceScores[i];
}
}
double threshold = 0.3; // set this based data & no. of classes
int labelNum = model.label[maxConfidenceIndex];
// reverse map number to name
String targetClassLabel = classLoadMap.get(labelNum);
LOG.info("classNumber:{}, className:{}; confidence:{}; for text:{}",
labelNum, targetClassLabel, (maxConfidence), text);
if (maxConfidence < threshold ) {
LOG.info("Not enough confidence; threshold={}", threshold);
targetClassLabel = null;
}
return targetClassLabel;