How to solve sine mathematic equation in java? - java

How to solve following mathematic equation in java?
Equation:
x + sin(x) = constant, where x is variable. I encountered this equation after 18 years. I forgot this basic concept. Please help me on this basic high school question.
I tried to code above equation x + sin(x) = constant as following, however, it is giving wrong answer. Please let me know where i am wrong.
public double balanceLength(double total_weight) {
// 5.00 assume inical value of x
return newtonRaphson( 5.00, total_weight);
}
private static double derivFunc(double x)
{
return sin(x) + x;
}
private static double func(double x, double weight)
{
return sin(x) + x - weight;
}
static double newtonRaphson(double x, double weight)
{
double h = func(x, weight) / derivFunc(x);
while (abs(h) >= EPSILON)
{
h = func(x, weight) / derivFunc(x);
x = x - h;
}
return round(x * 100.0) / 100.0 ;
}

This is a very basic implementation, only partially tested. It reruns x in radians, which satisfies y=six(x) +x for a given y :
//returned value in radians
static double evaluateSinxPlusx(double y){
double delta = y>0 ? 0.01 : -0.01 ;//change constants
double epsilon = 0.01; //to change
int iterations = 100; //accuracy
double x = 0;
double sum = 1;
while(Math.abs(y - sum) > epsilon) {
x+=delta;
//based Taylor series approximation
double term = 1.0;
sum = x;
double d = 1;
for (int i = 1; i< iterations; i++) {
term = Math.pow(x, i);
d*=i;
if (i % 4 == 1) {
sum += term/d;
}
if (i % 4 == 3) {
sum -= term/d;
}
}
}
return x;
}
//test it
public static void main(String[] args) throws Exception{
double y = 0.979;
//expected x = 0.5 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
y = -0.979;
//expected x = - 0.5 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
y = 0.33256;
//expected x = 0.16666 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
}
This is not a robust implementation and should be used as demo only.

Related

How can I get points from a two dimensional array in a circular pattern?

I'm just playing with Android Studio bitmaps and have created a dotted background for my application through iteration.
constant = 60;
int padding_X = (int) Math.floor((width % constant)/2f);
if (padding_X == 0) {
padding_X = (int) Math.floor(constant / 2);
}
int padding_Y = (int) Math.floor((height % constant)/2f);
if (padding_Y == 0) {
padding_Y = (int) Math.floor(constant/2);
}
System.out.println("padding X: "+padding_X);
System.out.println("padding Y: "+padding_Y);
int max_xn = Math.round((width-(padding_X*2)) / constant);
int max_yn = Math.round((height-(padding_Y*2)) / constant);
System.out.println("max xn: "+max_xn);
System.out.println("max yn: "+max_yn);
point_matrix = new int[max_xn+1][max_yn+1][2];
lens = new int[2];
for (int yn = 0; yn <= max_yn; yn++) {
int y = (int) (padding_Y + (yn*constant));
for (int xn = 0; xn <= max_xn; xn++) {
int x = (int) (padding_X + (xn*constant));
System.out.println("point # x: "+x+" y: "+y);
canvas.setPixel(x,y,Color.parseColor("#ffffff"));
point_matrix[xn][yn][0] = x;
point_matrix[xn][yn][1] = y;
}
}
runOnUiThread(() -> {
iv0.setImageBitmap(canvas);
});
lens[0] = max_xn+1;
lens[1] = max_yn+1;
I have also added each white pixel to a 3 dimensional array int[][][]. The array holds xn and yn for indexing the dots. Last array holds the coordinates onscreen. Example: {5, 1, {100,250}} 5 is the dots index on x axis, 1 is the index on y axis and 100 and 250 are coordinates on the bitmap.
I'm hoping to find a way for finding all dots on the 3 dim. array on a certain radius from the center.
A plan I had was iterating through all elements in the 3dim array and calculating the distance to the center with pythagoras theorem or something like that but that would be really inefficient seeing as this would have to be done multiple times.
The final plan is to have all of the dots to dissapear in a circular motion starting from the center. With a delay between each "radius interval".
Use trigonometric functions :)
static double i = 0;
static double pi = Math.PI;
static int q = 5; // half size of array
static double x;
static double y;
static double cx = 5; // offset center x
static double cy = 5; // offset center y
public static void main(String[] args) {
while (i < pi * 2) { // pi*2 is full angle of circle
x = Math.round (cx + Math.sin(i) * q);
y = Math.round (cy + Math.cos(i) * q);
System.out.print(String.format("X = %4f", x) + String.format("Y = %4f", y) + "\n");
i+=pi/180;
}
}

