Java - raise Real To Power n^k - java

I'm having difficulty writing a program to solve this exercise from a Java text book:
Write a method raiseRealToPower that takes a floating-point value x and an integer
k and returns xk. Implement your method so that it can correctly calculate the result
when k is negative, using the relationship
x^(-k) = 1 / x^k.
Use your method to display a table of values of πk for all values of k from –4 to 4.
I didn't done this part with PI, i know that, if my programs starts to work... this is what i done... tell me please, what is wrong.
import acm.program.*;
public class vjezba55 extends ConsoleProgram {
private static final double PI = 3.14159253;
public void run() {
double x = readDouble ("x: ");
double k = readDouble ("k: ");
println ("x^k = " + raiseDoublePower(x,k));
}
/* Method that counts x^k */
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
double total = 1;
for (int i= 0; i>k; i--) {
total = (double) 1 / x;
}
return total;
}
}
}

Take a look at your loop code. You are just recalculating total from scratch on each iteration, rather than updating the previous result.

I don't understand the part in the question regarding PI, but your method may be much simpler (according to using the relationship x^(-k) = 1 / x^k):
private double raiseDoublePower (double x, double k){
if (k >= 0) {
return Math.pow(x, k);
}
else {
return 1 / Math.pow(x, -k);
}
}

Related

Divergence of Taylor series expansion of sin(x) in Java

I'm trying to do the Taylor expansion of the sine of x, but given x greater than 150 degrees, the function diverges.
Here´s my code:
package TaylorJ;
import java.math.*;
public class SeriesSin {
Here I bound the Dominion to be [0, 2pi].
public static double Dominion(double x) {
double dpi = 2*Math.PI;
double dmx = 0;
if((x>=0 && x<=dpi)) {
dmx = x;
}
else if(x<0) {
dmx = dpi+(x%dpi);
}
else {
dmx = x%dpi;
}
return dmx;
}
Here, I defined a factorial function
public static int Factorial(int n) {
n = Math.abs(n);
int a = 1;
int b = 1;
if(n==0 || n == 1) {
return 1;
}
else {
for(int i=n; i>1;i--) {
b *=i;
}
return b;
}
}
Here's the Taylor (Maclaurin) series expansion for sin(x)
public static double Sin(double x) {
if(x%Math.PI == 0) {
x = Dominion(x);
}
else {
x = Dominion(Math.abs(Math.toRadians(x)));
}
int j = 0;
double nmu = 0;
double d1 = 10;
double d2 = 0;
do {
d1 = nmu;
nmu = nmu+ Math.pow(-1,j)*((Math.pow(x, ((2*j)+1)))/(Factorial((2*j)+1)));
d2 = nmu;
j = j+1;
}while((Math.abs(Math.abs(d2)-Math.abs(d1))>0.0001));
return nmu;
}
}
The thing is that it has to be defined for x in [0, 2pi], so I don't know what to do.
Thanks
The error is most likely a ripple effect of numerical over/undeflows. Note that the values of the factorial function, that you use as intermediate results in your computation, grow rather quickly. Using standard floating point number representations you will lose accuracy in computations rather quickly.
However, each of your summation terms can be computed by multiplying the previous term in the series with a suitable factor. This way you avoid overly large or small interim results.
Any text on numerical analysis should provide a much more detailed and stringent discussion.
In your code, replace the loop with the following code:
double asummandj = x;
do {
d1 = nmu;
nmu = nmu + Math.pow(-1,j) * asummandj;
d2 = nmu;
j = j+1;
asummandj = asummandj * (x / (2*j)) * (x / (2*j+1));
} while(Math.abs( d2 - d1 ) > 0.0001);

Mathematical Operations Without Using Java Math Class

