Question:
A class SeriesSum is designed to calculate the sum of the following series:
Class name : SeriesSum
Data members/instance variables:
x : to store an integer number
n : to store number of terms
sum : double variable to store the sum of the series
Member functions:
SeriesSum(int xx, int nn) : constructor to assign x=xx and n=nn
double findfact(int m) to return the factorial of m using recursive
technique.
double findpower(int x, int y) : to return x raised to the power of y using
recursive technique.
void calculate( ) : to calculate the sum of the series by invoking
the recursive functions respectively
void display( ) : to display the sum of the series
(a) Specify the class SeriesSum, giving details of the constructor(int, int),
double findfact(int), double findpower(int, int), void calculate( ) and
void display( ).
Define the main( ) function to create an object and call the
functions accordingly to enable the task.
Code:
class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{ for(int i=2;i<=n;i+=2)
sum += findpower(x,i)/findfact(i-1);
}
void display()
{ System.out.println("sum="+ sum);
}
static void main()
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
MyProblem:
I am having problems in understanding that when i= any odd number (Taking an example such as 3 here)then it value that passes through findfact is (i-1)=2 then how am I getting the odd factorials such as 3!
Any help or guidance would be highly appreciated.
Optional:
If you can somehow explain the recursion taking place in the findpower and findfactorial,it would be of great help.
Take a closer look a the loop. i starts at 2 and is incremented by 2 every iteration, so it is never odd. It corresponds to the successive powers of x, each of which is divided by the factorial of i -1 (which IS odd).
As for the recursion in findfact, you just need to unwrap the first few calls by hand to see why it works :
findfact(a) = a * findfact(a -1)
= a * (a - 1) * findfact(a -2)
= a * (a - 1) * (a - 2) * findfact(a - 3)
...
= a * (a - 1) * (a - 2) * ... * 2 * findfact(1)
= a * (a - 1) * (a - 2) * ... * 2 * 1
= a!*
The same reasoning works with findpower.
As a side note, while it may be helpful for teaching purposes, recursion is a terrible idea for computing factorials or powers.
I'm not sure I understand your question correctly, but I try to help you the best I can.
I am having problems in understanding that when i= any odd number
In this code i never will be any odd number
for(int i=2;i<=n;i+=2)
i will be: 2 , 4 , 6 , 8 and so on because i+=2
The Recursion
The findfact() function in a more readable version:
double findfact(int a){
if(a < 2 ){
return 1;
} else {
return a * findfact(a - 1);
}
}
you can imagine it as a staircase, every call of findfact is a step:
We test: if a < 2 then return 1 else we call findfact() again with a-1 and multiply a with the result of findfact()
The same function without recursion:
double findfact(int a){
int sum = 1;
for(int i = a; i > 0; i--){
sum *= i;
}
return sum;
}
Same by the findpower function:
if b == 0 then return 1 else call findpower() with a, b-1 and multiply the return value of findpower() with a
So the last called findpower() will return 1 (b = 0)
The second last findpower() will return a * 1 (b = 1)
The third last findpower() will return a * a * 1 (b = 2)
so you can see findpower(a, 2) = a * a * 1 = a^2
Hope I could help you
Try to run below code, it will clear all your doubts (i have modified some access specifier and created main method)
public class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{
System.out.println("x ="+x);
System.out.println("n ="+n);
for(int i=2;i<=n;i+=2){
System.out.println(x+"^"+i+"/"+(i-1)+"!" +" = " +(findpower(x,i)+"/"+findfact(i-1)) );
//System.out.println(findpower(x,i)+"/"+findfact(i-1));
sum += findpower(x,i)/findfact(i-1);
}
}
void display()
{ System.out.println("sum="+ sum);
}
public static void main(String arg[])
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
// ----- output ----
x =3
n =8
3^2/1! = 9.0/1.0
3^4/3! = 81.0/6.0
3^6/5! = 729.0/120.0
3^8/7! = 6561.0/5040.0
sum=29.876785714285713
You can simplify the summation and get rid of power and factorial. Please notice:
The very first term is just x * x
If you know term item == x ** (2 * n) / (2 * n - 1)! the next one will be item * x * x / (2 * n) / (2 * n + 1).
Implementation:
private static double sum(double x, int count) {
double item = x * x; // First item
double result = item;
for (int i = 1; i <= count; ++i) {
// Next item from previous
item = item * x * x / (2 * i) / (2 * i +1);
result += item;
}
return result;
}
In the real world, you can notice that
sinh(x) = x/1! + x**3/3! + x**5/5! + ... + x**(2*n - 1) / (2*n - 1)! + ...
and your serie is nothing but
x * sinh(x) = x**2/1! + x**4 / 3! + ... + x**(2*n) / (2*n - 1)! + ...
So you can implement
private static double sum(double x) {
return x * (Math.exp(x) - Math.exp(-x)) / 2.0;
}
Related
I have tried:
static public void power(int n, int X) {
System.out.print( + " ");
if (n>0) {
power(n-1, X);
}
}
This does not yield a value as I'm not sure how to do that.
public int calculatePower(int base, int powerRaised)
{
if (powerRaised != 0)
return (base*calculatePower(base, powerRaised-1));
else
return 1;
}
static int power(int x, int y)
{
// Initialize result
int temp;
if( y == 0) // Base condition
return 1;
temp = power(x, y/2); // recursive calling
if (y%2 == 0) //checking whether y is even or not
return temp*temp;
else
return x*temp*temp;
}
Well others have written solution which gives you correct answer but their time complexity is O(n) as you are decreasing the power only by 1. Below solution will take less time O(log n). The trick here is that
x^y = x^(y/2) * x^(y/2)
so we only need to calculate x^(y/2) and then square it. Now if y is even then there is not problem but when y is odd we have to multiply it with x. For example
3^5 = 3^(5/2) * 3^(5/2)
but (5/2) = 2 so above equation will become 3^2 * 3^2, so we have to multiply it with 3 again then it will become 3 * 3^(5/2) * 3^(5/2)
then 3^2 will be calculated as 3^(2/1) * (3^2/1) here it no need to multiply it with 3.
public static double pow(int a, int pow) {
if (pow == 0)
return 1;
if (pow == 1)
return a;
if (pow == -1)
return 1. / a;
if (pow > 1)
return a * pow(a, pow - 1);
return 1. / (a * pow(a, -1 * (pow + 1)));
}
Considering X as number and n as power and if both are positive integers
public static int power(int n, int X) {
if (n == 0) {
return 1;
} else if(n == 1) {
return X;
} else {
return X * power(n-1, X);
}
}
Let's re-write your function:
static public void power(int n, int X) {
System.out.print( + " ");
if (n>0) {
power(n-1, X);
}
}
First of all, lets change void to int.
Afterthat, when n equals to 1, we return the result as X, because X^1 = X:
static public int power(int n, int X) {
if (n>1) {
return X * power(n-1, X);
}
return X;
}
Scanner s = new Scanner(System.in) ;
System.out.println("Enter n");
int n = s.nextInt();
System.out.println("Enter x");
int x =s.nextInt();
if (n>0){
double pow =Math.pow(n,x);
System.out.println(pow);
}
While others have given you solutions in terms of code, I would like to focus on why your code didn't work.
Recursion is a programming technique in which a method (function) calls itself. All recursions possess two certain characteristics:
When it calls itself, it does so to solve a smaller problem. In your example, to raise X to the power N, the method recursively calls itself with the arguments X and N-1, i.e. solves a smaller problem on each further step.
There's eventually a version of the problem which is trivial, such that the recursion can solve it without calling itself and return. This is called base case.
If you are familiar with mathematical induction, recursion is its programming equivalent.
Number two above is what your code is lacking. Your method never returns any number. In the case of raising a number to a power, the base case would be to solve the problem for the number 0 as raising zero to any power yields one, so the code does not need to call itself again to solve this.
So, as others have already suggested, you need two corrections to your code:
Add a return type for the method.
State the base case explicitly.
public class HelloWorld{
public long powerfun(int n,int power,long value){
if(power<1){
return value;
}
else{
value = value * n;
return powerfun(n,power-1,value);
}
}
public static void main(String []args){
HelloWorld hello = new HelloWorld();
System.out.println(hello.powerfun(5,4,1));
}
}
I've tried to add comments to explain the logic to you.
//Creating a new class
public class RecursivePower {
// Create the function that will calculate the power
// n is the number to be raised to a power
// x is the number by which we are raising n
// i.e. n^x
public static int power(int n, int x){
// Anything raised to the 0th power is 1
// So, check for that
if (x != 0){
// Recursively call the power function
return (n * power(n, x-1));
// If that is true...
}else{
return 1;
} //end if else
} //end power
// Example driver function to show your program is working
public static void main(String[] args){
System.out.println("The number 5 raised to 6 is " + power(5,6));
System.out.println("The number 10 raised to 3 is " + power(10,3));
} //end psvm
} //end RecursivePower
I got bored and decided to dive into remaking the square root function without referencing any of the Math.java functions. I have gotten to this point:
package sqrt;
public class SquareRoot {
public static void main(String[] args) {
System.out.println(sqrtOf(8));
}
public static double sqrtOf(double n){
double x = log(n,2);
return powerOf(2, x/2);
}
public static double log(double n, double base)
{
return (Math.log(n)/Math.log(base));
}
public static double powerOf(double x, double y) {
return powerOf(e(),y * log(x, e()));
}
public static int factorial(int n){
if(n <= 1){
return 1;
}else{
return n * factorial((n-1));
}
}
public static double e(){
return 1/factorial(1);
}
public static double e(int precision){
return 1/factorial(precision);
}
}
As you may very well see, I came to the point in my powerOf() function that infinitely recalls itself. I could replace that and use Math.exp(y * log(x, e()), so I dived into the Math source code to see how it handled my problem, resulting in a goose chase.
public static double exp(double a) {
return StrictMath.exp(a); // default impl. delegates to StrictMath
}
which leads to:
public static double exp(double x)
{
if (x != x)
return x;
if (x > EXP_LIMIT_H)
return Double.POSITIVE_INFINITY;
if (x < EXP_LIMIT_L)
return 0;
// Argument reduction.
double hi;
double lo;
int k;
double t = abs(x);
if (t > 0.5 * LN2)
{
if (t < 1.5 * LN2)
{
hi = t - LN2_H;
lo = LN2_L;
k = 1;
}
else
{
k = (int) (INV_LN2 * t + 0.5);
hi = t - k * LN2_H;
lo = k * LN2_L;
}
if (x < 0)
{
hi = -hi;
lo = -lo;
k = -k;
}
x = hi - lo;
}
else if (t < 1 / TWO_28)
return 1;
else
lo = hi = k = 0;
// Now x is in primary range.
t = x * x;
double c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
if (k == 0)
return 1 - (x * c / (c - 2) - x);
double y = 1 - (lo - x * c / (2 - c) - hi);
return scale(y, k);
}
Values that are referenced:
LN2 = 0.6931471805599453, // Long bits 0x3fe62e42fefa39efL.
LN2_H = 0.6931471803691238, // Long bits 0x3fe62e42fee00000L.
LN2_L = 1.9082149292705877e-10, // Long bits 0x3dea39ef35793c76L.
INV_LN2 = 1.4426950408889634, // Long bits 0x3ff71547652b82feL.
INV_LN2_H = 1.4426950216293335, // Long bits 0x3ff7154760000000L.
INV_LN2_L = 1.9259629911266175e-8; // Long bits 0x3e54ae0bf85ddf44L.
P1 = 0.16666666666666602, // Long bits 0x3fc555555555553eL.
P2 = -2.7777777777015593e-3, // Long bits 0xbf66c16c16bebd93L.
P3 = 6.613756321437934e-5, // Long bits 0x3f11566aaf25de2cL.
P4 = -1.6533902205465252e-6, // Long bits 0xbebbbd41c5d26bf1L.
P5 = 4.1381367970572385e-8, // Long bits 0x3e66376972bea4d0L.
TWO_28 = 0x10000000, // Long bits 0x41b0000000000000L
Here is where I'm starting to get lost. But I can make a few assumptions that so far the answer is starting to become estimated. I then find myself here:
private static double scale(double x, int n)
{
if (Configuration.DEBUG && abs(n) >= 2048)
throw new InternalError("Assertion failure");
if (x == 0 || x == Double.NEGATIVE_INFINITY
|| ! (x < Double.POSITIVE_INFINITY) || n == 0)
return x;
long bits = Double.doubleToLongBits(x);
int exp = (int) (bits >> 52) & 0x7ff;
if (exp == 0) // Subnormal x.
{
x *= TWO_54;
exp = ((int) (Double.doubleToLongBits(x) >> 52) & 0x7ff) - 54;
}
exp += n;
if (exp > 0x7fe) // Overflow.
return Double.POSITIVE_INFINITY * x;
if (exp > 0) // Normal.
return Double.longBitsToDouble((bits & 0x800fffffffffffffL)
| ((long) exp << 52));
if (exp <= -54)
return 0 * x; // Underflow.
exp += 54; // Subnormal result.
x = Double.longBitsToDouble((bits & 0x800fffffffffffffL)
| ((long) exp << 52));
return x * (1 / TWO_54);
}
TWO_54 = 0x40000000000000L
While I am, I would say, very understanding of math and programming, I hit the point to where I find myself at a Frankenstein monster mix of the two. I noticed the intrinsic switch to bits (which I have little to no experience with), and I was hoping someone could explain to me the processes that are occurring "under the hood" so to speak. Specifically where I got lost is from "Now x is in primary range" in the exp() method on wards and what the values that are being referenced really represent. I'm was asking for someone to help me understand not only the methods themselves, but also how they arrive to the answer. Feel free to go as in depth as needed.
edit:
if someone could maybe make this tag: "strictMath" that would be great. I believe that its size and for the Math library deriving from it justifies its existence.
To the exponential function:
What happens is that
exp(x) = 2^k * exp(x-k*log(2))
is exploited for positive x. Some magic is used to get more consistent results for large x where the reduction x-k*log(2) will introduce cancellation errors.
On the reduced x a rational approximation with minimized maximal error over the interval 0.5..1.5 is used, see Pade approximations and similar. This is based on the symmetric formula
exp(x) = exp(x/2)/exp(-x/2) = (c(x²)+x)/(c(x²)-x)
(note that the c in the code is x+c(x)-2). When using Taylor series, approximations for c(x*x)=x*coth(x/2) are based on
c(u)=2 + 1/6*u - 1/360*u^2 + 1/15120*u^3 - 1/604800*u^4 + 1/23950080*u^5 - 691/653837184000*u^6
The scale(x,n) function implements the multiplication x*2^n by directly manipulating the exponent in the bit assembly of the double floating point format.
Computing square roots
To compute square roots it would be more advantageous to compute them directly. First reduce the interval of approximation arguments via
sqrt(x)=2^k*sqrt(x/4^k)
which can again be done efficiently by directly manipulating the bit format of double.
After x is reduced to the interval 0.5..2.0 one can then employ formulas of the form
u = (x-1)/(x+1)
y = (c(u*u)+u) / (c(u*u)-u)
based on
sqrt(x)=sqrt(1+u)/sqrt(1-u)
and
c(v) = 1+sqrt(1-v) = 2 - 1/2*v - 1/8*v^2 - 1/16*v^3 - 5/128*v^4 - 7/256*v^5 - 21/1024*v^6 - 33/2048*v^7 - ...
In a program without bit manipulations this could look like
double my_sqrt(double x) {
double c,u,v,y,scale=1;
int k=0;
if(x<0) return NaN;
while(x>2 ) { x/=4; scale *=2; k++; }
while(x<0.5) { x*=4; scale /=2; k--; }
// rational approximation of sqrt
u = (x-1)/(x+1);
v = u*u;
c = 2 - v/2*(1 + v/4*(1 + v/2));
y = 1 + 2*u/(c-u); // = (c+u)/(c-u);
// one Halley iteration
y = y*(1+8*x/(3*(3*y*y+x))) // = y*(y*y+3*x)/(3*y*y+x)
// reconstruct original scale
return y*scale;
}
One could replace the Halley step with two Newton steps, or
with a better uniform approximation in c one could replace the Halley step with one Newton step, or ...
This isn't homework, it's just practice. My first method to write was:
Write a static recursive method power that takes two int arguments named x and p and returns x multiplied by itself p times.
I did that, and here is the code:
public static int power(int x, int p)
{
if(p==0)
{
return 1;
}
else
{
int result = x * power(x, p - 1);
return result;
}
}
The next problem was:
Each level in the pyramid is a square, so if there are n levels, the bottom level has n * n balls, and the total number of balls is just
(n * n) + (number of balls in a pyramid of height n - 1).
There is just one ball in a pyramid of height 1. Write a static recursive method getPyramidCount that takes a single int argument representing the number of levels in a pyramid, and returns the total number of balls. (Use your power method above to square numbers.)
I'm so frustrated because I have no clue as to how to write this. I know I want to make another method that includes the power method, but I'm so clueless. Can you help me out here? At this point I feel like seeing someone's code for this is the only way for me to understand.
EDIT: Didn't mean to have 2 there. It's supposed to be x! I was doing 2 to the 8th power and forgot to put in x instead of 2!
Don't multiply by 2. It's x * x p times. Like,
public static int power(int x, int p) {
if (p <= 0) {
return 1;
}
return x * power(x, p - 1);
}
First of all this line :
int result = 2 * power(x, p - 1);
should be this :
int result = x * power(x, p - 1);
but about your pyramid, your code have just one input with value of n and the return value as you said is n2 + pyramid(n-1);
First of all, your power method is wrong. It would calculate 2^p instead of x^p.
Change
int result = 2 * power(x, p - 1);
to
int result = x * power(x, p - 1);
Now, for the pyramid question, the recursion is : numBalls(n) = n^2 + numBalls(n-1).
Therefore, the method would look like this :
public static int numBalls (int n)
{
if (n==1)
return 1;
else
return power(n,2) + numBalls(n-1);
}
With the help of some very nice people from this forum I've been able to translate some c++ into java language, but I'm not sure how to call this classes. Bassically what they are supposed to do is to return a "gen4 style" curve. If someone have an idea how to get this running please let me know!
/*
Derived from gen4 from the UCSD Carl package, described in F.R. Moore,
"Elements of Computer Music." It works like setline, but there's an
additional argument for each time,value pair (except the last). This
arg determines the curvature of the segment, and is called "alpha" in
the comments to trans() below. -JGG, 12/2/01
http://www.music.columbia.edu/cmc/rtcmix/docs/docs.html (maketable/gen4)
trans(a, alpha, b, n, output) makes a transition from <a> to <b> in
<n> steps, according to transition parameter <alpha>. It stores the
resulting <n> values starting at location <output>.
alpha = 0 yields a straight line,
alpha < 0 yields an exponential transition, and
alpha > 0 yields a logarithmic transition.
All of this in accord with the formula:
output[i] = a + (b - a) * (1 - exp(i * alpha / (n-1))) / (1 - exp(alpha))
for 0 <= i < n
*/
import java.lang.Math;
private static final int MAX_POINTS =1024;
public class gen{
int size; /* size of array to load up */
int nargs; /* number of arguments passed in p array */
float []pvals; /* address of array of p values */
double []array; /* address of array to be loaded up */
int slot; /* slot number, for fnscl test */
}
public static void fnscl(gen g) {
}
static void trans(double a, double alpha, double b, int n, double[] output) {
double delta = b - a;
if (output.length <= 1) {
output[0] = a;
return;
}
double interval = 1.0 / (output.length - 1);
if (alpha != 0) {
double denom = 1 / (1 - Math.exp(alpha));
for (int i = 0; i < output.length; i++)
output[i] = a + (1 - Math.exp(i * alpha * interval)) * delta * denom;
} else {
for (int i = 0; i < output.length; i++)
output[i] = a + i * delta * interval;
}
}
public static double gen4(gen g) {
int i;
int points = 0;
int seglen = 0;
double factor;
double time [] = new double[MAX_POINTS];
double value [] = new double[MAX_POINTS];
double alpha [] = new double[MAX_POINTS];
double ptr [];
if (g.nargs < 5 || (g.nargs % 3) != 2) /* check number of args */
System.out.println("gen4 usage: t1 v1 a1 ... tn vn");
if ((g.nargs / 3) + 1 > MAX_POINTS)
System.out.println("gen4 too many arguments");
for (i = points = 0; i < g.nargs; points++) {
time[points] = g.pvals[i++];
if (points > 0 && time[points] < time[points - 1])
System.out.println("gen4 non-increasing time values");
value[points] = g.pvals[i++];
if (i < g.nargs)
alpha[points] = g.pvals[i++];
}
factor = (g.size - 1) / time[points - 1];
for (i = 0; i < points; i++)
time[i] *= factor;
ptr = g.array;
for (i = 0; i < points - 1; i++) {
seglen = (int) (Math.floor(time[i + 1] + 0.5)
- Math.floor(time[i] + 0.5) + 1);
trans(value[i], alpha[i], value[i + 1], seglen, ptr);
ptr[i] += seglen - 1;
}
fnscl(g);
return 0.0;
}
If I understand your question correctly and you want to execute your program, you need some adjustments to your code.
You need to have a class. To execute it, you need a special main method.
/**
*Derived from...
*/
import java.lang.Math;
class Gen4Func {
class Gen {
// insert from question
}
public static void main(String[] args) {
// prepare parameters
// ...
// call your function
trans( ... );
// do more stuff
// ...
}
public static void fnscl(gen g) {
}
static void trans(double a, double alpha, double b, int n, double[] output) {
// insert from above
}
}
Save this to Gen4Func.java (must match class name). Then execute from via
> java Gen4Func
As I said: If I understand your question correctly.
HTH,
Mike
Bulky, copypaste to Gen.java and try setting Gen class fields with test values in main() method.
/*
* Derived from gen4 from the UCSD Carl package, described in F.R. Moore,
* "Elements of Computer Music." It works like setline, but there's an additional
* argument for each time,value pair (except the last). This arg determines the
* curvature of the segment, and is called "alpha" in the comments to trans()
* below. -JGG, 12/2/01
*
* http://www.music.columbia.edu/cmc/rtcmix/docs/docs.html (maketable/gen4)
*
*
*
* trans(a, alpha, b, n, output) makes a transition from <a> to <b> in <n>
* steps, according to transition parameter <alpha>. It stores the resulting <n>
* values starting at location <output>. alpha = 0 yields a straight line, alpha
* < 0 yields an exponential transition, and alpha > 0 yields a logarithmic
* transition. All of this in accord with the formula: output[i] = a + (b - a) *
* (1 - exp(i * alpha / (n-1))) / (1 - exp(alpha)) for 0 <= i < n
*/
public class Gen {
private static final int MAX_POINTS = 1024;
int size; //size of array to load up
int nargs; //number of arguments passed in p array
float[] pvals; //address of array of p values
double[] array; //address of array to be loaded up
int slot; //slot number, for fnscl test
public static void main(String[] args) {
Gen g = new Gen();
//initialize Gen fields here..
Gen.gen4(g);
}
public static void fnscl(Gen g) {
}
public static void trans(double a, double alpha, double b, int n, double[] output) {
double delta = b - a;
if (output.length <= 1) {
output[0] = a;
return;
}
double interval = 1.0 / (output.length - 1);
if (alpha != 0) {
double denom = 1 / (1 - Math.exp(alpha));
for (int i = 0; i < output.length; i++) {
output[i] = a + (1 - Math.exp(i * alpha * interval)) * delta * denom;
}
} else {
for (int i = 0; i < output.length; i++) {
output[i] = a + i * delta * interval;
}
}
}
public static double gen4(Gen g) {
int i;
int points = 0;
int seglen = 0;
double factor;
double time[] = new double[MAX_POINTS];
double value[] = new double[MAX_POINTS];
double alpha[] = new double[MAX_POINTS];
double ptr[];
if (g.nargs < 5 || (g.nargs % 3) != 2) /*
* check number of args
*/ {
System.out.println("gen4 usage: t1 v1 a1 ... tn vn");
}
if ((g.nargs / 3) + 1 > MAX_POINTS) {
System.out.println("gen4 too many arguments");
}
for (i = points = 0; i < g.nargs; points++) {
time[points] = g.pvals[i++];
if (points > 0 && time[points] < time[points - 1]) {
System.out.println("gen4 non-increasing time values");
}
value[points] = g.pvals[i++];
if (i < g.nargs) {
alpha[points] = g.pvals[i++];
}
}
factor = (g.size - 1) / time[points - 1];
for (i = 0; i < points; i++) {
time[i] *= factor;
}
ptr = g.array;
for (i = 0; i < points - 1; i++) {
seglen = (int) (Math.floor(time[i + 1] + 0.5)
- Math.floor(time[i] + 0.5) + 1);
trans(value[i], alpha[i], value[i + 1], seglen, ptr);
ptr[i] += seglen - 1;
}
fnscl(g);
return 0.0;
}
}
In Java, stand alone methods are not allowed. You should make them member of some class. In your case, it seems that 2 of your methods are using class gen as argument fnscl() amd gen4(). You can make them as member methods. The other one can remain static within class.
public class gen{
// data ...
public void fnscl () { ... } // member method
public double gen4 () { ... } // member method
// static method
public static void trans(double a, double alpha, double b, int n, double[] output) { ... }
}
main() also should be part of some class. I leave that choice up to you.
Java is a fully object oriented language in terms of paradigms. (Not as c++ which is also procedural), that's why as Kerrek SB said all methods has to be declared and defined inside a class.
What he was mistaken is that a file can contain only one public class and it has to be named exactly as the file. But it can also contain any number non-public classes with arbitrary names.
To run the program, you have to first compile the file with javac [filename].java then run it with java [classname] without! .class
One more thing. You can't declare a method like this:
public void foo();
The compiler will consider it to be an abstract method and raise an error message.
I'm trying to write a function in Java that calculates the n-th root of a number. I'm using Newton's method for this. However, the user should be able to specify how many digits of precision they want. This is the part with which I'm having trouble, as my answer is often not entirely correct. The relevant code is here: http://pastebin.com/d3rdpLW8. How could I fix this code so that it always gives the answer to at least p digits of precision? (without doing more work than is necessary)
import java.util.Random;
public final class Compute {
private Compute() {
}
public static void main(String[] args) {
Random rand = new Random(1230);
for (int i = 0; i < 500000; i++) {
double k = rand.nextDouble()/100;
int n = (int)(rand.nextDouble() * 20) + 1;
int p = (int)(rand.nextDouble() * 10) + 1;
double math = n == 0 ? 1d : Math.pow(k, 1d / n);
double compute = Compute.root(n, k, p);
if(!String.format("%."+p+"f", math).equals(String.format("%."+p+"f", compute))) {
System.out.println(String.format("%."+p+"f", math));
System.out.println(String.format("%."+p+"f", compute));
System.out.println(math + " " + compute + " " + p);
}
}
}
/**
* Returns the n-th root of a positive double k, accurate to p decimal
* digits.
*
* #param n
* the degree of the root.
* #param k
* the number to be rooted.
* #param p
* the decimal digit precision.
* #return the n-th root of k
*/
public static double root(int n, double k, int p) {
double epsilon = pow(0.1, p+2);
double approx = estimate_root(n, k);
double approx_prev;
do {
approx_prev = approx;
// f(x) / f'(x) = (x^n - k) / (n * x^(n-1)) = (x - k/x^(n-1)) / n
approx -= (approx - k / pow(approx, n-1)) / n;
} while (abs(approx - approx_prev) > epsilon);
return approx;
}
private static double pow(double x, int y) {
if (y == 0)
return 1d;
if (y == 1)
return x;
double k = pow(x * x, y >> 1);
return (y & 1) == 0 ? k : k * x;
}
private static double abs(double x) {
return Double.longBitsToDouble((Double.doubleToLongBits(x) << 1) >>> 1);
}
private static double estimate_root(int n, double k) {
// Extract the exponent from k.
long exp = (Double.doubleToLongBits(k) & 0x7ff0000000000000L);
// Format the exponent properly.
int D = (int) ((exp >> 52) - 1023);
// Calculate and return 2^(D/n).
return Double.longBitsToDouble((D / n + 1023L) << 52);
}
}
Just iterate until the update is less than say, 0.0001, if you want a precision of 4 decimals.
That is, set your epsilon to Math.pow(10, -n) if you want n digits of precision.
Let's recall what the error analysis of Newton's method says. Basically, it gives us an error for the nth iteration as a function of the error of the n-1 th iteration.
So, how can we tell if the error is less than k? We can't, unless we know the error at e(0). And if we knew the error at e(0), we would just use that to find the correct answer.
What you can do is say "e(0) <= m". You can then find n such that e(n) <= k for your desired k. However, this requires knowing the maximal value of f'' in your radius, which is (in general) just as hard a problem as finding the x intercept.
What you're checking is if the error changes by less than k, which is a perfectly acceptable way to do it. But it's not checking if the error is less than k. As Axel and others have noted, there are many other root-approximation algorithms, some of which will yield easier error analysis, and if you really want this, you should use one of those.
You have a bug in your code. Your pow() method's last line should read
return (y & 1) == 1 ? k : k * x;
rather than
return (y & 1) == 0 ? k : k * x;