How would I write a recursive static method that uses an (n+1) term MacLaurin series to compute e^x, called e(x,n), by using the following recursive formulation:
e(x,0)= 1
e(x,n)= e(x,n-1) + x^n/n!, if n>0
Also, my method signature needs to use the following:
public static double eTwo(double x, long n)
Been stuck for a while, any thoughts guys?
This is simplest solution that get on my mind, did you try it?
public static double eTwo(double x, long n){
if(n==0)
return 1;
else
return eTwo(x,n-1) + Math.pow(x, n)/factorial(n);
}
public double factorial (n){
if(n==0)
return 1;
else
return n*factorial(n-1);
}
A version which is likely a little more efficient would be to use a loop instead of recursion, because only a single stack frame needs to be allocated:
static double eTwo(double x, long n) {
double result = 1;
for (long i = 1; i < n; i++)
result += Math.pow(x, (double) i) / (double) factorial(i);
return result;
}
static long factorial(long n) {
long result = 1;
for (long i = 1; i <= n; i++)
result *= i;
return result;
}
Related
In the following (naive) implementation of a pow(x, n) method, ignoring completely any optimized approach, I find the following problem:
public double pow(double x, int n) {
boolean negative = n < 0;
long power = Math.abs(n);
double ans = 1.0;
for(long i = 0; i < power; i++) {
ans = ans * x;
}
return negative ? 1.0/ans: ans;
}
Here I have made the assumption that for the case of negative exponent I simply calculate the x^n and then return 1/(x^n) since e.g. 2^(-3) = 1/(2^3)
Problem:
The code fails in the following case:
pow(2.00000, -2147483648)
The output is 1.00000 while the expected correct result is 0.00000
If I change the code as follows:
public double pow(double x, int n) {
long power = n;
if(power < 0) {
x = 1 / x;
power = -power;
}
double ans = 1.0;
for(long i = 0; i < power; i++) {
ans = ans * x;
}
return ans;
}
The result is correct!
So what is the difference between doing the approaches? I was expecting them to be equivalent but they are not
Math.abs(n) is still an int, and only afterwards it is assigned to a long, Therefore, the absolute value of -2147483648 was -2147483648 again (this is noted in the documentation of Math.abs(int)). With the negative bound, the loop performed no iterations.
Math.abs((long)n) would work around that issue.
public static long fallingPower(int n, int k)
However, in the related operation of falling power that is useful in many combinatorial formulas and denoted syntactically by underlining the exponent, each term that gets multiplied into the product is always one less than the previous term. For example, the falling power 83 would be computed as 8 * 7 * 6 = 336. Similarly, the falling power 105 would equal 10 * 9 * 8 * 7 * 6 = 30240. Nothing important changes if the base n is negative. For example, the falling power (-4)5 is computed the exact same way as -4 * -5 * -6 * -7 * -8 = -6720.
This method should compute and return the falling power nk where n can be any integer, and k can be any nonnegative integer. (Analogous to ordinary powers, n0 = 1 for any n.) The automated tester is designed so that your method does not need to worry about potential integer overflow as long as you perform computations using long type of 64-bit integers.
public static long fallingPower(int n, int k)
long result = n;
for (int i = n; i < k; i--) {
result = result * n;
}
return result;
}
Is my method right?
It should be:
public static long fallingPower(int n, int k){
long result = n;
for (int i = 0; i < k; i++) {
n=n-1;
result = result * n;
}
return result;
}
You are supposed to multiply k times, starting with n and decrementing each factor by one. Your code currently doesn't really make any sense. I would do it like this:
public static long fallingPower(int n, int k)
long result = n;
for (int i = 1; i < k; i++) {
result = result * (n-i);
}
return result;
}
k is required to be non-negative, so you need to handle that in the method too, for example with an exception:
public static long fallingPower(int n, int k)
if(k < 0) {
throw new IllegalArgumentException("Negative exponent");
}
long result = n;
for (int i = 1; i < k; i++) {
result = result * (n-i);
}
return result;
}
public static long fallingPower(int n, uint k){
long result = 1;
for(; k > 0; k--, n--){
result *= n;
}
return result;
}
This is more of the programming logic, not your method, if I am not wrong. I do not have error handling. I started going backward just like you, assuming the least integer permutation of zero is equal to 1 and at least we need to return 1.
You can start from k number before the n and multiply thereafter until you reach n.
public static long fallingPower(int n, int k)
{
long result = 1;
for (int i = 1 ; i <= k ; i++) {
result = result * n;
n = n-1;
}
return result;
}
I am trying to write a function in java that finds the result of an operand raised to the power of another.
I can't use the pow function or any form of loop. What are any possible solutions? I tried "^" and that didn't work.
public static String raiseP(int op1, int op2){
int result = op1 ^ op2; //Doesn't Work
return result;
}
Would there be a way to do this using basic math?
I have written:
public static int pow(int x, int y, int n, int z){
if (y == n){
System.out.println(z);
return z;
}
else{
z = z*x;
n += 1;
pow(x,y,n,z);
return 0;
}
}
ex: pow(5,9,0,1) == 5^9
but am not allowed to use recursion.
Without being able to call Math.pow or using loops, the only other possibility is using recursion:
public int powerFunction(int base, int exponent) {
if(exponent < 0){ throw new IllegalArgumentException("unsupported negative pow"); }
if(exponent == 0){ return 1; }
else{
return base * powerFunction(base, exponent - 1);
}
}
Calling powerFunction(2, 3) will give you: 1 * 2 * 2 * 2 = 8
You could simply use that
pow(x,y) = exp(y*log(x))
which is also part of the implementation of the power function in the math library.
The recursion could help you:
public static int myPowerRec(int op1, int op2, int res) {
if (op2 == 0) {
return res;
}
else {
return (myPowerRec(op1, op2 - 1, op1 * res));
}
}
You will need to initialize res to 1 (myPowerRec(23, 2, 1) will give you 1 * 23 * 23).
This recursion is called tail recursion and will allow you to use this function without stack problem.
Be careful, you must check op2 value before.
Using a for loop:
public static int power(a, b) { // a ^ b
int p = 1;
for (int i = 1, i <= b; i++)
p *= a;
return p;
}
i have this piece of Code for the calc:
public static double CalcPoisson(double m, double u, boolean va)
{
double answer = 0;
if(!va)
{
answer = (Math.exp(-u)* Math.pow(u, m)) / (factorial(m));
}
if(va)
{
for(int i = 0; i < m; i++)
{
answer = answer + (Math.exp(-u)* Math.pow(u, i)) / (factorial(i));
}
}
return answer;
And this was my factorial method
public static double factorial (double n)
{
return n == 0 ? 1 : n *factorial(n-1);
}
Problem is: the maximum value to calculate is 170...i need way more (like factorial of 500)
I have written a new Method:
public static BigDecimal factorial2 (double n)
{
BigDecimal fct = BigDecimal.valueOf(1);
for(int i = 1; i<=n; i++)
{
fct = fct.multiply(BigDecimal.valueOf(i));
}
return fct;
How can i use my new factorialmethod in my "CalcPoisson" Method?
Problem is, i cant divide double with BigDecimal...
Thanks for the help :)
For No One:
I have still this Line of Code in one method that uses CalcPoisson, im still bad with BigDecimal, i cant handle it.
The Line:
BigDecimal nenner = CalcPoisson(m, u, false) + (1-p) * CalcPoisson(m, u, true);
for(int i = 0; i < m; i++)
{
answer = answer + (Math.exp(-u)* Math.pow(u, i)) / (factorial(i));
}
Note that this algorithm computes all factorials from 0 through m-1. Much faster and more accurate to factor that out:
long fact = 1;
for(int i = 0; i < m; i++) {
answer = answer + (Math.exp(-u)* Math.pow(u, i)) / fact;
fact *= (i+1);
}
then note that Math.exp(-u) is invariant in the loop, so extract it:
long fact = 1;
double eu = Math.exp(-u);
for(int i = 0; i < m; i++) {
answer = answer + (eu * Math.pow(u, i)) / fact;
fact *= (i+1);
}
And you can also get rid of the repeated calls to Math.pow():
long fact = 1;
double eu = Math.exp(-u);
double term = u;
for(int i = 0; i < m; i++) {
answer = answer + (eu * term) / fact;
fact *= (i+1);
term *= u;
}
Finally, you can also get combine term and fact into a single parameter (left as an exercise for the student).
You could create a new BigDecimal out of the Double
Then you can use the multiplie method of the BigDecimal
fct = fct.multiplie(new BigDecimal(doubleValue));
Your approach is too direct. Such loops are usually written in terms of while (nextTerm < epsilon) , not as a for loop. That is, of course, provided that you can prove that the terms do decrease with i.
The other problem is that while the value of the expression pow(u,i) / factorial(i) may fit in a double, its parts surely do not. You need to compute this in a different way. Of course, as you do, you lose precision, so it becomes even more complicated.
I should better stop. My Math professor promised that he will hunt down and kill any of us who tried to do computational math, and he was a serious gentleman.
You can convert your double to BigDecimal and then you can divide two BigDecimals as following:
BigDecimal answer = BigDecimal.ZERO;
BigDecimal myOwn = new BigDecimal(Double.toString(Math.exp(-u)* Math.pow(u, i)));
answer = answer.add(myOwn.divide(factorial2(i)));
Use BigDecimal to find Factorial as you have done in factorial2().
Finally your method will look like:
public static BigDecimal CalcPoisson(double m, double u, boolean va)
{
BigDecimal answer = BigDecimal.ZERO;
if(!va)
{
BigDecimal myOwn1 = new BigDecimal(Double.toString((Math.exp(-u)* Math.pow(u, m))));
answer = myOwn1.divide(fakultaet(m));
}
if(va)
{
for(int i = 0; i < m; i++)
{
BigDecimal myOwn = new BigDecimal(Double.toString(Math.exp(-u)* Math.pow(u, i)));
answer = answer.add(myOwn.divide(factorial2(i)));
}
}
return answer;
Assuming that you have return type of method fakultaet() is BigDecimal. And if you have return value double for the same, than try:
answer = myOwn1.divide(new BigDecimal(fakultaet(m)));
EDIT
BigDecimal nenner = CalcPoisson(m, u, false).add((BigDecimal.ONE.subtract(new BigDecimal(p))).multiply( CalcPoisson(m, u, true)));
I have to write simple code to calculate cos(x) value with McLaurin series approximation. I have to do it recursively. Problem is that with too big angle (param in radians) or too high precision (loop has to stop while last term is smaller or equal than given ε) I get StackOverFlowError. At first I did it non-recursively and it worked perfectly, but it's not fully correct according to assignment. I tried to decrease number of calls for term, but I couldn't fix this. Is there any way to improve this code?
public int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
public double term(double x, int n) {
return Math.pow(-1, n) * (Math.pow(x, 2*n) / factorial(2*n));
}
public double laurin(String param, String epsilon) {
double x, eps;
double result = 1;
int n = 0;
x = Double.parseDouble(param);
eps = Double.parseDouble(epsilon);
while(Math.abs(term(x, n)) > eps) {
result += term(x, n) * (term(x, n+1) / term(x, n));
n++;
}
return result;
}
Changing factorial(int n) to non-recursive hasn't changed much, I still get an error real quick.