Saving a sequence of numbers to an array

There is a code for solving the Lorentz system, I need to save all the solutions x, y, z at each iteration in the corresponding array solutions, that is, 5000 solutions x, y, z put in an array, how is this best done? How to translate arrays to a string then?
public class Butterfly {
public static double dx(double x, double y, double z) {
return -10*(x - y);
}
public static double dy(double x, double y, double z) {
return -x*z + 28*x - y;
}
public static double dz(double x, double y, double z) {
return x*y - 8*z/3;
}
public static void main(String[] args) {
double x = 0.0, y = 20.0, z = 25.0; //
double dt = 0.001;
// uses Euler method
for (int i = 0; i < 5000; i++) {
//
double xnew = x + dx(x, y, z) * dt;
double ynew = y + dy(x, y, z) * dt;
double znew = z + dz(x, y, z) * dt;
x = xnew;
y = ynew;
z = znew;
double[][] xyzArray = new double[5000][3];
for (i = 0; i < xyzArray.length; i++) {
for (int j = 0; i < xyzArray.length; j++) {
xyzArray[i][j] = x;
}
}
for (i = 0; i < xyzArray.length; i++) {
for (int j = 0; i < xyzArray.length; j++) {
System.out.println(xyzArray[i][j]);
}
System.out.println();
}
}
}
}
Аfter editing the code the program displays 5000 times one value x, y, z, not all the values. I think that in this way lost the other solutions. After all, I have 5000 decisions of each variable, I need to save each...
// uses Euler method
double[][] xyzArray = new double[5000][3];
for (int i = 0; i < xyzArray.length; i++) {
for (i = 0; i < 5000; i++) {
double xnew = x + dx(x, y, z) * dt;
double ynew = y + dy(x, y, z) * dt;
double znew = z + dz(x, y, z) * dt;
xyzArray[i][0] = xnew;
xyzArray[i][1] = ynew;
xyzArray[i][2] = znew;
}
}
for (int i = 0; i < xyzArray.length; i++) {
System.out.println(xyzArray[i][0] + ", " + xyzArray[i][1] + ", " + xyzArray[i][2]);
}
}
after editing the following code is produced. 5,000 solutions of the first iteration are still output: it does not work in IDEAS or in jshell. I understand that the code is correct, but I can not understand why I get the wrong result
public class Butterfly {
public static double dx(double x, double y, double z) {
return -10 * (x - y);
}
public static double dy(double x, double y, double z) {
return -x * z + 28 * x - y;
}
public static double dz(double x, double y, double z) {
return x * y - 8 * z / 3;
}
public static void main(String[] args) {
double x = 0.0, y = 20.0, z = 25.0;
double dt = 0.001;
double[][] xyzArray = new double[5000][3];
for (int i = 0; i < xyzArray.length; i++) {
double xnew = x + dx(x, y, z) * dt;
double ynew = y + dy(x, y, z) * dt;
double znew = z + dz(x, y, z) * dt;
xyzArray[i][0] = xnew;
xyzArray[i][1] = ynew;
xyzArray[i][2] = znew;
}
for (int i = 0; i < xyzArray.length; i++) {
System.out.println(xyzArray[i][0] + ", " + xyzArray[i][1] + ", " + xyzArray[i][2]);
}
}
}
You've declared your array inside the loop. You don't want to create 5000 copies of your array of 5000 data points! You want only 1 array of 5000 data points, so you need to declare and create the array outside the loop.
double[][] xyzArray = new double[5000][3];
// uses Euler method
for (int i = 0; i < xyzArray.length; i++) {
// ... compute xnew, ynew, znew ... etc ...
Once you've got your new values for the current step, you want to save them in the [i]-th entry of your array. You'll store x in the [i][0] sub-entry, y in the [i][1] sub-entry, and z in the [i][2] sub-entry.
xyzArray[i][0] = xnew;
xyzArray[i][1] = ynew;
xyzArray[i][2] = znew;
To print the values out after all values have been computed:
} // end of Euler method loop
for (int i = 0; i < xyzArray.length; i++) {
System.out.println(xyzArray[i][0] + ", " + xyzArray[i][1] +", " + xyzArray[i][2]);
}
Your revision 3 code works.
View your revision 3 code
Copy the program text
Paste it in a jshell
Execute it with Butterfly.main(new String[] {})
And you will see your 5000 x,y,z values -- all different.
C:\>"\Program Files\Java\jdk-10\bin\jshell.exe"
| Welcome to JShell -- Version 10
| For an introduction type: /help intro
jshell> public class Butterfly {
...>
...> public static double dx(double x, double y, double z) {
...> return -10*(x - y);
[... many lines omitted for brevity ...]
...> }
...> }
...> }
| created class Butterfly
jshell> Butterfly.main(new String[] {})
0.2, 19.98, 24.933333333333334
0.39780000000000004, 19.960633333333334, 24.870840444444443
0.5934283333333333, 19.9419174796712, 24.81245854319926
0.786913224796712, 19.92386713960567, 24.758126085937494
[... many lines omitted for brevity ...]
0.381817425662861, 0.5879585365342771, 12.654916756967012
0.38387883677157514, 0.59322959817818, 12.621394805096582
0.3859723443856412, 0.5985398896533907, 12.587965480571079
0.3880980198383187, 0.6038899688589537, 12.554628592467306
jshell>

