I'm having difficulty even beginning to solve this problem. All examples that I have found are either too simple or way too complex to digest.
I want to to find the value S given a series of inputs. The function is univariate but non-linear. S will always be between -3 .. 3.
I would like to use the Apache Commons library, as I have had prior experience in other sections of that code.
For each time I want to solve my problem, I know the following information:
double R =250.0;
double om1 = 5.0;
double om2 = 15.0;
double th21 = 29.07965;
double th22 = 29.69008;
double D_obs = th21 - th22;
The actual values will change between solutions, but they are fixed for any one particular solution.
The value I want to find is:
double S = 0.0;
such that
double d1 = delta(R,om1,th21,S);
double d2 = delta(R,om2,th22,S);
double D_calc = d1 - d2;
have values to make
double minme = Math.abs(D_obs - D_calc);
a minimum, or alternately, solve
double minme = D_obs - D_calc;
where minme=0.
The function delta is defined as
public static double delta(double R, double om, double th2, double s)
{
if(Math.abs(s) <= 0.0001) //is the displacement == 0?
{
return 0.0;
}
else
{
return Math.toDegrees((-1*Cos(th2)*s-R*Sin(om)+Sqrt(-1*Math.pow(Cos(th2),2)*Math.pow(s,2)+2*Cos(th2)*Sin(om)*R*s-Math.pow(Cos(om),2)*Math.pow(R,2)+Math.pow(R,2)+2*Math.pow(s,2)))/(Sin(th2)*s));
}
}
where, for example, Cosis defined elsewhere as Math.cos(Math.toRadians(val))
Where/what can I read/do to get a start on this problem?
I found an answer I could work with: Newton-Raphson method using the Math.Commons library
The key code is
public static void main(String args[])
{
//setup all variables
final double R =(new Double(args[0])).doubleValue(); //=250.0;
final double om1 =(new Double(args[1])).doubleValue(); //= 5.0;
final double om2 =(new Double(args[2])).doubleValue(); //= 15.0;
final double th21=(new Double(args[3])).doubleValue(); //= 29.07965;
final double th22=(new Double(args[4])).doubleValue(); //= 29.69008;
final double D_obs = th21 - th22;
BisectionSolver solver = new BisectionSolver();
UnivariateFunction f = new UnivariateFunction()
{
public double value(double s) {
return ((delta(R,om1,th21,s)-delta(R,om2,th22,s)) - (D_obs));
}
};
System.out.printf("The speciment offset is %.3f mm.\n", solver.solve(1000, f, -3, 3));
}
Related
The formula to calculate the area of a circumference is defined as x =
π . R2. Considering to this problem that π = 3.14159:
Calculate the area using the formula given in the problem description.
Input The input contains a value of floating point (double precision),
that is the variable R.
And for an input of 2, I should be getting x=12.5664 rounded by one number.
I tried using this simple code, but I couldn't remember what to do with the "cannot convert from double to float" error. It's been half a year since I coded.
package TEST;
import java.util.Scanner;
public class TEST {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// let A be radius
float A = scanner.nextFloat();
float A_2 = A * A;
// let B be Pi
double B = 3.14159;
// let x be circumference
float x = A_2 * B;
System.out.printf("x= %.4f" + x);
}}
The cause of the compilation error is the following assignment:
float x = A_2 * B;
where B is of type, double and therefore the result of the product will of type, double which can not be accommodated into a variable of type, float. Remember: double requires 8 bytes of space whereas a float variable can accommodate only 4 bytes.
After correcting this compilation error, you will encounter a runtime error because you have used a plus sign (+) instead of a comma (,) inside the printf statement.
Apart from this,
Always follow Java naming conventions e.g. A should be a and A_2 should be a2 following the conventions.
You can use Math.PI instead of using your own value for PI.
The following code incorporates these changes:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// let a be radius
float a = scanner.nextFloat();
float a2 = a * a;
// let b be PI
double b = Math.PI;
// let x be circumference
double x = a2 * b;
System.out.printf("x= %.4f", x);
}
}
A sample run:
2
x= 12.5664
You could try:
double A_2Converted = (double) A_2;
and use that.
source: Convert float to double without losing precision
I have to create a code that, given the polygon name and its vertex coordinates, prints the perimeter. Even if I change the input values, it always print 5.0 . What am I doing wrong?
I tried using a for loop and print the length of every side of a triangle, but the result is still 5.0 and printed just once. Now I tried to print the recursive sum at every step but no results
public static void main(String[] args) {
int i;
double result = 0;
double x1 = Double.valueOf(args[1]);
double y1 = Double.valueOf(args[2]);
Punto p1 = new Punto(x1, y1);
double x2 = Double.valueOf(args[3]);
double y2 = Double.valueOf(args[4]);
Punto p2 = new Punto(x2, y2);
double x3 = Double.valueOf(args[5]);
double y3 = Double.valueOf(args[6]);
Punto p3 = new Punto(x3, y3);
Punto[] punti = {p1, p2, p3};
Poligono A = new Poligono(args[0], punti);
for (i = 0; i < punti.length - 1; i++) {
double xa = Punto.getX(punti[i++]);
double xb = Punto.getX(punti[i]);
double ya = Punto.getY(punti[i++]);
double yb = Punto.getY(punti[i]);
result = result + Math.sqrt(Math.pow(Math.abs(xa - xb), 2) + Math.pow(Math.abs(ya - yb), 2));
System.out.println(result);
}
}
(Punto means point) The right answer is 12, but it always prints 5 and just once
You should probably replace double xa = Punto.getX(punti[i++]); with double xa = Punto.getX(punti[i + 1]); so that you don't modify i as it is used to iterate through the array.
The correct answer to your question is already there by #devgianlu!
However, I would like to add that, when something apparently not-reasonable happens, try to debug your code (executing step by step the lines, for example). You will discover that the machine always does what we say to do. Sometimes we think to declare a specific task but, in reality, we are declaring unintentionally something else.
As said in the title, my problem is that my perlin noise is showing clear lines between the unit squares instead of flowing smoothly. My code, which is very basic, is shown below. It is based on the simple explanation from this site: http://flafla2.github.io/2014/08/09/perlinnoise.html
int grads[][] = {
{1,0},{0,1},{-1,0},{0,-1},
{1,1},{-1,1},{1,-1},{-1,-1}
};
public double perlin (double x, double y) {
int unitX = (int)Math.floor(x) & 255; // decide unit square
int unitY = (int)Math.floor(y) & 255; // decide unit square
double relX = x-Math.floor(x); // relative x position
double relY = y-Math.floor(y); // relative y position
//System.out.print(unitX + " " + unitY + " ");
// bad pseudorandom gradient
int units = unitX+unitY;
//System.out.println(units + " added ");
int[] gradTL = grads[(units)%8];
int[] gradTR = grads[(units+1)%8];
int[] gradBL = grads[(units+1)%8];
int[] gradBR = grads[(units+2)%8];
// distance from edges to point, relative x and y inside the unit square
double[] vecTL = {relX,relY};
double[] vecTR = {1-relX,relY};
double[] vecBL = {relX,1-relY};
double[] vecBR = {1-relX,1-relY};
double tl = dot(gradTL,vecTL);
double tr = dot(gradTR,vecTR);
double bl = dot(gradBL,vecBL);
double br = dot(gradBR,vecBR);
double u = fade(relX);
double v = fade(relY);
double x1 = lerp(tl,tr,u);
double y1 = lerp(bl,br,u);
return lerp(x1,y1,v);
}
public double dot(int[] grad, double[] dist) {
return (grad[0]*dist[0]) + (grad[1]*dist[1]);
}
public double lerp(double start, double end, double rate){
return start+rate*(end-start);
}
public double fade(double t) {
return t*t*t*(t*(t*6-15)+10);
}
I am using a flow field to visualize the noise, which I know is probably just overcomplicated but it is the end goal of this project. Example As you can see, there are obvious lines that are showing the grid of the perlin noise.
Here is what I'm inputting into the function.
double val = p.perlin((x/width)*2, (y/height)*2);
I want to try and make the noise flow smoothly between the unit squares. Also yes, I understand that simplex noise is considered to be better, but I am not trying to make perlin noise, not simplex noise.
This part looks wrong to me:
// distance from edges to point, relative x and y inside the unit square
double[] vecTL = {relX,relY};
double[] vecTR = {1-relX,relY};
double[] vecBL = {relX,1-relY};
double[] vecBR = {1-relX,1-relY};
I think you want
double[] vecTL = {relX,relY};
double[] vecTR = {relX-1,relY};
double[] vecBL = {relX,relY-1};
double[] vecBR = {relX-1,relY-1};
So, I don't know whether I've implemented this incorrectly, or whether it's a feature of this kind of filter; but, I'd been trying to apply a peak filter to an audio signal and it wasn't working.
Some testing revealed that it wasn't filtering for the frequency I selected; but a nearby value, some of which are powers of 2, so, eg, filtering 4KHz actually filtered 4096Hz.
Here's the filter (it's from http://dspguide.com/ch19/3.htm):
SAMPLE_RATE is 88*1024
class Coefficients {
double a0=0;
double a1=0;
double a2=0;
double twoCos2piFreq=0;
double b1=0;
double b2=0;
double K=0;
double R=0;
double rSquared=0;
public Coefficients(double freq, double bandwidth)
{
twoCos2piFreq=2*Math.cos(2*Math.PI*freq);
R=1-(3*bandwidth);
rSquared=R*R;
K=(1-(R*twoCos2piFreq)+rSquared)/(2-twoCos2piFreq);
b1=R*twoCos2piFreq;
b2=-rSquared;
}
// ----------------------------------------------------------------
// Source x, result y
// y[i]=a0*x[i] + a1*x[i-1] + a2*x[i-2] + b1*y[i-1] + b2*y[i-2]
private void recursiveFilter(float[] x, float[] y)
{
double x_2 = 0.0f; // delayed x, y samples
double x_1 = 0.0f;
double y_2 = 0.0f;
double y_1 = 0.0f;
for (int i = 0; i < x.length; ++i){
double xi=x[i];
double yi=a0*xi + a1*x_1 + a2*x_2 + b1*y_1 + b2*y_2;
x_2 = x_1; // shift delayed x, y samples
y_2 = y_1;
x_1 = xi;
y_1 = yi;
y[i] = (float)yi;
}
}
// ------------------------------------------------------------
public float[] filtered(float[] signal)
{
float[] result=new float[signal.length];
recursiveFilter(signal,result);
return result;
}
}
// ----------------------------------------------------------------
class BandPassCoefficients extends Coefficients
{
public BandPassCoefficients(double freq, double bandwidth)
{
super(freq/(double)SAMPLE_RATE,bandwidth/(double)SAMPLE_RATE);
a0=1-K;
a1=(K-R)*twoCos2piFreq;
a2=rSquared-K;
}
}
and to test it, I fill a buffer with a sine wave of a range of frequencies, one at a time, apply the filter and measure the highest amplitude in the result.
Fairly obvious code, but here it is:
// ----------------------------------------------------------------
private void genTestSignal(float freq)
{
float[] leftSignal=createSinWaveBuffer(freq,ONE_SECOND);
float[] rightSignal=createSinWaveBuffer(freq,ONE_SECOND);
denormalise( leftSignal ,inputSignal, LEFT_CHANNEL);
denormalise(rightSignal,inputSignal,RIGHT_CHANNEL);
}
The denormalise and normalise functions just convert to and from interleaved signed 16-bit values to single channel floats.
This samples the start of the signal, to find the largest absolute magnitude:
private void findOptimalFreq(float[] signal, float freq)
{
float maxAmplitude=0;
int peak=0;
for(int i=(int)freq/2; i<(int)freq*3/2; i+=2){
BandPassCoefficients signalFilter=new BandPassCoefficients(i,10);
float[] normalised=signalFilter.filtered(signal);
float loudest=0;
// only scan the first part, since it's all the same
for(int j=1; j<10000; ++j){
float s=Math.abs(normalised[j]);
if(s>loudest) loudest=s;
}
if(loudest>maxAmplitude){
maxAmplitude=loudest;
peak=i;
}
}
log("freq,"+freq+","+peak);
}
And, for completion, the code which steps through the audio range, testing each frequency.
for(workingFreq=100; workingFreq<20000; workingFreq+=100){
genTestSignal(workingFreq);
inputShorts=new short[inputSignal.length/2];
ByteBuffer.wrap(inputSignal).order(bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(inputShorts);
findOptimalFreq(normalised(inputShorts,RIGHT_CHANNEL),workingFreq);
}
The output is logged to System.out, and copied to a spreadsheet, since it's CSV format.
Here's some of it, the left is the target frequency, the right is the actual frequency which the peak is at:
6200,6436
6300,6436
6400,6436
6500,6932
6600,6932
6700,6932
6800,6932
6900,6932
7000,7510
7100,7510
7200,7510
7300,7510
7400,7510
7500,7510
7600,8192
7700,8192
7800,8192
7900,8192
8000,8192
8100,8192
8200,9012
8300,9012
Any thoughts?
I've gone through the filter code over and over, and I'm fairly sure it's right; but there's no mention anywhere I've seen of this kind of "feature", so I don't know what to do next.
Didn't solve the problem; but was able to replace it with a BiQuadratic filter from this site: BiQuadDesigner
There is a link to java source:
HTH anyone else struggling with this.
Dear more advanced programmers,
I have to programm a Pythagoras tree (see: https://en.wikipedia.org/wiki/Pythagoras_tree_(fractal) ) and I want to take a step forward, but I just can't.
I want to create the 3rd point of the triangle, but after 2 days of searching in books, internet, my head, etc., I just did not find a solution. Well, I have a solution, but it wont work for the recursive step and I don't know how to create the 3rd and 4th point of the following squares.
I want my programm to draw the step 1 of the tree.
Here's my code for the calculation so far:
public static void main(String[] args) {
double ax;
double ay;
double bx;
double by;
double cx;
double cy;
double dx;
double dy;
ax = 0.25;
ay = 0.75;
bx = 0.25;
by = 0.25;
cx = 0.75;
cy = 0.25;
dx = 0.75;
dy = 0.75;
StdDraw.line(ax,ay,bx,by); // ax etc. are doubles
StdDraw.line(bx,by,cx,cy);
StdDraw.line(cx,cy,dx,dy);
StdDraw.line(dx,dy,ax,ay);
double alpha;
double beta;
double random = 0.0;
while(random <= 0.3 || random >= 0.6){ //random angular between 30&60
random = Math.random();
}
random = random*100; //to make it an angular
alpha = random; //set alpha to this angular
beta = 90-alpha;
double sinusBeta= Math.toRadians(beta);
double sinusAlpha= Math.toRadians(alpha);
sinusBeta = Math.sin(sinusBeta);
sinusAlpha = Math.sin(sinusAlpha);
double side_b = 0.5*sinusBeta;
double side_a = 0.5*sinusAlpha;
double hypothenuse = Math.sqrt((side_b*side_b)+(side_a*side_a));
double p = (side_a*side_a)/hypothenuse; //to get h of the triangle
double q= (side_b*side_b)/hypothenuse;
double h = Math.sqrt(p*q);
double triangleTop_x = ax+q;
double triangleTop_y = ay+h;
StdDraw.line(ax, ay, triangleTop_x , triangleTop_y);
StdDraw.line(dx, dy, triangleTop_x , triangleTop_y);
}
I know that this is not the right way to get the last triangle point cause it has the condition that the hypothenuse is exactly in the direction of the x-axis. Which is not true for step two anymore, so a recursive method would not behave as it should. I wrote all the code by my own, I know it is not the best one, but it would be awesome to get an idea of how I can build the triangle and the following squares not direction-dependent.
Thank you so much in advance for any ideas that may help!