I'm trying to calculate a the inverse of a 2 tailed Student Distribution using commons-math. I'm using Excel to compare values and validate if my results are correct.
So Using excel to calculate TINV with 5 degrees of freedom and 95.45% I use
=TINV(0.0455,5)
And get the Result: 2.64865
Using commons Math like so :
TDistribution t = new TDistribution(5);
double value = t.inverseCumulativeProbability(0.9545);
I get Result : 2.08913
I'm probably doing something wrong obviously. I'm not really that math savvy but I need to port an Excel sheet formula to Java for a project and got stuck on this.
What should I be using to get the result exactly like the TINV value? What am I missing.
MS documentation [1] says that TINV returns a two-tailed value. I'm pretty sure Commons Math is returning a one-tailed value. In order to get Commons Math to agree with Excel, cut the tail mass in half, i.e., call
t.inverseCumulativeProbability (1 - tail_mass/2);
[1] http://office.microsoft.com/en-us/excel-help/tinv-function-HP010335663.aspx
Related
I have an excel file that has a complex calculation model, the performance of direct using apache POI is not acceptable to me. therefore I am thinking to extract the full set formula chain and parse it to java.
for example: If C1=A1+B1 and A1=A2+B2, B1=A3+B3 => C1 = A2+B2+A3+B3
I also noticed that there is an object called CalculationChain, it seems there is a convenient way to get the formula chain. rather than parse these nested Cells one by one.
Anyone can give an example to shed some light on?
This is not a good answer, but it moves one step forward.
XSSFEvaluationWorkbook xssfEvaluationWorkbook = XSSFEvaluationWorkbook.create(workbook);
Ptg[] ptg = FormulaParser.parse(cell.getCellFormula(), xssfEvaluationWorkbook, FormulaType.NAMEDRANGE, sheetIndex);
I have a requirement where I need to get values based on some excel formula fields. On a high level, we have an excel where user has the liberty to enter date values and based on these input the formula fields are updated and total revenue field value is calculated.
Now to perform these validations via code will it be better to
Write own utilities in Java for each formula in spreadsheet.
Use Apache POI to input the values in spreadsheet on runtime and evaluate formulas to get revenue value.
On approach 1 I am having below issues :
On implementing below code for =YEARFRAC(B1, B2+1)*12 formula
public static double calculateContractLength(String startdate,String enddate) {
double monthsBetween = ChronoUnit.MONTHS.between(
LocalDate.parse(startdate),
LocalDate.parse(enddate));
return monthsBetween;
}
I see mismatch in result of excel formula and above code. For Instance Start Date = 2/12/2020 End Date = 12/31/2022, I see excel showing 34.63 but Code returning 34.0
To better handle is I want to know if there are some existing libraries which have already implemented these spreadsheet formulas or just updating the excel at run time with Apache POI would be a better solution.
I tend to understand from the documentation of the yearfrac function (link at the bottom) that when given two arguments (as in your example), it will count 30 days in a month. I don’t know whether it’s a requirement that your Java code does exactly the same. In any case here’s my attempt to mimic:
public static double calculateContractLength(String startdate,String enddate) {
Period per = Period.between(
LocalDate.parse(startdate),
LocalDate.parse(enddate));
return per.toTotalMonths() + per.getDays() / 30.0;
}
Trying it out with the example dates from your question, expecting 34.63:
System.out.println(calculateContractLength("2020-02-12", "2022-12-31"));
Output is:
34.63333333333333
I also tried the dates from the example in the yearfrac documentation:
System.out.println(calculateContractLength("2012-01-01", "2012-07-30"));
The documentation says that the result is 0.58055556 years, so that should be 0.58055556 * 12 months = 6.96666672 months. We get:
6.966666666666667
There will probably still be (a bit greater) differences in corner cases. Fractions of months are not well-defined. One sign if the same is that the MS documentation states:
The YEARFRAC function may return an incorrect result when using
the US (NASD) 30/360 basis, and the start_date is the last day in
February.
Link
Documentation of the YEARFRAC function
I have to do (-5.428271)1/3 and want the complex-number "0.8787335 + 1.522011i" as well as the other 2 results.
Is there a method to do that?
If there isn't, how can I create it?
Apache commons math has an nthRoot method returning a list of complex values. If you do not want the dependency, the javadoc has the formula.
I have a two array inputs of data. Call them p and t. I need to find the regression function of these columns so I can accuratly predict future values. Is there any way to do this with in java? If so, what is the best way?
I know of:
apache commons math (see stat.regression).
I've been reading up on the net about the issues with handling float and double types in java. Unfortunately, the image is still not clear. Hence, i'm asking here direct. :(
My MySQL table has various DECIMAL(m,d) columns. The m may range from 5 to 30. d stays a constant at 2.
Question 1.
What equivalent data-type should i be using in Java to work (i.e store, retrieve, and process) with the size of the values in my table? (I've settled with double - hence this post).
Question 2.
While trying to parse a double from a string, i'm getting errors
Double dpu = new Double(dpuField.getText());
for example -
"1" -> java.lang.NumberFormatException: empty String
"10" -> 1.0
"101" -> 10.0
"101." -> 101.0
"101.1" -> 101.0
"101.19" -> 101.1
What am i doing wrong? What is the correct way to convert a string to a double value?
And what measures should i take to perform operations on such values?
EDIT
This is the code -
System.out.println(dpuField.getText());
Double dpu = new Double(dpuField.getText());
System.out.println(dpu);
Yes, the problem lies with getText() reporting the wrong value of the dpuField.
This method is called on the JTextField keyTyped event. So what's going wrong here?
EDIT 2
Looking at :
http://journals.ecs.soton.ac.uk/java/tutorial/post1.0/ui/keylistener.html
Apparently, keyTyped() does not give me the keycode. I'll have to switch to keyRealeased()
What equivalent data-type should i be using in Java to work (i.e store, retrieve, and process) with the size of the values in my table? (I've settled with double - hence this post).
Since it's a DECIMAL field, you should prefer java.math.BigDecimal. You can store it in DB using PreparedStatement#setBigDecimal() and you can retrieve it from DB using ResultSet#getBigDecimal().
While trying to parse a double from a string, i'm getting errors
This can't be true. The problem lies somewhere else. Maybe it is just not returning the data you expect to be returned or you are not using/debugging the values you expect them to be.
if you need exact precision without rounding errors, you should use a BigDecimal.
Your code looks OK - could it be that dpuField.getText() somehow cuts the last character from the string values you list above?
Update: you say
Yes, the problem lies with getText() reporting the wrong value of the dpuField. This method is called on the JTextField keyTyped event.
Could it be that getText() returns the value of the field before the last typed key is actually appended to it?
For decimal, I believe you risk losing precision if you don't use a BigDecimal on the Java side, as some decimal fractions can't be stored as a binary fraction.
Prefer Double.valueOf(String) over the constructor, but that's a valid way. Something else must be going on (i.e. I doubt those are the actual String values you're passing in).
Question1: It's bad idea to map DECIMAL columns to Double, usually the BigDecimal is the correct type. http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html#1055175
Question 2: You are doing something wrong; print the String value before converting.