Trying to calculate sunrise...ain't getting the right answer

This is my current code:
public class Sunpos {
final private double Pi = Math.PI;
final private double eul = 2.71828182845904523552 ;
final private double sonauf = 90;
final private double RAD = 0.017453292519943295769236907684886;
public double sunrisefinal (double Breitengrad, double Laengengrad, int tagzahl, int sommerzeit, int nacht) {
double lngHour = Laengengrad/15;
double t = tagzahl + ((6 - lngHour)/24);
// double ab = tagzahl + ((18 - lngHour)/24);
double M = (0.9856 * t) - 3.289;
double L = M + (1.916 * Math.sin(M)) + (0.020 * Math.sin(2 * M)) + 282.634;
if (L >= 359) { L -= 360; }
else if (L < 0) { L += 360; }
double RA = (Math.atan(0.91764 * Math.tan(Pi/180)*L));
if (RA >= 359) { RA -= 360; }
else if (RA < 0) { RA += 360; }
double Lquadrant = (Math.floor(L/90)*90);
double RAquadrant = (Math.floor(RA/90))*90;
RA = RA + (Lquadrant - RAquadrant);
RA = RA/15;
double sinDec = 0.39782 * Math.sin((Pi/180)*L);
double cosDec = (180/Pi)*(Math.cos(Math.asin(sinDec)));
double cosH = (Math.cos((Pi/180)*sonauf)-(sinDec*Math.sin((Pi/180)*Breitengrad)))/(cosDec * Math.cos((Pi/180)*Breitengrad));
double H = 360 - Math.acos(cosH);
H /= 15;
double T = H + RA -(0.06571 * t) - 6.622;
double UTC = T - lngHour;
if (UTC >= 23) { UTC -= 24; }
else if (UTC < 0) { UTC += 24; }
double locTime = UTC; // Fuer die schweiz!
System.out.println(locTime);
return(0);
}
The inputs are the following: ( 50, 10, 294, 1, 0). The last 2 can be ignored.
Now I am basing this on the following page:
http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
The code should be complete according to the site, but I don't get anywhere near the supposed results. I should get around 7.5 for today but I'm getting a 9.358.
Now, that might be because something with radiants/degrees? I can't quite get my Mind into that, as I've been trying to insert those converters (Pi/180) into the code, without any usable result.
Can anyone tell me where to put them or point me in the right direction? I've spent waaaay too much time on this already, and now I'm so close.
I'll just post my implementation here in case people need it (ported from the same source as yours)
https://gist.github.com/zhong-j-yu/2232343b14a5b5ef5b9d
public class SunRiseSetAlgo
{
static double calcSunrise(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, true);
}
static double calcSunset(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, false);
}
// http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
static double calc(int dayOfYear, double localOffset, double latitude, double longitude, boolean rise)
{
//1. first calculate the day of the year
// int N1 = floor(275 * month / 9.0);
// int N2 = floor((month + 9) / 12.0);
// int N3 = (1 + floor((year - 4 * floor(year / 4.0) + 2) / 3.0));
// int N = N1 - (N2 * N3) + day - 30;
int N = dayOfYear;
//2. convert the longitude to hour value and calculate an approximate time
double lngHour = longitude / 15;
double t = rise?
N + (( 6 - lngHour) / 24) :
N + ((18 - lngHour) / 24);
//3. calculate the Sun's mean anomaly
double M = (0.9856 * t) - 3.289;
//4. calculate the Sun's true longitude
double L = M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634;
L = mod(L, 360);
//5a. calculate the Sun's right ascension
double RA = atan(0.91764 * tan(L));
RA = mod(RA, 360);
//5b. right ascension value needs to be in the same quadrant as L
double Lquadrant = (floor( L/90)) * 90;
double RAquadrant = (floor(RA/90)) * 90;
RA = RA + (Lquadrant - RAquadrant);
//5c. right ascension value needs to be converted into hours
RA = RA / 15;
//6. calculate the Sun's declination
double sinDec = 0.39782 * sin(L);
double cosDec = cos(asin(sinDec));
//7a. calculate the Sun's local hour angle
double zenith = 90 + 50.0/60;
double cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude));
if (cosH > 1)
throw new Error("the sun never rises on this location (on the specified date");
if (cosH < -1)
throw new Error("the sun never sets on this location (on the specified date");
//7b. finish calculating H and convert into hours
double H = rise?
360 - acos(cosH) :
acos(cosH);
H = H / 15;
//8. calculate local mean time of rising/setting
double T = H + RA - (0.06571 * t) - 6.622;
//9. adjust back to UTC
double UT = T - lngHour;
//10. convert UT value to local time zone of latitude/longitude
double localT = UT + localOffset;
localT = mod(localT, 24);
return localT;
}
static int floor(double d){ return (int)Math.floor(d); }
static double sin(double degree)
{
return Math.sin(degree*Math.PI/180);
}
static double cos(double degree)
{
return Math.cos(degree*Math.PI/180);
}
static double tan(double degree)
{
return Math.tan(degree*Math.PI/180);
}
static double atan(double x)
{
return Math.atan(x) *180/Math.PI;
}
static double asin(double x)
{
return Math.asin(x) *180/Math.PI;
}
static double acos(double x)
{
return Math.acos(x) *180/Math.PI;
}
static double mod(double x, double lim)
{
return x - lim * floor(x/lim);
}
}
Everone seems to link to this http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
which doesn't exist anymore. Why not try something that gets updated once in a while like https://en.wikipedia.org/wiki/Sunrise_equation
Then if you like you could help edit it to make it better.

