Reducing recursive calls on pow recursion method? - java

Had a question on how to reduce the amount of recursive calls on a self implementation of the pow method. Here is what I wrote, can this be improved?
public static int pow(double a, int b) {
boolean isNegative = false;
if(b < 0) {
isNegative = true;
}
if(b == 0) {
return 1;
}
else if(b == 1) {
return (isNegative ? (1 / b) : b);
}
return (isNegative ? ((1 / b) * (1 / b) * pow(a, b + 2)) : (b * b * pow(a, b - 2)));
}

Yes, it can be improved.
Think about it this way:
If b is even, then a^b = a^(b/2) * a^(b/2).
If b is odd, then a^b = a^(b/2) * a^(b/2) * a (where / means integer division).
Code (brain-compiled, coffee hasn't kicked in yet, etc.):
public static double pow(double a, int b) {
if (b < 0)
return 1 / pow(a, -b);
if (b == 0)
return 1;
double halfPow = pow(a, b/2);
if (b % 2 == 0)
return halfPow * halfPow;
else
return halfPow * halfPow * a;
}
This gives you O(log b) recursive calls, as opposed to O(n) in your solution.

Have a look at memoization.

EDIT: Fundamentally, you've got three problems:
The code doesn't work (as of the edit, it now completely ignores a)
The code is too complicated
The code is recursing more than you want it to
Trying to fix the third of these without fixing the first is pointless.
Your first port of call should be some unit tests. They will prove very quickly that your code is currently broken, and give you some confidence that when you've fixed it, you can then change it and know whether or not you've broken anything.
Then you should aim to simplify it. For example, you could easily start your method with:
if (b < 0)
{
return 1 / pow(a, -b);
}
... then you don't need to worry about negative values of b any more.
Finally you can look at what you've got left and try to turn a recursive solution into an iterative solution.

Related

Recursive method for x^n optimised for when n is even

I need to write a recursive method using Java called power that takes a double x and an integer n and that returns x^n. Here is what I have so far.
public static double power(double x, int n) {
if (n == 0)
return 1;
if (n == 1)
return x;
else
return x * (power(x, n-1));
}
This code works as expected. However, I am trying to go the extra mile and perform the following optional exercise:
"Optional challenge: you can make this method more efficient, when n is even, using x^n = (x^(n/2))^2."
I am not sure how to implement that last formula when n is even. I do not think I can use recursion for that. I have tried to implement the following, but it also does not work because I cannot take a double to the power of an int.
if (n%2 == 0)
return (x^(n/2))^2;
Can somebody point me in the right direction? I feel like I am missing something obvious. All help appreciated.
It's exactly the same principle as for x^n == x*(x^(n-1)): Insert your recursive function for x^(n/2) and (...)^2, but make sure you don't enter an infinite recursion for n == 2 (as 2 is even, too):
if (n % 2 == 0 && n > 2)
return power(power(x, n / 2), 2);
}
Alternatively, you could just use an intermediate variable:
if (n % 2 == 0) {
double s = power(x, n / 2);
return s * s;
}
I'd probably just handle 2 as a special case, too -- and avoid the "and"-condition and extra variable:
public static double power(double x, int n) {
if (n == 0) return 1;
if (n == 1) return x;
if (n == 2) return x * x;
if (n % 2 == 0) return power(power(x, n / 2), 2);
return x * (power(x, n - 1));
}
P.S. I think this should work, too :)
public static double power(double x, int n) {
if (n == 0) return 1;
if (n == 1) return x;
if (n == 2) return x * x;
return power(x, n % 2) * power(power(x, n / 2), 2);
}
When n is even, the formula is exactly what you wrote: divide n by two, call power recursively, and square the result.
When n is odd, the formula is a little more complex: subtract 1 from n, make a recursive call for n/2, square the result, and multiply by x.
if (n%2 == 0)
return (x^(n/2))^2;
else
return x*(x^(n/2))^2;
n/2 truncates the result, so subtraction of 1 is not done explicitly. Here is an implementation in Java:
public static double power(double x, int n) {
if (n == 0) return 1;
if (n == 1) return x;
double pHalf = power(x, n/2);
if (n%2 == 0) {
return pHalf*pHalf;
} else {
return x*pHalf*pHalf;
}
}
Demo.
Hint: The ^ operation won't perform exponentiation in Java, but the function you wrote, power will.
Also, don't forget squaring a number is the same as just multiplying it by itself. No function call needed.
Making a small change to your function, it will reduce the number of recursive calls made:
public static double power(double x, int n) {
if (n == 0) {
return 1;
}
if (n == 1) {
return x;
}
if (n % 2 == 0) {
double temp = power(x, n / 2);
return temp * temp;
} else {
return x * (power(x, n - 1));
}
}
Since
x^(2n) = (x^n)^2
you can add this rule to your method, either using the power function you wrote, as Stefan Haustein suggested, or using the regular multiplication operator, since it seems you are allowed to do that.
Note that there is no need for both the base cases n=1 and n=0, one of them suffices (prefferably use the base case n=0, since otherwise your method would not be defined for n=0).
public static double power(double x, int n) {
if (n == 0)
return 1;
else if (n % 2 == 0)
double val = power(x, n/2);
return val * val;
else
return x * (power(x, n-1));
}
There is no need to check that n>2 in any of the cases.
This just reminds me more optimisation could be done
and this following code.
class Solution:
# #param x, a float
# #param n, a integer
# #return a float
def pow(self, x, n):
if n<0:
return 1.0/self.pow(x,-n)
elif n==0:
return 1.0
elif n==1:
return x
else:
m = n & (-n)
if( m==n ):
r1 = self.pow(x,n>>1)
return r1*r1
else:
return self.pow(x,m)*self.pow(x,n-m)
what is more intermediate result could be memorised and avoid redundant computation.

