27 if (symbolName ==
'x') {
30 if (da != 0 || db != 0) {
39 Expression * e = Expression::shallowReduce(context, angleUnit);
43 #if MATRIX_EXACT_REDUCING 52 Complex<T> * Integral::templatedApproximate(Context & context, AngleUnit angleUnit)
const {
53 VariableContext<T> xContext = VariableContext<T>(
'x', &context);
55 T a = aInput->type() ==
Type::Complex ?
static_cast<Complex<T> *
>(aInput)->toScalar() :
NAN;
58 T b = bInput->type() ==
Type::Complex ?
static_cast<Complex<T> *
>(bInput)->toScalar() :
NAN;
63 #ifdef LAGRANGE_METHOD 64 T result = lagrangeGaussQuadrature<T>(a, b, xContext, angleUnit);
66 T result = adaptiveQuadrature<T>(a, b, 0.1, k_maxNumberOfIterations, xContext, angleUnit);
71 ExpressionLayout * Integral::privateCreateLayout(
PrintFloat::Mode floatDisplayMode, ComplexFormat complexFormat)
const {
74 ExpressionLayout * childrenLayouts[2];
76 childrenLayouts[1] =
new StringLayout(
"dx", 2);
81 T Integral::functionValueAtAbscissa(
T x, VariableContext<T> xContext, AngleUnit angleUnit)
const {
84 xContext.setExpressionForSymbolName(&e, &xSymbol, xContext);
86 T result = f->type() ==
Type::Complex ?
static_cast<Complex<T> *
>(f)->toScalar() :
NAN;
91 #ifdef LAGRANGE_METHOD 94 T Integral::lagrangeGaussQuadrature(
T a,
T b, VariableContext<T> xContext, AngleUnit angleUnit)
const {
98 const static T x[10]={0.0765265211334973337546404, 0.2277858511416450780804962, 0.3737060887154195606725482, 0.5108670019508270980043641,
99 0.6360536807265150254528367, 0.7463319064601507926143051, 0.8391169718222188233945291, 0.9122344282513259058677524,
100 0.9639719272779137912676661, 0.9931285991850949247861224};
101 const static T w[10]={0.1527533871307258506980843, 0.1491729864726037467878287, 0.1420961093183820513292983, 0.1316886384491766268984945, 0.1181945319615184173123774,
102 0.1019301198172404350367501, 0.0832767415767047487247581, 0.0626720483341090635695065, 0.0406014298003869413310400, 0.0176140071391521183118620};
106 for (
int j = 0; j < 10; j++) {
108 result += w[j]*(functionValueAtAbscissa(xm+dx, xContext, angleUnit) + functionValueAtAbscissa(xm-dx, xContext, angleUnit));
117 Integral::DetailedResult<T> Integral::kronrodGaussQuadrature(
T a,
T b, VariableContext<T> xContext, AngleUnit angleUnit)
const {
122 const static T wg[5]= {0.066671344308688137593568809893332, 0.149451349150580593145776339657697,
123 0.219086362515982043995534934228163, 0.269266719309996355091226921569469, 0.295524224714752870173892994651338};
124 const static T xgk[11]= {0.995657163025808080735527280689003, 0.973906528517171720077964012084452,
125 0.930157491355708226001207180059508, 0.865063366688984510732096688423493, 0.780817726586416897063717578345042,
126 0.679409568299024406234327365114874, 0.562757134668604683339000099272694, 0.433395394129247190799265943165784,
127 0.294392862701460198131126603103866, 0.148874338981631210884826001129720, 0.000000000000000000000000000000000};
128 const static T wgk[11]= {0.011694638867371874278064396062192, 0.032558162307964727478818972459390,
129 0.054755896574351996031381300244580, 0.075039674810919952767043140916190, 0.093125454583697605535065465083366,
130 0.109387158802297641899210590325805, 0.123491976262065851077958109831074, 0.134709217311473325928054001771707,
131 0.142775938577060080797094273138717, 0.147739104901338491374841515972068, 0.149445554002916905664936468389821};
140 T fc = functionValueAtAbscissa(centr, xContext, angleUnit);
143 for (
int j = 0; j < 5; j++) {
145 T absc = hlgth*xgk[jtw];
146 T fval1 = functionValueAtAbscissa(centr-absc, xContext, angleUnit);
147 T fval2 = functionValueAtAbscissa(centr+absc, xContext, angleUnit);
150 T fsum = fval1+fval2;
152 resk += wgk[jtw]*fsum;
155 for (
int j = 0; j < 5; j++) {
157 T absc = hlgth*xgk[jtwm1];
158 T fval1 = functionValueAtAbscissa(centr-absc, xContext, angleUnit);
159 T fval2 = functionValueAtAbscissa(centr+absc, xContext, angleUnit);
162 T fsum = fval1+fval2;
163 resk += wgk[jtwm1]*fsum;
168 for (
int j = 0; j < 10; j++) {
171 T integral = resk*hlgth;
172 resabs = resabs*dhlgth;
173 resasc = resasc*dhlgth;
175 if (resasc != 0 && abserr != 0) {
176 abserr = 1 >
std::pow((
T)(200*abserr/resasc), (
T)1.5)? resasc*
std::pow((
T)(200*abserr/resasc), (
T)1.5) : resasc;
178 if (resabs > max/(50.0*
epsilon)) {
181 DetailedResult<T> result;
182 result.integral = integral;
183 result.absoluteError = abserr;
188 T Integral::adaptiveQuadrature(
T a,
T b,
T eps,
int numberOfIterations, VariableContext<T> xContext, AngleUnit angleUnit)
const {
192 DetailedResult<T> quadKG = kronrodGaussQuadrature(a, b, xContext, angleUnit);
193 T result = quadKG.integral;
194 if (quadKG.absoluteError <= eps) {
196 }
else if (--numberOfIterations > 0) {
198 return adaptiveQuadrature<T>(a, m, eps/2, numberOfIterations, xContext, angleUnit) + adaptiveQuadrature<T>(m, b, eps/2, numberOfIterations, xContext, angleUnit);
static bool shouldStopProcessing()
int polynomialDegree(char symbolName) const override
Expression * replaceWith(Expression *newOperand, bool deleteAfterReplace=true)
Expression * approximate(Context &context, AngleUnit angleUnit=AngleUnit::Default) const
Type type() const override
const Expression * m_operands[T]
ExpressionLayout * createLayout(PrintFloat::Mode floatDisplayMode=PrintFloat::Mode::Default, ComplexFormat complexFormat=ComplexFormat::Default) const
static Complex< T > Float(T x)
Expression * clone() const override
const Expression * operand(int i) const
virtual int polynomialDegree(char symbolName) const