How to find correlation between two integer arrays in java

I am searching a lot but could not find exactly what i need till now.
I have two integer arrayas int[] x and int[] y. I want to find simple linear correlation between these two integer arrays and it should return the result as double. In java do you know any library function providing this or any code snippet?
There is nothing in core Java. There are libraries out there you can use. Apache Commons has a statistical project, check PearsonCorrelation class.
Sample code:
public static void main(String[] args) {
double[] x = {1, 2, 4, 8};
double[] y = {2, 4, 8, 16};
double corr = new PearsonsCorrelation().correlation(y, x);
System.out.println(corr);
}
prints out 1.0
Correlation is quite easy to compute manually:
http://en.wikipedia.org/wiki/Correlation_and_dependence
public static double Correlation(int[] xs, int[] ys) {
//TODO: check here that arrays are not null, of the same length etc
double sx = 0.0;
double sy = 0.0;
double sxx = 0.0;
double syy = 0.0;
double sxy = 0.0;
int n = xs.length;
for(int i = 0; i < n; ++i) {
double x = xs[i];
double y = ys[i];
sx += x;
sy += y;
sxx += x * x;
syy += y * y;
sxy += x * y;
}
// covariation
double cov = sxy / n - sx * sy / n / n;
// standard error of x
double sigmax = Math.sqrt(sxx / n - sx * sx / n / n);
// standard error of y
double sigmay = Math.sqrt(syy / n - sy * sy / n / n);
// correlation is just a normalized covariation
return cov / sigmax / sigmay;
}