I've been making my own class library in Java and I've run into a small annoyance. The library is centered around math. I started with the intention of not using the Java Math Class. Unfortunately, my lack of skill paired with my inability to find a resource online that tackles this problem has resulted in me falling back onto the Java Math Class. Is there a way I can do logarithms without using Math.log?
We could try to use a power series as per: https://math.stackexchange.com/a/61283
For example:
#Test
public void printMathCalculation() {
double libValue = Math.log(100);
double myValue = getLn(100);
System.out.println("Actual: \t" + libValue);
System.out.println("Approximate: \t" + myValue);
}
//Take double to an integer power
private double pow(double num, int power) {
double result = 1;
for(int i = 0; i < power; i++) {
result *= num;
}
return result;
}
//Get natural log
private double getLn(double num) {
int accuracy = 1000;
double sum = 0;
for(int n = 0; n < accuracy; n++) {
double num1 = (1.0/(2*n+1));
double num2 = (num-1)/(num+1);
sum += num1*pow(num2,2*n+1);
}
return 2 * sum;
}
The results I get are:
Actual: 4.605170185988092
Approximate: 4.605170185988078
You should use Math.log
Try this, using simple maths to calculate
public static int toLog2N(int num){
return num>1 ? 1 + toLog2N(num/2) : 0;
}
Its just an example, you should use Math class as it provides different methods like log(double a), log10(double a), log1p(double a). It will make your code more readable and easier to understand.
hope it helps!

Create a program that calculates the square root of a number without using Math.sqrt

This is the formula that can be used to calculate the square root of a number.
result=(guess+(number/guess))/2;
For example, I need to get the square root of 9. First, I need to make a guess. For this one, it's 6. Although, I know that the square root of 9 is 3, I chose 6 to show how the program should work.
that makes...
result=(6+(9/6))/2 which is equal to 3.75.
To get the actual square root of 9, I need to make the result the new guess.The program should continue as...
result=(3.75+(9/3.75))/2 which is equal to 3.075.
This process should continue till difference between result and the result after it is equal to 0. For example
result=(3+(9/3))/2 is always equal to 3.
When the value of result is passed to guess, the next result will also be 3. That means 3 is the square root of nine.
Here's my code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double result=0;
while(Math.abs(guess-ans)!=0){
result=(guess+(num/guess))/2;
guess=result;
}
System.out.print(result);
}
}
Output
3.75
My problem is I can't compare the value of result and the previous result. Since guess is equal to result, the program immediately since guess and result are already equal. How can I fix it?
Just exchange the two statements in the while loop (and the initializations to avoid a division by zero):
public static void calcRoot(){
double num=9;
double guess=0;
double result=6;
while(Math.abs(guess-result)!=0){
guess=result;
result=(guess+(num/guess))/2;
}
System.out.print(result);
}
The trick is to have the old value still in guess and the new one in result when the test is executed.
And you should not test for != 0, due to rounding errors this may not be achieved. Better test for some small value >= 1e-7
To compare the result with the previous result you need to keep both of them in a variable.
This does a binary chop.
public static double sqrt(double ans) {
if (ans < 1)
return 1.0 / sqrt(1.0 / ans);
double guess = 1;
double add = ans / 2;
while (add >= Math.ulp(guess)) {
double guess2 = guess + add;
double result = guess2 * guess2;
if (result < ans)
guess = guess2;
else if (result == ans)
return guess2;
add /= 2;
}
return guess;
}
public static void main(String[] args) {
for (int i = 0; i <= 10; i++)
System.out.println(sqrt(i) + " vs " + Math.sqrt(i));
}
prints
0.0 vs 0.0
1.0 vs 1.0
1.414213562373095 vs 1.4142135623730951
1.7320508075688772 vs 1.7320508075688772
2.0 vs 2.0
2.236067977499789 vs 2.23606797749979
2.449489742783178 vs 2.449489742783178
2.64575131106459 vs 2.6457513110645907
2.82842712474619 vs 2.8284271247461903
3.0 vs 3.0
3.162277660168379 vs 3.1622776601683795
and
for (int i = 0; i <= 10; i++)
System.out.println(i / 10.0 + ": " + sqrt(i / 10.0) + " vs " + Math.sqrt(i / 10.0));
prints
0.0: 0.0 vs 0.0
0.1: 0.31622776601683794 vs 0.31622776601683794
0.2: 0.4472135954999581 vs 0.4472135954999579
0.3: 0.5477225575051662 vs 0.5477225575051661
0.4: 0.6324555320336759 vs 0.6324555320336759
0.5: 0.7071067811865476 vs 0.7071067811865476
0.6: 0.7745966692414834 vs 0.7745966692414834
0.7: 0.8366600265340758 vs 0.8366600265340756
0.8: 0.894427190999916 vs 0.8944271909999159
0.9: 0.9486832980505138 vs 0.9486832980505138
1.0: 1.0 vs 1.0
Just create another variable to store the value of the previous guess.
This is the code:
package javaPackage;
public class SquareRoot {
public static void main(String[] args) {
calcRoot();
}
public static void calcRoot(){
double num=9;
double guess=6;
double prevGuess=0;
double result=0;
while(Math.abs(guess-prevGuess)!=0){
result=(guess+(num/guess))/2;
prevGuess = guess;
guess=result;
}
System.out.print(result);
}
}
For performance,following this code:
public static double sqrt(double num) {
double half = 0.5 * num;
long bit = Double.doubleToLongBits(num);
bit = 0x5fe6ec85e7de30daL - (bit >> 1);
num = Double.longBitsToDouble(bit);
for (int index = 0; index < 4; index++) {
num = num * (1.5f - half * num * num);
}
return 1 / num;
}
About the magic number 0x5fe6ec85e7de30daL,you can see the FAST INVERSE SQUARE ROOT
Let's see the performance,the test code:
double test = 123456;
//trigger the jit compiler
for (int index = 0; index < 100000000; index++) {
sqrt(test);
}
for (int index = 0; index < 100000000; index++) {
Math.sqrt(test);
}
//performance
long start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
sqrt(test);
}
System.out.println("this:"+(System.currentTimeMillis() - start));
start = System.currentTimeMillis();
for (long index = 0; index < 10000000000L; index++) {
Math.sqrt(test);
}
System.out.println("system:"+(System.currentTimeMillis() - start));
System.out.println(sqrt(test));
System.out.println(Math.sqrt(test));
and the result is:
this:3327
system:3236
this result:351.363060095964
system result:351.363060095964
public static double sqrt(double number)
{
double dd=number, sqi, sqrt=0;
long i, b=0, e=0, c=1, z, d=(long)number, r=0, j;
for (i=1l, sqi=1; ; i*=100l, sqi*=10)
{
if (i>dd)
{
i/=100;
sqi/=10;
j=i;
break;
}
}
for (z=0l; z<16; dd=(dd-(double)(r*i))*100, j/=100l, sqi/=10, z++)
{
r=(long)(dd/i);
d=(e*100l)+r;
int a=9;
for (c=((b*10l)+a)*a; ; a--)
{
c=((b*10l)+a)*a;
if (c<=d)
break;
}
//if (a>=0)
// System.out.print(a);
e=d-c;
sqrt+=a*sqi;
if (number==sqrt*sqrt && j==1)
break;
//if (j==1)
// System.out.print('.');
b=b*10l+2l*(a);
}
return sqrt;
}
Sorry for the undefined variable names....but this program really works!
This program is based on long division method of finding square root

