@@ -50,70 +50,87 @@ namespace pov
50
50
* Local preprocessor defines
51
51
******************************************************************************/
52
52
53
- /* WARNING WARNING WARNING
54
-
55
- The following three constants have been defined so that quartic equations
56
- will properly render on fpu/compiler combinations that only have 64 bit
57
- IEEE precision. Do not arbitrarily change any of these values.
58
-
59
- If you have a machine with a proper fpu/compiler combo - like a Mac with
60
- a 68881, then use the native floating format (96 bits) and tune the
61
- values for a little less tolerance: something like: factor1 = 1.0e15,
62
- factor2 = -1.0e-7, factor3 = 1.0e-10.
63
-
64
- The meaning of the three constants are:
65
- factor1 - the magnitude of difference between coefficients in a
66
- quartic equation at which the Sturmian root solver will
67
- kick in. The Sturm solver is quite a bit slower than
68
- the algebraic solver, so the bigger this is, the faster
69
- the root solving will go. The algebraic solver is less
70
- accurate so the bigger this is, the more likely you will
71
- get bad roots.
72
-
73
- factor2 - Tolerance value that defines how close the quartic equation
74
- is to being a square of a quadratic. The closer this can
75
- get to zero before roots disappear, the less the chance
76
- you will get spurious roots.
77
-
78
- factor3 - Similar to factor2 at a later stage of the algebraic solver.
79
- */
80
-
81
- #ifndef FUDGE_FACTOR1
82
- #define FUDGE_FACTOR1 1.0e12
83
- #endif
84
- #ifndef FUDGE_FACTOR2
85
- #define FUDGE_FACTOR2 -1.0e-5
86
- #endif
87
- #ifndef FUDGE_FACTOR3
88
- #define FUDGE_FACTOR3 1.0e-7
89
- #endif
53
+ // / @def FUDGE_FACTOR2
54
+ // / Value defining how close the quartic equation is to being a square
55
+ // / of a quadratic.
56
+ // /
57
+ // / @note
58
+ // / The closer this can get to zero before roots disappear, the less the chance
59
+ // / you will get spurious roots.
60
+ // /
61
+ const DBL FUDGE_FACTOR2 = -1.0e-5 ;
62
+
63
+ // / @def FUDGE_FACTOR3
64
+ // / Similar to @ref FUDGE_FACTOR2 at a later stage of the algebraic solver.
65
+ // /
66
+ // / @note
67
+ // /
68
+ // / @ref FUDGE_FACTOR2 and @ref FUDGE_FACTOR3 have been defined so that quartic
69
+ // / equations will properly render on fpu/compiler combinations that only have
70
+ // / 64 bit IEEE precision. Do not arbitrarily change any of these values.
71
+ // /
72
+ // / If you have a machine with a proper fpu/compiler combo - like a Mac with a
73
+ // / 68881, then use the native floating format (96 bits) and tune the values for
74
+ // / a little less tolerance: something like: factor2 = -1.0e-7, factor3 =
75
+ // / 1.0e-10. Twenty five years later the reality is still double accuracy
76
+ // / due use of fastmath (not IEEE compliant) compiling, use of SSE Fused
77
+ // / Multiply Add instructions, etc.
78
+ // /
79
+ const DBL FUDGE_FACTOR3 = 1.0e-7 ;
90
80
91
- /* Constants. */
81
+ // / @def TWO_M_PI_3
82
+ // / Value used in solve_cubic() equal to 2.0 * pi / 3.0.
83
+ // /
92
84
const DBL TWO_M_PI_3 = 2.0943951023931954923084 ;
85
+
86
+ // / @def FOUR_M_PI_3
87
+ // / Value used in solve_cubic() equal to 4.0 * pi / 3.0.
88
+ // /
93
89
const DBL FOUR_M_PI_3 = 4.1887902047863909846168 ;
94
90
95
- /* Max number of iterations. */
91
+ // / @def MAX_ITERATIONS
92
+ // / Max number of polysolve sturm chain based bisections.
93
+ // /
94
+ // / @note
95
+ // / regula_falsa() uses twice this value internally as it can be
96
+ // / quite slow to converge in the worst case.
97
+ // /
96
98
const int MAX_ITERATIONS = 65 ;
97
99
98
- // NOTE: Value below which multiple roots ignored. Rays near tangent to surface
99
- // create extremely close roots and instability in sturm chain sign change
100
- // results from numchanges(). Also where the diagonal line of missed roots in
101
- // formed polynomials appears due root collapsing toward each other in
102
- // directions parallel to the ray.
100
+ // / @def SBISECT_MULT_ROOT_THRESHOLD
101
+ // / Value below which multiple roots ignored in sturm chained based bisection
102
+ // / and a sigle root at the middle of the current interval is returned.
103
+ // /
104
+ // / @note
105
+ // / Rays near tangent to surface create extremely close roots and instability
106
+ // / in sturm chain sign change results from numchanges(). Threshold often
107
+ // / tripped in sphere_sweep polynomials where the roots frequently collapse
108
+ // / inward due equation set up.
109
+ // /
103
110
const DBL SBISECT_MULT_ROOT_THRESHOLD = 1e-6 ;
104
111
105
- // NOTE: max_value - min_value threshold below which regula_falsa function is
106
- // tried when there is a single root. Single roots happen often. Rays continued
107
- // by transparency or internal reflection for example will have just one root.
108
- // Idea is to delay use of regula_falsa method until the ray domain is small.
112
+ // / @def REGULA_FALSA_THRESHOLD
113
+ // / Threshold below which regula_falsa function is tried when there is a single root.
114
+ // /
115
+ // / @note
116
+ // / Ray interval max_value - min_value threshold below which regula_falsa
117
+ // / function is tried when there is a single root. Single roots happen often.
118
+ // / Rays continued by transparency or internal reflection for example will have
119
+ // / just one root. Idea is to delay use of regula_falsa method until the ray
120
+ // / domain is small given regula-falsi method can converge very, very slowly
121
+ // / with common enough ray-surface equations.
122
+ // /
109
123
const DBL REGULA_FALSA_THRESHOLD = 1.0 ;
110
124
125
+ // / @def RELERROR
126
+ // / Smallest relative error along the ray when using the polysolve(), sturm
127
+ // / chain bisection / regula-falsi method.
128
+ // /
129
+ const DBL RELERROR = 1.0e-12 ;
130
+
111
131
/* A coefficient smaller than SMALL_ENOUGH is considered to be zero (0.0). */
112
132
const DBL SMALL_ENOUGH = 1.0e-10 ;
113
133
114
- /* Smallest relative error we want. */
115
- const DBL RELERROR = 1.0e-12 ;
116
-
117
134
118
135
/* ****************************************************************************
119
136
* Local typedefs
@@ -141,7 +158,6 @@ static int numchanges (int np, const polynomial *sseq, DBL a);
141
158
static DBL polyeval (DBL x, int n, const DBL *Coeffs);
142
159
static int buildsturm (int ord, polynomial *sseq);
143
160
static int visible_roots (int np, const polynomial *sseq);
144
- static int difficult_coeffs (int n, const DBL *x);
145
161
146
162
147
163
/* ****************************************************************************
@@ -728,7 +744,7 @@ static bool regula_falsa(const int order, const DBL *coef, DBL a, DBL b, DBL *va
728
744
729
745
break ;
730
746
}
731
- else if (fabs (fx) < (RELERROR/ 1000 ))
747
+ else if (fabs (fx) < (1 /std::numeric_limits<DBL>::digits10 ))
732
748
{
733
749
*val = x;
734
750
@@ -1006,138 +1022,6 @@ static int solve_cubic(const DBL *x, DBL *y)
1006
1022
}
1007
1023
}
1008
1024
1009
- #ifdef USE_NEW_DIFFICULT_COEFFS
1010
-
1011
- /* ****************************************************************************
1012
- *
1013
- * FUNCTION
1014
- *
1015
- * difficult_coeffs
1016
- *
1017
- * INPUT
1018
- *
1019
- * OUTPUT
1020
- *
1021
- * RETURNS
1022
- *
1023
- * AUTHOR
1024
- *
1025
- * Alexander Enzmann
1026
- *
1027
- * DESCRIPTION
1028
- *
1029
- * Test to see if any coeffs are more than 6 orders of magnitude
1030
- * larger than the smallest.
1031
- *
1032
- * CHANGES
1033
- *
1034
- * -
1035
- *
1036
- ******************************************************************************/
1037
-
1038
- static int difficult_coeffs (int n, DBL *x)
1039
- {
1040
- int i, flag = 0 ;
1041
- DBL t, biggest;
1042
-
1043
- biggest = fabs (x[0 ]);
1044
-
1045
- for (i = 1 ; i <= n; i++)
1046
- {
1047
- t = fabs (x[i]);
1048
-
1049
- if (t > biggest)
1050
- {
1051
- biggest = t;
1052
- }
1053
- }
1054
-
1055
- /* Everything is zero no sense in doing any more */
1056
-
1057
- if (biggest == 0.0 )
1058
- {
1059
- return (0 );
1060
- }
1061
-
1062
- for (i = 0 ; i <= n; i++)
1063
- {
1064
- if (x[i] != 0.0 )
1065
- {
1066
- if (fabs (biggest / x[i]) > FUDGE_FACTOR1)
1067
- {
1068
- x[i] = 0.0 ;
1069
- flag = 1 ;
1070
- }
1071
- }
1072
- }
1073
-
1074
- return (flag);
1075
- }
1076
- #else
1077
- /* ****************************************************************************
1078
- *
1079
- * FUNCTION
1080
- *
1081
- * difficult_coeffs
1082
- *
1083
- * INPUT
1084
- *
1085
- * OUTPUT
1086
- *
1087
- * RETURNS
1088
- *
1089
- * AUTHOR
1090
- *
1091
- * Alexander Enzmann
1092
- *
1093
- * DESCRIPTION
1094
- *
1095
- * Test to see if any coeffs are more than 6 orders of magnitude
1096
- * larger than the smallest (function from POV-Ray v1.0) [DB 8/94].
1097
- *
1098
- * CHANGES
1099
- *
1100
- * -
1101
- *
1102
- ******************************************************************************/
1103
-
1104
- static int difficult_coeffs (int n, const DBL *x)
1105
- {
1106
- int i;
1107
- DBL biggest;
1108
-
1109
- biggest = 0.0 ;
1110
-
1111
- for (i = 0 ; i <= n; i++)
1112
- {
1113
- if (fabs (x[i]) > biggest)
1114
- {
1115
- biggest = x[i];
1116
- }
1117
- }
1118
-
1119
- /* Everything is zero no sense in doing any more */
1120
-
1121
- if (biggest == 0.0 )
1122
- {
1123
- return (0 );
1124
- }
1125
-
1126
- for (i = 0 ; i <= n; i++)
1127
- {
1128
- if (x[i] != 0.0 )
1129
- {
1130
- if (fabs (biggest / x[i]) > FUDGE_FACTOR1)
1131
- {
1132
- return (1 );
1133
- }
1134
- }
1135
- }
1136
-
1137
- return (0 );
1138
- }
1139
-
1140
- #endif
1141
1025
1142
1026
#ifdef TEST_SOLVER
1143
1027
/* ****************************************************************************
@@ -1748,13 +1632,6 @@ int Solve_Polynomial(int n, const DBL *c0, DBL *r, int sturm, DBL epsilon, Rende
1748
1632
}
1749
1633
}
1750
1634
1751
- /* Test for difficult coeffs. */
1752
-
1753
- if ((!sturm) && (difficult_coeffs (4 , c)))
1754
- {
1755
- sturm = true ;
1756
- }
1757
-
1758
1635
/* Solve quartic polynomial. */
1759
1636
1760
1637
if (sturm)
0 commit comments