I'm trying to make a program in Java to calculate the formula for the Ricker wavelet:
But the results are not matching to the real ones.
This is what I'm using:
private static double rickerWavelet(double t, double f){
double p = (Math.pow(Math.PI, 2))*(Math.pow(f, 2))*(Math.pow(t, 2));
double lnRicker = 1 - (2 * p) * Math.exp(-p);
return lnRicker;
}
Am I using the Math functions wrongly?
To match the formula,
double lnRicker = 1 - (2 * p) * Math.exp(-p);
needs to be
double lnRicker = (1 - (2 * p)) * Math.exp(-p);
Since * has higher operator precedence than -, in your expression the multiplication of (2 * p) with Math.exp(-p) will be done first, which is not what you want.
I'd just like to add that Math.pow(x, 2) can be written more simply (and possibly more accurately and more efficiently) as x * x ... for any variable or constant x.
Look at your executing equation if you know about BODMAS method:
You should do: (1-(2*p))* Math.exp(-p);
I just changed your equation by inserting round brackets around 1-2*p..
Related
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 11 months ago.
I'm trying to code an implementation of the fixed iteration algorithm in java - using java because that's what I'm most comfortable with at the moment, although I imagine that there'd be languages more suited to this purpose than java.
My base function is f(x) = x^4 + 2x^2 - x - 3 and for fixed point iteration, this changes to g(x) = ((x + 3 - x^4)/2)^(1/2).
This is my code snippet for the function in java:
'''
public static double function(double x) {
return Math.pow(((3 + x - Math.pow(x, 4))/2) , 1/2);
}
'''
My problem is that when I input an x value of 1.0 into the function, I get a value out of the function of 1.0, which is incorrect because the value should be 1.2247...
I need help with why this function is returning an incorrect value - or is there something that I'm doing which isn't right?
That 1/2 at the end will hurt you. You should consider using double parameters instead.
I'd suggest you changing 1/2 with 0.5, and even if you want to go safer instead of doing:
((3 + x - Math.pow(x, 4))/2
you could go with
((3 + x - Math.pow(x, 4))*0.5
It might be treating your double as an int and that's why you lose precision - can you try typecasting the hardcoded values as double?
Something like this:
public static double function(double x) {
double a = 3.0;
double b = 4.0;
double c = 0.5;
return Math.pow(((a + x - Math.pow(x, b))*c) , c);
}
In a problem that I am practicing, the goal is to write the quadratic expression, then round it to the thousandths place. Here is the desired output:
1(a variable) 6(b variable) 3(c variable)
4(a variable) 10(b variable) 6.1(c variable)
Output:
-0.551, -5.449 (answer for top line)
-1.056, -1.444 (answer for bottom line)
The question is not about how to solve the problem, but instead the answers that I am getting. When computing the quadratic equation as follows:
double a = scan.nextDouble();
double b = scan.nextDouble();
double c = scan.nextDouble();
//equation is correct
double answer1 = 0.001 * Math.floor((-b + Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a)* 1000.0) ;
double answer2 = 0.001 * Math.floor((-b - Math.sqrt(Math.pow(b, 2) - (4 * a * c))) / (2 * a) * 1000.0);
The answers I am getting are correct, except when I start the rounding to the thousandths place, some numbers are right and others are not even though it looks like they are rounding correctly just not according to the problem.
My Output:
-0.551, -5.45
-1.057, -1.444
Is this something to do with how I am rounding? Any help on understanding this rounding issue would be appreciated :)
https://floating-point-gui.de/languages/java/
How to Round
To get a String:
String.format("%.2f", 1.2399) // returns "1.24"
String.format("%.3f", 1.2399) // returns "1.240"
String.format("%.2f", 1.2) // returns "1.20"
To print to standard output (or any PrintStream):
System.out.printf("%.2f", 1.2399) // same syntax as String.format()
If you don’t want trailing zeroes:
new DecimalFormat("0.00").format(1.2)// returns "1.20"
new DecimalFormat("0.##").format(1.2)// returns "1.2"
If you need a specific rounding mode:
new BigDecimal("1.25").setScale(1, RoundingMode.HALF_EVEN); // returns 1.2
And if you do need to round the actual number not just the printed output:
double result = Math.round(value * scale) / scale;
where scale might be fixed at 1000 for three decimal places or calculated for an arbitrary number of decimal places:
int scale = (int) Math.pow(10, precision);
public class P2A7 {
public static void main(String[] args) {
String name = args[0];
int weight = Integer.parseInt(args[1]);
double length = Double.parseDouble(args[2]);
double bmi = weight / length * length;
System.out.println(bmi);
}
}
Passing java Name 80 1.9 from the command line gives the output "80".
Why are the division and multiplication completely ignored?
Putting parentheses around "length * length" fixes this.
#Kristjan Link, This is because precedence of operator, when you write weight / (length * length) you increase precedence of multiplication *, because precedence of operator inside parentheses is always more than operator outside parentheses
Use of parentheses fix it because it increases precedence of * operator. By using parentheses you explicitly give * more precedence than / that's why multiplication expression will be executed first due to its increased precedence other wise both * and / have same precedence.
NOTE:
but remember despite same precedence / execute first than * because it comes first. Just like () is way to increase precedence, shifting position of operator is another way increase or decrease precedence of operators.The table present here. will be helpful for you in this regard.
Because double bmi = weight / length * length = weight is not same as double bmi= weight / (length * length)
In the first case, You are ending up getting the same result as you are not using any parenthesis.
/ and * have equal precedence, so weight / length * length means (weight / length) * length
Because / has higher precedence than . Hence, your code just performs divide and multiply by length which returns weight. () has higher precedence than / and hence the code inside () will execute first which results in weight multiplied by lengthlength
When writing a method in java, I noticed that these two functions return the same value.
// Riemann-Siegel theta function using the approximation by the Stirling series
public static double theta (double t) {
return (t/2.0 * StrictMath.log(t/2.0/StrictMath.PI) - t/2.0
- StrictMath.PI/8.0 + 1.0/48.0/t + 7.0/5760.0/t/t/t);
}
// Riemann-Siegel theta function using the approximation by the Stirling series
public static double theta2 (double t) {
return (t/2.0 * Math.log(t/(2.0*Math.PI)) - t/2.0
- Math.PI/8.0 + 1.0/(48.0*Math.pow(t, 1)) + 7.0/(5760*Math.pow(t, 3)));
}
What is
7.0/5760.0/t/t/t
doing? Why is this the same as 7.0/(5760*t^3)?
the expression 7.0/5760.0/t1/t2/t3 will be computed from L-R.
like-
r=(7.0/5760.0)
r1=(result/t1)
r2=(r1/t2)
r3=(r2/t3)
and r3 is your final result
if you have expression like 8/2*2*2 it will be calculated as same i've explained earlier but in 8/2*(2*2) expression (2*2) will be calculated first because perathesis has higher priority then /.
it is also aplly in case of math.pow() function because functions also have the higher priority the operators.
I'm trying to create a program in Java to calculate the inside angles of any triangle when the user inputs the side lengths. I've seen a few questions similar to this but I can`t get mine to work.
I want this to calculate the angle in degrees but it keeps giving me the wrong answer or not a number (NaN). I've tried putting it all in to one equation in case it was just rounding errors but it just gave the same answer. I've since put it back into this format to make it easier to read.
public class Triangles
{
// variables already declared and user inputs double sideOne, sideTwo, sideThree
threeSq=sideThree*sideThree;
twoSq=sideTwo*sideTwo;
oneSq=sideOne*sideOne;
public static double getAngleOne(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angOne;
angOne = (oneSq + twoSq - threeSq) / (2 * sideOne * sideTwo);
angOne = Math.toRadians(angOne);
angOne = Math.acos(angOne);
angOne = Math.toDegrees(angOne);
return angOne;
}
public static double getAngleTwo(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angTwo;
angTwo = (twoSq + threeSq - oneSq) / (2 * sideTwo * sideThree);
angTwo = Math.toRadians(angTwo);
angTwo = Math.acos(angTwo);
angTwo = Math.toDegrees(angTwo);
return angTwo;
}
public static double getAngleThree(double oneSq, double twoSq, double threeSq, double sideOne, double sideTwo, double sideThree)
{
double angThree;
angThree = (oneSq + threeSq - twoSq) / (2 * sideOne * sideThree);
angThree = Math.toRadians(angThree);
angThree = Math.acos(angThree);
angThree = Math.toDegrees(angThree);
return angThree;
}
}
I`m using the cosine law, but it is not giving me the correct answer. For example, when I input the side lengths as 3, 3 and 3 it gives me 71.68993312052173; when I input 5, 6 and 7 (sides 1, 2 and 3 respectively), I get NaN.
edit:
Thanks for the advice, I have changed all the ints to doubles and my math was the problem (forgot brackets around the oneSq + twoSq - threeSq)
I put up the full revised code but it is still giving the wrong answer, for a triangle with all sides the same, it should return 60 for all three but it`s returning 89.49999365358626.
After correcting the computation of the ratios there still remains one thing to do: Lose the lines
angOne = Math.toRadians(angOne);
at this point, angOne does not contain any angle. If the sides obey the triangle inequality, angOne should at that point contain a number between -1 and 1 that does not need converting.
The ratio of the areas for an equilateral triangle is 0.5. The operations convert-to-radians, acos, convert-to-degrees can be combined as
M*acos(x/M) = M*(pi/2-asin(x/M)),
with the multiplier M=180/pi. Since x/M is small, the result is approximately
M*(pi/2-x/M)=90-x,
resulting in a value close to 89.5, as obtained in your last trial.
Of course, the desired result is M*acos(0.5)=M*(pi/3)=60.
Apart from not using double values, your calculations are probably not correct.
According to cosine law
cosγ = (a^2 + b^2 - c^2)/2ab
so change ang = oneSq + threeSq - twoSq / (2 * sideOne * sideThree); to
double ang = (oneSq + twoSq - threeSq)*1.0 / (2 * sideOne * sideTwo);