TestDome: my solution works but I am only getting %50 right and not %100?

This is the scenario question:
A frog only moves forward, but it can move in steps 1 inch long or in jumps 2 inches long. A frog can cover the same distance using different combinations of steps and jumps.
Write a function that calculates the number of different combinations a frog can use to cover a given distance.
For example, a distance of 3 inches can be covered in three ways: step-step-step, step-jump, and jump-step.
public class Frog{
public static int numberOfWays(int input) {
int counter = 2;
int x = 0;
for (int i = 1 ; i< input -1; i++ ){
x = i + counter;
counter = x;
}
if (input <3){
x = input;
}
return x;
}
public static void main(String[] args) {
System.out.println(numberOfWays(10));
}
}
This solution only gives me %50 right not sure why its not %100 right, I tested it with other values and returns the right results.
I think recursion is a nice way to solve problems like that
public int numberOfCombinations(int distance) {
if (distance == 1) {
return 1; //step
} else if (distance == 2) {
return 2; // (step + step) or jump
} else {
return numberOfCombinations(distance - 1) + numberOfCombinations(distance - 2);
// we jumped or stepped into the current field
}
}
Let f[n] be the number of combinations of steps and jumps such that you travel n inches. You can immediately see that f[n] = f[n-1] + f[n-2], that is first you can travel n-1 inches in some way and then use 1 step or you can travel n-2 inches in some way and then use 1 jump. Since f[1] = 1 and f[2] = 2 you can see that f[n] = fib(n+1), the n+1-th Fibonacci number. You can calculate it in linear time if it suits the purpose or, more efficiently, you can calculate it in log n time - reference
The problem is a modified version of the Fibonacci series. I get 100% for the following (sorry it's C# but is very similar):
using System;
public class Frog
{
public static int NumberOfWays(int n)
{
int firstnumber = 0, secondnumber = 1, result = 0;
if (n == 1) return 1;
if (n == 2) return 2;
for (int i = 2; i <= n + 1; i++)
{
result = firstnumber + secondnumber;
firstnumber = secondnumber;
secondnumber = result;
}
return result;
}
public static void Main(String[] args)
{
Console.WriteLine(NumberOfWays(3));
Console.WriteLine(NumberOfWays(4));
Console.WriteLine(NumberOfWays(5));
Console.WriteLine(NumberOfWays(6));
Console.WriteLine(NumberOfWays(7));
Console.WriteLine(NumberOfWays(8));
}
}
Think overlapping subproblem / dynamic programming. You need to memorize the repetitive calls to the sub-problem which will save you all the time.
I believe this should cover your all scenarios.
public static string numberOfCombinations(int distance)
{
if (distance == 1) {
return "Step";//1
} else if (distance == 2) {
return "Jump";//2
} else{
return numberOfCombinations(1) + numberOfCombinations(distance - 1);
}
}

Stack Overflow Error (Java)

So my code is printing out estimations of Pi using a for and while loop and a recursive method. It's all working except my compiler is saying there's a stack overflow error for the if statement in my recursive method.
public static final double REAL_PI = 3.14159;//PI is the value Mr.B gave us on the handout
public static double Pi = 0; //Pi is the value of Pi that this program calculates
public static int m = 0;
public static int c = 0;
public static void main (String [] args)
{
Algorithm(); //calls on method of calculating pi
System.out.println("Calculated pi: " + Pi); //prints out pi
countDigits(Pi); //calls on countdigits method
System.out.println("Number of digits: " + c); //has the computer print out the count because that's how many digits are the same
While();
Recursive(1, 0.0); //calls on estimate digits method
}
public static double Algorithm() //should return a double (pi)
{
for(m=1; m<=100000; m++)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));//Math.pow uses math package to calculate a power to use the algorithm
}
return Pi;
}
public static int countDigits (double Pi)
{
int a = (int) Pi; //the int cast makes Pi and REAL_PI into integers so the program can compare each digit separately
int b = (int) REAL_PI;
int c = 0;
int count = 0;
while(a == b)//if m less then or equal to 100,000 then while loop runs
{
count ++;
a = (int) (Pi*(Math.pow(10,count))); //if a=b then the computer will multiply Pi and REAL_PI by 10
b = (int) (REAL_PI*(Math.pow(10,count)));
/*when you input a and b
* while loop compares them
* if a = b then loop continues until a doesn't equal b and loop ends
*/
}
c = count; //gives c the value of the count so it can be used outside the method
return count;
}
public static double While()
{
int m = 1;
Pi = 0.0;
while (countDigits(Pi) < 6)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));
m++;
}
Pi = (int)(Pi * 1000000);
Pi = (double)(Pi/1000000);
System.out.println("Pi using while loop: " + Pi);
return Pi;
}
public static double Recursive(int m,double Pi)
{
Pi += 4*(Math.pow(-1, m-1)/((2*m)-1));
if (countDigits(Pi) < 6)
{
return Pi += Recursive(m+1,Pi);
}
Pi = (int)(Pi * 1000000);
Pi = (double)(Pi/1000000);
System.out.println("Pi using recursive: " + Pi);
return Pi;
}
}
The problem is that the Leibniz series for computing π converges EXTREMELY slowly. Using your program, I found that after 3663 iterations (when I killed the program), the values looked like this:
pi=3.141865802997432
pi=3.1413195787723875
pi=3.1418656538577117
pi=3.1413197278306884
Still only 3 decimal places, and it is going to take a long time even to be accurate to 4. The stack is not big enough to hold so many recursive calls, and eventually it will overflow.

Categories

Resources