Power function using recursion

I have to write a power method in Java. It receives two ints and it doesn't matter if they are positive or negative numbers. It should have complexity of O(logN). It also must use recursion. My current code gets two numbers but the result I keep outputting is zero, and I can't figure out why.
import java.util.Scanner;
public class Powers {
public static void main(String[] args) {
float a;
float n;
float res;
Scanner in = new Scanner(System.in);
System.out.print("Enter int a ");
a = in.nextFloat();
System.out.print("Enter int n ");
n = in.nextFloat();
res = powers.pow(a, n);
System.out.print(res);
}
public static float pow(float a, float n) {
float result = 0;
if (n == 0) {
return 1;
} else if (n < 0) {
result = result * pow(a, n + 1);
} else if (n > 0) {
result = result * pow(a, n - 1);
}
return result;
}
}
Let's start with some math facts:
For a positive n, aⁿ = a⨯a⨯…⨯a n times
For a negative n, aⁿ = ⅟a⁻ⁿ = ⅟(a⨯a⨯…⨯a). This means a cannot be zero.
For n = 0, aⁿ = 1, even if a is zero or negative.
So let's start from the positive n case, and work from there.
Since we want our solution to be recursive, we have to find a way to define aⁿ based on a smaller n, and work from there. The usual way people think of recursion is to try to find a solution for n-1, and work from there.
And indeed, since it's mathematically true that aⁿ = a⨯(aⁿ⁻¹), the naive approach would be very similar to what you created:
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
return ( a * pow(a,n-1));
}
However, the complexity of this is O(n). Why? Because For n=0 it doesn't do any multiplications. For n=1, it does one multiplication. For n=2, it calls pow(a,1) which we know is one multiplication, and multiplies it once, so we have two multiplications. There is one multiplication in every recursion step, and there are n steps. So It's O(n).
In order to make this O(log n), we need every step to be applied to a fraction of n rather than just n-1. Here again, there is a math fact that can help us: an₁+n₂ = an₁⨯an₂.
This means that we can calculate aⁿ as an/2⨯an/2.
But what happens if n is odd? something like a⁹ will be a4.5⨯a4.5. But we are talking about integer powers here. Handling fractions is a whole different thing. Luckily, we can just formulate that as a⨯a⁴⨯a⁴.
So, for an even number use an/2⨯an/2, and for an odd number, use a⨯ an/2⨯an/2 (integer division, giving us 9/2 = 4).
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
if ( n % 2 == 1 ) {
// Odd n
return a * pow( a, n/2 ) * pow(a, n/2 );
} else {
// Even n
return pow( a, n/2 ) * pow( a, n/2 );
}
}
This actually gives us the right results (for a positive n, that is). But in fact, the complexity here is, again, O(n) rather than O(log n). Why? Because we're calculating the powers twice. Meaning that we actually call it 4 times at the next level, 8 times at the next level, and so on. The number of recursion steps is exponential, so this cancels out with the supposed saving that we did by dividing n by two.
But in fact, only a small correction is needed:
public static int pow( int a, int n) {
if ( n == 0 ) {
return 1;
}
int powerOfHalfN = pow( a, n/2 );
if ( n % 2 == 1 ) {
// Odd n
return a * powerOfHalfN * powerOfHalfN;
} else {
// Even n
return powerOfHalfN * powerOfHalfN;
}
}
In this version, we are calling the recursion only once. So we get from, say, a power of 64, very quickly through 32, 16, 8, 4, 2, 1 and done. Only one or two multiplications at each step, and there are only six steps. This is O(log n).
The conclusion from all this is:
To get an O(log n), we need recursion that works on a fraction of n at each step rather than just n - 1 or n - anything.
But the fraction is only part of the story. We need to be careful not to call the recursion more than once, because using several recursive calls in one step creates exponential complexity that cancels out with using a fraction of n.
Finally, we are ready to take care of the negative numbers. We simply have to get the reciprocal ⅟a⁻ⁿ. There are two important things to notice:
Don't allow division by zero. That is, if you got a=0, you should not perform the calculation. In Java, we throw an exception in such a case. The most appropriate ready-made exception is IllegalArgumentException. It's a RuntimeException, so you don't need to add a throws clause to your method. It would be good if you either caught it or prevented such a situation from happening, in your main method when you read in the arguments.
You can't return an integer anymore (in fact, we should have used long, because we run into integer overflow for pretty low powers with int) - because the result may be fractional.
So we define the method so that it returns double. Which means we also have to fix the type of powerOfHalfN. And here is the result:
public static double pow(int a, int n) {
if (n == 0) {
return 1.0;
}
if (n < 0) {
// Negative power.
if (a == 0) {
throw new IllegalArgumentException(
"It's impossible to raise 0 to the power of a negative number");
}
return 1 / pow(a, -n);
} else {
// Positive power
double powerOfHalfN = pow(a, n / 2);
if (n % 2 == 1) {
// Odd n
return a * powerOfHalfN * powerOfHalfN;
} else {
// Even n
return powerOfHalfN * powerOfHalfN;
}
}
}
Note that the part that handles a negative n is only used in the top level of the recursion. Once we call pow() recursively, it's always with positive numbers and the sign doesn't change until it reaches 0.
That should be an adequate solution to your exercise. However, personally I don't like the if there at the end, so here is another version. Can you tell why this is doing the same?
public static double pow(int a, int n) {
if (n == 0) {
return 1.0;
}
if (n < 0) {
// Negative power.
if (a == 0) {
throw new IllegalArgumentException(
"It's impossible to raise 0 to the power of a negative number");
}
return 1 / pow(a, -n);
} else {
// Positive power
double powerOfHalfN = pow(a, n / 2);
double[] factor = { 1, a };
return factor[n % 2] * powerOfHalfN * powerOfHalfN;
}
}
pay attention to :
float result = 0;
and
result = result * pow( a, n+1);
That's why you got a zero result.
And instead it's suggested to work like this:
result = a * pow( a, n+1);
Beside the error of initializing result to 0, there are some other issues :
Your calculation for negative n is wrong. Remember that a^n == 1/(a^(-n)).
If n is not integer, the calculation is much more complicated and you don't support it. I won't be surprised if you are not required to support it.
In order to achieve O(log n) performance, you should use a divide and conquer strategy. i.e. a^n == a^(n/2)*a^(n/2).
Here is a much less confusing way of doing it, at least if your not worred about the extra multiplications. :
public static double pow(int base,int exponent) {
if (exponent == 0) {
return 1;
}
if (exponent < 0) {
return 1 / pow(base, -exponent);
}
else {
double results = base * pow(base, exponent - 1);
return results;
}
}
# a pow n = a pow n%2 * square(a) pow(n//2)
# a pow -n = (1/a) pow n
from math import inf
def powofn(a, n):
if n == 0:
return 1
elif n == 1:
return a
elif n < 0:
if a == 0 : return inf
return powofn(1/a, -n)
else:
return powofn(a, n%2) * powofn(a*a, n//2)
A good rule is to get away from the keyboard until the algorythm is ready. What you did is obviously O(n).
As Eran suggested, to get a O(log(n)) complexity, you have to divide n by 2 at each iteration.
End conditions :
n == 0 => 1
n == 1 => a
Special case :
n < 0 => 1. / pow(a, -n) // note the 1. to get a double ...
Normal case :
m = n /2
result = pow(a, n)
result = resul * resul // avoid to compute twice
if n is odd (n % 2 != 0) => resul *= a
This algorythm is in O(log(n)) - It's up to you to write correct java code from it
But as you were told : n must be integer (negative of positive ok, but integer)
import java.io.*;
import java.util.*;
public class CandidateCode {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
int m = sc.nextInt();
int n = sc. nextInt();
int result = power(m,n);
System.out.println(result);
}
public static int power(int m, int n){
if(n!=0)
return (m*power(m,n-1));
else
return 1;
}
}
try this:
public int powerN(int base, int n) {return n == 0 ? 1 : (n == 1 ? base : base*(powerN(base,n-1)));
ohk i read solutions of others posted her but let me clear you those answers have given you
the correct & optimised solution but your solution can also works by replacing float result=0 to float result =1.

Power function with recursion - java

Here's the working recursive power function alternative to Math.Pow class:
public class Powers {
public static long pow(long x, long p) {
if (p == 0) {
return 1;
}
if (p % 2 == 0) {
long a = pow(x, (p / 2));
return a * a; //This line
} else {
long a = pow(x, ((p - 1) / 2));
return x * a * a; //This line
}
}
}
If I try to be clever and use as much recursion as possible by changing the lines mentioned above to return pow(a, 2) and return x * pow(a, 2), I get a stack overflow error. I get that it should cause considerably more calls to pow, but I don't think it should loop like it appears to. Can anyone explain me through this? Thanks
Doing this you will get the following sequence of calls:
pow(a, 2) -> pow(a, 1) -> pow(a, 0) -> pow(1, 2) -> pow(1, 1) -> pow(1, 0) -> pow(1, 2) -> ...
You should either debug this with some IDE, or simply add some expression in the beginning of the method:
public static long pow(long x, long p) {
System.out.println ("x = " + x + ", p = " + p);
...
Then, read the output, it will contain the sequence of calls of pow

Recursive function taking ages to run

I profiled my code and found that my program spent roughly 85% of the time executing this particular recursive function. The function aims to calculate the probability of reaching a set of states in a markov chain, given an initial position (x,y).
private static boolean condition(int n){
int i = 0;
while ( n >= i){
if( n == i*4 || n == (i*4 - 1))
return true;
i++;
}
return false;
}
public static double recursiveVal(int x, int y, double A, double B){
if(x> 6 && (x- 2 >= y)){ return 1;}
if(y> 6 && (y- 2 >= x)){ return 0;}
if(x> 5 && y> 5 && x== y){ return (A*(1-B) / (1 -(A*B) - ((1-A)*(1-B))));}
if(condition(x+ y)){
return (recursiveVal(x+1, y,A,B)*A + recursiveVal(x, y+1,A,B)*(1-A));
}
else{
return (recursiveVal(x+1, y,A,B)*(1-B) + recursiveVal(x,y+1,A,B)*B);
}
}
I was once told that 99% of recursive functions could be replaced by a while loop. I'm having trouble doing this though. Does anyone know how I could improve the execution time or rewrite this as a iterative loop?
Thanks
You could try to use a technique called memoization which basically caches previously computed results for recursive calls.
Wikipedia article on memoization.
As a side note, I recommend reformatting your code a bit. Here is a simplified version of yoru code.
private static boolean condition(int n){
for (int i = 0; i <= n; i++)
if(n == i*4 || n == (i * 4 - 1))
return true;
return false;
}
public static double recursiveVal(int x, int y, double A, double B){
if (x > 6 && (x - 2 >= y))
return 1;
if (y > 6 && (y - 2 >= x))
return 0;
if(x > 5 && y > 5 && x == y)
return A*(1-B) / (1 -(A*B) - ((1-A)*(1-B)));
double val1 = recursiveVal(x+1, y, A, B);
double val2 = recursiveVal(x, y+1, A, B);
return condition(x + y)
? A * val1 + val2 * (1-A)
: (1-B) * val1 + B * val2;
}
If you want to refactor a recursive function to an iterative one the steps are as follows:
1) Determine the base case of the Recursion. Base case, when reached, causes Recursion to end. Every Recursion must have a defined base case. In addition, each recursive call must make a progress towards the base case (otherwise recursive calls would be performed infinitely).
2) Implement a loop that will iterate until the base case is reached.
3) Make a progress towards the base case. Send the new arguments to the top of the loop instead to the recursive method.
Example of how trying to understand what it is doing can make the code faster/simpler...
This method is trying to determine if 'n' is a multiple of 4 or n+1 is a multiple of 4. This can be written much shorter as.
private static boolean condition(int n){
return (n+1) & 3 <= 1;
}
To convert this to an iterative form, note that you are computing a function on two (discrete) variables. You can use a table to store the values of the function, and fill in the table in a specific order so that you have already computed values you need by the time you need them. (in this case, from higher values of x and y).
In this case, the boundary cases (corresponding to the base cases in the original recursion) are:
f(7, y..5), f(8, 6)
f(x..5, 7), f(6, 8)
f(7, 7)
Then we fill in f(7, 6) and f(6, 7) and then proceed "downwards" - i.e.
f(6, 6), f(5, 6) ... f(x, 6), f(6, 5), f(5, 5) ... f(x, 5) ... f(x, y).
Note that what looks like function call syntax corresponds to a table lookup (it really converts to array syntax).

