I have a mathematical formula and had a hard time to understand this and converted in to Java code.
[Attached Image is the formula I have to solve]
I have written some code and it is not helping much. In the formula I have value for C and P and need to find N.
Below is the code I have used
public static Double sigmaSum(int c, int n, Double p){
Double sum = 0.00;
for(int i=0; i<c; i++){
for(int j=i; j<n;j++){
sum += ((Math.pow(p, j)) * (Math.pow((1-p), (n-j))));
}
I have a corresponding excel formula but I don't know how to convert it into java.
Option Explicit
Dim intLTPD, intCL, intC, intCalcF, intK, intComboNum, intComboDen1, intI, intJ, intComboDen2, intCombo, intL As Integer
Dim lngSampleSize As Long
Sub macBinSampPlan()
'
intLTPD = (Range("B1") / 100)
intCL = Range("B2") / 100
'intC = Int(Range("B3"))
Cells.Range("A6").Select
intCombo = 0
intCalcF = 0
intI = 0
intJ = 0
For intC = 0 To 10
For intI = 1 To 10000
For intJ = 0 To intC
If intI >= intJ Then
intCombo = Application.WorksheetFunction.Combin(intI, intJ)
intCalcF = intCalcF + (intCombo * (Application.WorksheetFunction.Power(intLTPD, intJ)) * (Application.WorksheetFunction.Power((1 - intLTPD), (intI - intJ))))
Else
Exit For
End If
Next intJ
If (intCalcF - (1 - intCL)) / intCalcF <= intLTPD Then
lngSampleSize = intI
Exit For
Else
intCombo = 0
intCalcF = 0
End If
Next intI
ActiveCell = intC
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveCell = lngSampleSize + 1
ActiveCell.Offset(1, -1).Range("A1").Select
Next intC
End Sub
I am working on this around a week and not able to get it resolved.It should be a great help if some body can solve this. Thanks in advance.
Vivek
The way your implement your binomial seems to be wrong. According to your formula, the code should rather be:
public static Double sigmaSum(int c, int n, Double p){
Double sum = 0.00;
for(int i=0; i<c; i++){
sum += ((CombinatoricsUtils.binomialCoefficientDouble(n,i)) * (Math.pow(p, i)) * (Math.pow((1-p), (n-i))));
}
}
I have not tested the code yet.
Related
I have to write a Taylor series until the 16th element that calculates sin and compare the values returned values with Math.sin. Well , everything works fine until the last time when instead of 0.00000 i get 0.006941.Where is my error and if somebody have an idea how to write this in a more professional way I would be very happy.
import java.text.NumberFormat;
import java.text.DecimalFormat;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
NumberFormat formatter = new DecimalFormat("#0.000000");
double val[] = {0, Math.PI / 3, Math.PI / 4, Math.PI / 6, Math.PI / 2, Math.PI};
for (int i = 0; i < val.length; i++) {
System.out.println("With Taylor method: " + formatter.format(Taylor(val[i])));
System.out.println("With Math.sin method: " + formatter.format(Math.sin(val[i])));
}
}
public static double Taylor ( double val){
ArrayList<Double> memory = new ArrayList<Double>();
double row = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
double mth = Math.pow(val, s);
double result = mth / factorial(s);
memory.add(result);
}
for (int i = 0; i < 16; i++) {
if (i % 2 == 0) {
double d = memory.get(i);
row = row - d;
} else {
double d = memory.get(i);
row = row + d;
}
}
return row;
}
public static long factorial ( double n){
long fact = 1;
for (int i = 2; i <= n; i++) {
fact = fact * i;
}
return fact;
}
}
Your math is correct, but your factorials are overflowing once you get to calculating 21!. I printed out the factorials calculated.
factorial(3) = 6
factorial(5) = 120
factorial(7) = 5040
factorial(9) = 362880
factorial(11) = 39916800
factorial(13) = 6227020800
factorial(15) = 1307674368000
factorial(17) = 355687428096000
factorial(19) = 121645100408832000
factorial(21) = -4249290049419214848 // Overflow starting here!
factorial(23) = 8128291617894825984
factorial(25) = 7034535277573963776
factorial(27) = -5483646897237262336
factorial(29) = -7055958792655077376
factorial(31) = 4999213071378415616
factorial(33) = 3400198294675128320
It appears that your raising val to ever higher powers isn't significant enough to make a difference with the overflow until you get to the highest value in your array, Math.PI itself. There the error due to overflow is significant.
Instead, calculate each term using the last term as a starting point. If you have the last value you entered into memory, then just multiply val * val into that value and then divide the next two numbers in sequence for the factorial part.
That's because memory.get(i) is equal to memory.get(i - 1) * (val * val) / ((s - 1) * s). This also makes your calculation more efficient. It avoids the multiplication repetition when calculating the numerator (power part) and the denominator (the factorial calculation). This will also avoid the overflow which results from how you calculated the denominator separately.
My implementation of this idea substitutes this for the first for loop:
double mth = val;
for (int i = 0, s = 3; i < 16; i++, s = s + 2) {
mth = mth * val * val;
mth = mth / ((s - 1) * s);
memory.add(mth);
}
and places
double row = val;
between the for loops, to ensure that the first term is the initial sum as you had it before. Then you don't even need the factorial method.
This this I get 0.000000 for Math.PI.
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
I want to solve this math question in processing:
S=1+1/2-1/3+1/4...+1/99-1/100.
Here is my code (don't know why it doesn't work. I suppose it will print one number in the console, but it comes out a series of natural numbers):
float N = 0;
float T = 0;
int i = 1;
void draw() {
for (i = 1; i < 100; i += 2) {
N = N + 1 / i;
T = T + 1 / (i + 1);
}
println(N - T);
}
First off, draw() runs every frame. Use setup() instead, it runs once.
Second, dividing ints results in an int. Go ahead, do println(1/i) and see the magic.
Third, always google around for some time before going to SO. You'll learn more by finding it out yourself. And this was very solvable with google and a little effort ;)
working code:
float N = 0;
float T = 0;
int i = 1;
void setup() {
for (i = 1; i < 100; i += 2) {
N = N + 1.0 / i;
T = T + 1.0 / (i + 1);
}
println(N - T);
}
1 / i is a division expression between two integers, the result of which will be an int obtained by truncating the fraction part of the result. Since you are calculating float you can resolve it by using a 1f float literal
for (int i = 1; i < 100; i += 2) {
N = N + 1f / i;
T = T + 1f / (i + 1);
}
However your code currently counts the following:
Consider i = 1 for which you get T = 0.5 which you later subtract from N while you should be adding it as per your problem statement. One way to sole it is to write the code as:
float sum = 1;
for (int i = 2; i <= 100; i++) {
float term = 1f / i;
if (i % 2 != 0) {
term *= -1;
}
sum += term;
}
System.out.println(sum);
the question is to find the sum of this series
series
i used this code to solve it , but im not quite sure the logic is correct.
the noofterms is how many terms are going to be added
and x is the number that will be assigned to the variable.
does the logic seem correct?
public static double sumOfSeries(double x, int noofterms){
double evennumbers=1;
double oddnumbers=1;
double result=1;
// since the power of x starts from 1 , we start i from 1 and increment by 2
for (int i=1; i<noofterms; i+=2 ){
// we reset starting numbers so we start from them everytime
evennumbers = 1;
oddnumbers = 1;
// everytime the number increases by 2 when it is smaller than i+1
// ex when its equal to 2 , j = 3 , j+1 = 4 so it increments by 2
// when its 4 , j = 5 , j+ 1 = 6 , it increments
for (int j=2; j<=i+1; j+=2){
// multiply by increments of 2
evennumbers= evennumbers * j;
}
// it starts from 1 and increments by 2 so it goes like 1,3,5
for (int z=1; z<=i; z+=2){
oddnumbers = oddnumbers * z;
}
result*=((Math.pow(x, (double)i)) / (double)i) + (oddnumbers/evennumbers);
}
return result;
}
You can do it better. Note that numerators and denominators form two sequences, so you can keep previous terms to efficiently make computations, this will look like this :
long even = 1;
long odd = 1;
double result = x;
for(long i = 1; i < noofterms; i++)
{
even *= 2 * i;
odd *= 2 * i - 1;
double oper = Math.pow(x, (double)(2 * i + 1)) / (double)(2 * i + 1);
result += (double)even / (double)odd * oper;
}
You can improve by using logarithms because even and odd will grow very fast and will lead to overflows :
double even = 0.0;
double odd = 0.0;
double result = x;
double logx = Math.log(x);
for(long i = 1; i < noofterms; i++)
{
even += Math.log((double)(2 * i));
odd += Math.log((double)(2 * i - 1));
double oper = logx * (2 * i + 1) - Math.log((double)(2 * i + 1));
result += Math.exp(even - odd + oper);
}
EDIT: only one sequence could also be computed : p *= (double)(2*i)/(2*i-1). Then the log trick is not useful.
I was attempting to solve this morning's Codeforces problem Div 2C: http://codeforces.com/contest/716/problem/C
This problem has the potential to loop up to 100,000 times so the parameter here can be up to 100,000. Loop seems to break when passing in 100,000 (and possibly earlier) and i is declared as an int:
public void solve(int a) {
double x = 2;
double y = 0;
double n = 0;
double target = 0;
double lcm = 0;
for (int i = 1; i <= a; i++) {
lcm = (i + 1) * i;
y = ((lcm * lcm) - x) / i;
n = (y * i) + x;
if (Math.sqrt(n) % (i + 1) == 0) {
x = Math.sqrt(n);
String answer = String.format("%.0f", y);
System.out.println("this is i: " + i);
System.out.println(answer);
}
}
}
Here is the relevant output:
this is i: 46337
99495281029892
this is i: 46338
99501722706961
this is i: 46340
99514606895203
this is i: 65535
32769
Doing a quick search on Stack overflow shows that the number 65535 is associated with a 16-bit unsigned int, but java uses 32bit ints. Changing the type to double works, as does simply looping 100,000 times and printing without the code logic. I understand that 100,000^2 IS above the maximum int limit, but this value is never stored as an int in my code. What's going on here?
The following line generates an out of bounds int before converting the result to double:
lcm = (i + 1) * i;
The above is essentially the same as:
lcm = (double)((i + 1) * i);
or
int temp = (i + 1) * i;
lcm = (double) temp;
Instead try (first converting to double and then taking what is similar to a square):
lcm = (i + 1.0) * i;
I just solve this but want know more efficient way to do matrix multiplication
M = | 1 0 3 |
| 1 0 2 |
| 0 5 0 |
f[n] = M^n
I have implemented using Exponentiation_by_squaring
Is there more efficient then this ?
I guess, this is actually more suitable for math as there's a closed form solution. It's system of Linear homogeneous recurrence relations with constant coefficients.
Another posibility: You could speed up the program twice by deriving a formula for two steps, i.e., express RR(i) etc. via RR(i-2), etc.
And this can be repeated, so you can jump much faster.
One problem is that your calculations are overflowing. If you run it for K=1 and J=9, you get -334328541#510576792#-817751931.
The easiest fix for that is to do % 1000000006 in calculateProduction.
About efficiency, I would look at this problem as performing matrix multiplications.
You start with the vector (i.e. 1*3 matrix):
3 1 0
And at each step you multiply it (mod 1000000006) with the matrix:
1 1 0
0 0 5
3 2 0
Let's call the vector V and the matrix M. Basically you need to calculate V*MN. Since matrix multiplication is associative, you can calculate MN first, and do that recursively:
MN = (MN/2)2 if N is even, or
MN = M*(M[N/2])2 if N is odd
You don't need to calculate MM. This is why:
PP[i] = 5*MM[i-1] = 5*(RR[i-2] + 2*PP[i-2])
RR[i] = RR[i-1] + 3*PP[i-1] = (RR[i-2] + 3*PP[i-2]) + 3*PP[i-1]
See? You don't need to calculate MM at each step. This should be the algorithm:
public class RecurrenceMachine {
private static final int max = 1000000006;
public String calculate(int k, int j) {
long n = k * j;
if (n < 1)
return "error";
long RRi2 = 3;
long PPi2 = 0;
long RRi1 = 3 + 3 * PPi2;
long PPi1 = 5 * 1;
if (n == 1)
return RRi1 + "##" + (RRi2 + 2 * PPi2) + "##" + PPi1;
Long PPi = (long) 0, RRi = (long) 0, temp;
int i;
for (i = 2; i <= n; i++) {
temp = RRi2 + 2 * PPi2;
PPi = 5 * temp;
if (PPi >= max)
PPi %= max;
RRi = temp + PPi2 + 3 * PPi1;
if (RRi >= max)
RRi %= max;
RRi2 = RRi1;
PPi2 = PPi1;
RRi1 = RRi;
PPi1 = PPi;
}
return RRi + "##" + (RRi2 + 2 * PPi2) % max + "##" + PPi1;
}
}
I tried only with small values and it seems to work.