Perlin noise value range

I used perlin noise to generate a 2D height map. At first i tried some parameters manually and found a good combination of amplitude, persistence,... for my job.
Now that i'm developing the program, i added the feature for user to change the map parameters and make a new map for himself but now i see that for certain parameters (Mostly octaves and frequency) the values are not in the range i used to see. I thought that if a set Amplitude = 20, the values(heights) i get from it will be in e.g [0,20] or [-10,10] or [-20,20] ranges but now i see that Amplitude is not the only parameter that controls output range.
My question is: Is there an exact mathematical formula (a function of Amplitude, Octaves, Frequency and persistence) to compute the range or i should take a lot of samples (like 100,000) and check minimum and maximum values of them to guess the aproximate range?
Note: The following code is an implementation of perlin noise that one of stackoverflow guys worte it in C and i ported it to java.
PerlinNoiseParameters.java
public class PerlinNoiseParameters {
public double persistence;
public double frequency;
public double amplitude;
public int octaves;
public int randomseed;
public PerlinNoiseParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
this.ChangeParameters(persistence, frequency, amplitude, octaves, randomseed);
}
public void ChangeParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
this.persistence = persistence;
this.frequency = frequency;
this.amplitude = amplitude;
this.octaves = octaves;
this.randomseed = 2 + randomseed * randomseed;
}
}
PerlinNoiseGenerator.java
public class PerlinNoiseGenerator {
PerlinNoiseParameters parameters;
public PerlinNoiseGenerator() {
}
public PerlinNoiseGenerator(PerlinNoiseParameters parameters) {
this.parameters = parameters;
}
public void ChangeParameters(double persistence, double frequency, double amplitude, int octaves, int randomseed) {
parameters.ChangeParameters(persistence, frequency, amplitude, octaves, randomseed);
}
public void ChangeParameters(PerlinNoiseParameters newParams) {
parameters = newParams;
}
public double get(double x, double y) {
return parameters.amplitude * Total(x, y);
}
private double Total(double i, double j) {
double t = 0.0f;
double _amplitude = 1;
double freq = parameters.frequency;
for (int k = 0; k < parameters.octaves; k++) {
t += GetValue(j * freq + parameters.randomseed, i * freq + parameters.randomseed)
* _amplitude;
_amplitude *= parameters.persistence;
freq *= 2;
}
return t;
}
private double GetValue(double x, double y) {
int Xint = (int) x;
int Yint = (int) y;
double Xfrac = x - Xint;
double Yfrac = y - Yint;
double n01 = Noise(Xint - 1, Yint - 1);
double n02 = Noise(Xint + 1, Yint - 1);
double n03 = Noise(Xint - 1, Yint + 1);
double n04 = Noise(Xint + 1, Yint + 1);
double n05 = Noise(Xint - 1, Yint);
double n06 = Noise(Xint + 1, Yint);
double n07 = Noise(Xint, Yint - 1);
double n08 = Noise(Xint, Yint + 1);
double n09 = Noise(Xint, Yint);
double n12 = Noise(Xint + 2, Yint - 1);
double n14 = Noise(Xint + 2, Yint + 1);
double n16 = Noise(Xint + 2, Yint);
double n23 = Noise(Xint - 1, Yint + 2);
double n24 = Noise(Xint + 1, Yint + 2);
double n28 = Noise(Xint, Yint + 2);
double n34 = Noise(Xint + 2, Yint + 2);
double x0y0 = 0.0625 * (n01 + n02 + n03 + n04) + 0.1250
* (n05 + n06 + n07 + n08) + 0.2500 * n09;
double x1y0 = 0.0625 * (n07 + n12 + n08 + n14) + 0.1250
* (n09 + n16 + n02 + n04) + 0.2500 * n06;
double x0y1 = 0.0625 * (n05 + n06 + n23 + n24) + 0.1250
* (n03 + n04 + n09 + n28) + 0.2500 * n08;
double x1y1 = 0.0625 * (n09 + n16 + n28 + n34) + 0.1250
* (n08 + n14 + n06 + n24) + 0.2500 * n04;
double v1 = Interpolate(x0y0, x1y0, Xfrac);
double v2 = Interpolate(x0y1, x1y1, Xfrac);
double fin = Interpolate(v1, v2, Yfrac);
return fin;
}
private double Interpolate(double x, double y, double a) {
double negA = 1.0 - a;
double negASqr = negA * negA;
double fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA);
double aSqr = a * a;
double fac2 = 3.0 * aSqr - 2.0 * (aSqr * a);
return x * fac1 + y * fac2;
}
private double Noise(int x, int y) {
int n = x + y * 57;
n = (n << 13) ^ n;
int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff;
return 1.0 - (double) t * 0.931322574615478515625e-9;
}
}
The range of a single perlin noise step is:
http://digitalfreepen.com/2017/06/20/range-perlin-noise.html
-sqrt(N/4), sqrt(N/4)
With N being the amount of dimensions. 2 in your case.
Octaves, persistence and amplitude add on top of that:
double range = 0.0;
double _amplitude = parameters.;
for (int k = 0; k < parameters.octaves; k++) {
range += sqrt(N/4) * _amplitude;
_amplitude *= parameters.persistence;
}
return range;
There might be some way to do this as a single mathematical expression. Involving pow(), but by brain fails me right now.
This is not a problem with octaves and frequency affecting amplitude, not directly at least. It is a problem with integer overflow. Because you introduce your random seed by adding it to the the x and y co-ordinates (which is unusual, I don't think this is the usual implimentation)
t += GetValue(j * freq + parameters.randomseed, i * freq + parameters.randomseed)* _amplitude;
And random seed could be huge (possibly the near full size of the int) because
this.randomseed = 2 + randomseed * randomseed;
So if you input large values for j and i you end up with the doubles that are passed through at GetValue(double x, double y) being larger than the maximum size of int, at that point when you call
int Xint = (int) x;
int Yint = (int) y;
Xint and YInt won't be anything like x and y (because x and y could be huge!) and so
double Xfrac = x - Xint;
double Yfrac = y - Yint;
could be much much larger that 1, allowing values not between -1 and 1 to be returned.
Using reasonable and small values my ranges using your code are between -1 and 1 (for amplitude 1)
As an asside, in java usually method names are methodName, not MethodName
If its useful please find annother java implimentation of perlin noise here:
http://mrl.nyu.edu/~perlin/noise/

Categories

Resources