What's the syntax for mod in java

As an example in pseudocode:
if ((a mod 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
Instead of the modulo operator, which has slightly different semantics, for non-negative integers, you can use the remainder operator %. For your exact example:
if ((a % 2) == 0)
{
isEven = true;
}
else
{
isEven = false;
}
This can be simplified to a one-liner:
isEven = (a % 2) == 0;
Here is the representation of your pseudo-code in minimal Java code;
boolean isEven = a % 2 == 0;
I'll now break it down into its components. The modulus operator in Java is the percent character (%). Therefore taking an int % int returns another int. The double equals (==) operator is used to compare values, such as a pair of ints and returns a boolean. This is then assigned to the boolean variable 'isEven'. Based on operator precedence the modulus will be evaluated before the comparison.
Since everyone else already gave the answer, I'll add a bit of additional context. % the "modulus" operator is actually performing the remainder operation. The difference between mod and rem is subtle, but important.
(-1 mod 2) would normally give 1. More specifically given two integers, X and Y, the operation (X mod Y) tends to return a value in the range [0, Y). Said differently, the modulus of X and Y is always greater than or equal to zero, and less than Y.
Performing the same operation with the "%" or rem operator maintains the sign of the X value. If X is negative you get a result in the range (-Y, 0]. If X is positive you get a result in the range [0, Y).
Often this subtle distinction doesn't matter. Going back to your code question, though, there are multiple ways of solving for "evenness".
The first approach is good for beginners, because it is especially verbose.
// Option 1: Clearest way for beginners
boolean isEven;
if ((a % 2) == 0)
{
isEven = true
}
else
{
isEven = false
}
The second approach takes better advantage of the language, and leads to more succinct code. (Don't forget that the == operator returns a boolean.)
// Option 2: Clear, succinct, code
boolean isEven = ((a % 2) == 0);
The third approach is here for completeness, and uses the ternary operator. Although the ternary operator is often very useful, in this case I consider the second approach superior.
// Option 3: Ternary operator
boolean isEven = ((a % 2) == 0) ? true : false;
The fourth and final approach is to use knowledge of the binary representation of integers. If the least significant bit is 0 then the number is even. This can be checked using the bitwise-and operator (&). While this approach is the fastest (you are doing simple bit masking instead of division), it is perhaps a little advanced/complicated for a beginner.
// Option 4: Bitwise-and
boolean isEven = ((a & 1) == 0);
Here I used the bitwise-and operator, and represented it in the succinct form shown in option 2. Rewriting it in Option 1's form (and alternatively Option 3's) is left as an exercise to the reader. ;)
To get Java's % (REM) operation to work like MOD for negative X and positive Y values, you can use this method:
private int mod(int x, int y)
{
int result = x % y;
if (result < 0)
{
result += y;
}
return result;
}
or with the ternary operator (shorter, but not possible or less efficient in some situations):
private int mod(int x, int y)
{
int result = x % y;
return result < 0? result + y : result;
}
Java actually has no modulo operator the way C does. % in Java is a remainder operator. On positive integers, it works exactly like modulo, but it works differently on negative integers and, unlike modulo, can work with floating point numbers as well. Still, it's rare to use % on anything but positive integers, so if you want to call it a modulo, then feel free!
While it's possible to do a proper modulo by checking whether the value is negative and correct it if it is (the way many have suggested), there is a more compact solution.
(a % b + b) % b
This will first do the modulo, limiting the value to the -b -> +b range and then add b in order to ensure that the value is positive, letting the next modulo limit it to the 0 -> b range.
Note: If b is negative, the result will also be negative
The code runs much faster without using modulo:
public boolean isEven(int a){
return ( (a & 1) == 0 );
}
public boolean isOdd(int a){
return ( (a & 1) == 1 );
}
In Java it is the % operator:
15.17.3. Remainder Operator %
Note that there is also floorMod in the java.lang.Math class which will give a different result from % for arguments with different signs:
public static int floorMod​(int x, int y)
As others have pointed out, the % (remainder) operator is not the same as the mathematical
mod modulus operation/function.
mod vs %
The x mod n function maps x to n in the range of [0,n).
Whereas the x % n operator maps x to n in the range of (-n,n).
In order to have a method to use the mathematical modulus operation and not
care about the sign in front of x one can use:
((x % n) + n) % n
Maybe this picture helps understand it better (I had a hard time wrapping my head around this first)
if (a % 2 == 0) {
} else {
}
you should examine the specification before using 'remainder' operator % :
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.17.3
// bad enough implementation of isEven method, for fun. so any worse?
boolean isEven(int num)
{
num %= 10;
if(num == 1)
return false;
else if(num == 0)
return true;
else
return isEven(num + 2);
}
isEven = isEven(a);
Also, mod can be used like this:
int a = 7;
b = a % 2;
b would equal 1. Because 7 % 2 = 1.
The remainder operator in Java is % and the modulo operator can be expressed as
public int mod(int i, int j)
{
int rem = i % j;
if (j < 0 && rem > 0)
{
return rem + j;
}
if (j > 0 && rem < 0)
{
return rem + j;
}
return rem;
}
In Java, the mod operation can be performed as such:
Math.floorMod(a, b)
Note:
The mod operation is different from the remainder operation. In Java, the remainder operation can be performed as such:
a % b
Another way is:
boolean isEven = false;
if((a % 2) == 0)
{
isEven = true;
}
But easiest way is still:
boolean isEven = (a % 2) == 0;
Like #Steve Kuo said.
The modulo operator is % (percent sign). To test for evenness or generally do modulo for a power of 2, you can also use & (the and operator) like isEven = !( a & 1 ).
An alternative to the code from #Cody:
Using the modulus operator:
bool isEven = (a % 2) == 0;
I think this is marginally better code than writing if/else, because there is less duplication & unused flexibility. It does require a bit more brain power to examine, but the good naming of isEven compensates.

Categories

Resources