저는 물류 방정식을 사용하여 Feigenbaum의 상수를 계산하는 프로그램을 작성하고 있습니다.이 프로그램은 초 안정성 값을 찾은 다음이 초 안정성 값의 비율을 사용하여 상수를 계산합니다.프로그램은 이전 반복에서 작동 함에도 불구하고 멈춘 것처럼 보입니다
거의 모든 내 값에 대해 BigDecimal을 사용하므로 상수 계산 중 필요한 수준의 정밀도를 유지할 수 있습니다.
내가 페이지에 다음 파일의 30 ~ 35의 C++ 코드에서 내 코드에 적응하고는 : http://webcache.googleusercontent.com/search?q=cache:xabTioRiF0IJ:home.simula.no/~logg/pub/reports/chaos_hw1.ps.gz+&cd=21&hl=en&ct=clnk&gl=us
나는 프로그램이 내 질문에, 심지어 문제를 무엇을 의심한다. 나는 프로그램을 실행하고, 그것은 작동하는 것 같다. 출력은 처음 4 개의 슈퍼 스 테이블 값을 가져오고 첫 번째 2 개의 d는 예상되는 값이지만이 4 개의 행을 표시 한 후 프로그램이 멈춘 것처럼 보입니다. 예외는 없지만 30 분을 기다린 후에도 계산이 더 이상 출력되지 않습니다. 계산 시간이 각 행에 대해 거의 같아야하기 때문에 정확히 무엇이 원인인지 파악할 수 없지만 분명히 그렇지 않습니다. 여기
Feigenbaum constant calculation (using superstable points):
j a d
-----------------------------------------------------
1 2.0 N/A
2 3.23606797749979 N/A
4 3.4985616993277016 4.708943013540503
8 3.554640862768825 4.680770998010695
그리고 내 코드는 다음과 같습니다 : 여기 내 출력
import java.math.*;
// If there is a stable cycle, the iterates of 1/2 converge to the cycle.
// This was proved by Fatou and Julia.
// (What's special about x = 1/2 is that it is the critical point, the point at which the logistic map's derivative is 0.)
// Source: http://classes.yale.edu/fractals/chaos/Cycles/LogisticCycles/CycleGeneology.html
public class Feigenbaum4
{
public static BigDecimal r[] = new BigDecimal[19];
public static int iter = 0;
public static int iter1 = 20; // Iterations for tolerance level 1
public static int iter2 = 10; // Iterations for tolerance level 2
public static BigDecimal tol1 = new BigDecimal("2E-31"); // Tolerance for convergence level 1
public static BigDecimal tol2 = new BigDecimal("2E-27"); // Tolerance for convergence level 2
public static BigDecimal step = new BigDecimal("0.01"); // step when looking for second superstable a
public static BigDecimal x0 = new BigDecimal(".5");
public static BigDecimal aZero = new BigDecimal("2.0");
public static void main(String [] args)
{
System.out.println("Feigenbaum constant calculation (using superstable points):");
System.out.println("j\t\ta\t\t\td");
System.out.println("-----------------------------------------------------");
int n = 20;
if (FindFirstTwo())
{
FindRoots(n);
}
}
public static BigDecimal F(BigDecimal a, BigDecimal x)
{
BigDecimal temp = new BigDecimal("1");
temp = temp.subtract(x);
BigDecimal ans = (a.multiply(x.multiply(temp)));
return ans;
}
public static BigDecimal Dfdx(BigDecimal a, BigDecimal x)
{
BigDecimal ans = (a.subtract(x.multiply(a.multiply(new BigDecimal("2")))));
return ans;
}
public static BigDecimal Dfda(BigDecimal x)
{
BigDecimal temp = new BigDecimal("1");
temp = temp.subtract(x);
BigDecimal ans = (x.multiply(temp));
return ans;
}
public static BigDecimal NewtonStep(BigDecimal a, BigDecimal x, int n)
{
// This function returns the Newton step for finding the root, a,
// of fn(x,a) - x = 0 for a fixed x = X
BigDecimal fval = F(a, x);
BigDecimal dval = Dfda(x);
for (int i = 1; i < n; i++)
{
dval = Dfda(fval).add(Dfdx(a, fval).multiply(dval));
fval = F(a, fval);
}
BigDecimal ans = fval.subtract(x);
ans = ans.divide(dval, MathContext.DECIMAL64);
ans = ans.negate();
return ans;
}
public static BigDecimal Root(BigDecimal a0, int n)
{
// Find the root a of fn(x,a) - x = 0 for fixed x = X
// with Newton’s method. The initial guess is a0.
//
// On return iter is the number of iterations if
// the root was found. If not, iter is -1.
BigDecimal a = a0;
BigDecimal a_old = a0;
BigDecimal ans;
// First iter1 iterations with a stricter criterion,
// tol1 < tol2
for (iter = 0; iter < iter1; iter++)
{
a = a.add(NewtonStep(a, x0, n));
// check for convergence
BigDecimal temp = a.subtract(a_old);
temp = temp.divide(a_old, MathContext.DECIMAL64);
ans = temp.abs();
if (ans.compareTo(tol1) < 0)
{
return a;
}
a_old = a;
}
// If this doesn't work, do another iter2 iterations
// with the larger tolerance tol2
for (; iter < (iter1 + iter2); iter++)
{
a = a.add(NewtonStep(a, x0, n));
// check for convergence
BigDecimal temp = a.subtract(a_old);
temp = temp.divide(a_old, MathContext.DECIMAL64);
ans = temp.abs();
if (ans.compareTo(tol2) < 0)
{
return a;
}
a_old = a;
}
BigDecimal temp2 = a.subtract(a_old);
temp2 = temp2.divide(a_old, MathContext.DECIMAL64);
ans = temp2.abs();
// If not out at this point, iterations did not converge
System.out.println("Error: Iterations did not converge,");
System.out.println("residual = " + ans.toString());
iter = -1;
return a;
}
public static boolean FindFirstTwo()
{
BigDecimal guess = aZero;
BigDecimal r0;
BigDecimal r1;
while (true)
{
r0 = Root(guess, 1);
r1 = Root(guess, 2);
if (iter == -1)
{
System.out.println("Error: Unable to find first two superstable orbits");
return false;
}
BigDecimal temp = r0.add(tol1.multiply(new BigDecimal ("2")));
if (temp.compareTo(r1) < 0)
{
System.out.println("1\t\t" + r0.doubleValue() + "\t\t\tN/A");
System.out.println("2\t" + r1.doubleValue() + "\t\tN/A");
r[0] = r0;
r[1] = r1;
return true;
}
guess = guess.add(step);
}
}
public static void FindRoots(int n)
{
int n1 = 4;
BigDecimal delta = new BigDecimal(4.0);
BigDecimal guess;
for (int i = 2; i < n; i++)
{
// Computation
BigDecimal temp = (r[i-1].subtract(r[i-2])).divide(delta, MathContext.DECIMAL64);
guess = r[i-1].add(temp);
r[i] = Root(guess, n1);
BigDecimal temp2 = r[i-1].subtract(r[i-2]);
BigDecimal temp3 = r[i].subtract(r[i-1]);
delta = temp2.divide(temp3, MathContext.DECIMAL64);
// Output
System.out.println(n1 + "\t" + r[i].doubleValue() + "\t" + delta.doubleValue());
// Step to next superstable orbit
n1 = n1 * 2;
}
}
}
편집 : 필 Steitz의 대답은 본질적으로 내 문제를 해결했다. 좀 스레드 덤프에서보고, 그들을 시도하고 이해하는 약간의 연구를 수행하고, 정보를 디버깅 내 프로그램을 컴파일 한 후, 나는 메인 스레드가 줄에서 실속 된 것을 발견 할 수 있었다 :
dval = Dfda(fval).add(Dfdx(a, fval).multiply(dval));
필 Steit의뿐만 아니라이 줄
MathContext.DECIMAL128
을 사용하여 말했듯이 : 방법 F, Dfda 및 Dfdx 내 곱셈 연산에도
dval = Dfda(fval).add(Dfdx(a, fval).multiply(dval));
하지만를, 내가 얻을 수있었습니다 내 코드가 제대로 작동합니다.
DECIMAL128을 사용했습니다. 정밀도가 낮을수록 관성 검사를 위해 낮은 수와 비교하기 때문에 계산이 작동하지 않게 되었기 때문입니다.
몇 개의 스레드 덤프를 사용하여 프로세스가 멈춰있는 곳을 확인해 보셨습니까? – Leon
디버거를 사용하고 스레드 덤프로 블록 할 때 코드가 수행하는 작업을 확인하는 것이 좋습니다. 아무도이 코드를 모두 거쳐 버그를 찾고 있습니다. –
bmorris591, 어떤 디버거를 권하고 싶습니까? 나는 어떤 종류의 디버거와도 경험이 없다. – mps62