8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 01:23:03 +01:00

Fix #7064 - Linear regression functions aren't implemented correctly.

This commit is contained in:
Adriano dos Santos Fernandes 2021-12-10 17:29:02 -03:00
parent 53c85657a1
commit b1019c84c4

View File

@ -2028,12 +2028,15 @@ void RegrAggNode::aggPass(thread_db* /*tdbb*/, jrd_req* /*request*/, dsc* /*desc
dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
{ {
impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset); impure_value_ex* impure = request->getImpure<impure_value_ex>(impureOffset);
RegrImpure* impure2 = request->getImpure<RegrImpure>(impure2Offset);
dsc temp;
if (impure->vlux_count == 0) if (impure->vlux_count == 0)
return NULL; return NULL;
RegrImpure* impure2 = request->getImpure<RegrImpure>(impure2Offset);
dsc temp;
double doubleVal;
Decimal128 decimal128Val;
if (nodFlags & FLAG_DECFLOAT) if (nodFlags & FLAG_DECFLOAT)
{ {
DecimalStatus decSt = tdbb->getAttachment()->att_dec_status; DecimalStatus decSt = tdbb->getAttachment()->att_dec_status;
@ -2054,57 +2057,55 @@ dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
const Decimal128 sq = varPopX.sqrt(decSt).mul(decSt, varPopY.sqrt(decSt)); const Decimal128 sq = varPopX.sqrt(decSt).mul(decSt, varPopY.sqrt(decSt));
const Decimal128 corr = covarPop.div(safeDivide, sq); const Decimal128 corr = covarPop.div(safeDivide, sq);
Decimal128 d;
switch (type) switch (type)
{ {
case TYPE_REGR_AVGX: case TYPE_REGR_AVGX:
d = avgX; decimal128Val = avgX;
break; break;
case TYPE_REGR_AVGY: case TYPE_REGR_AVGY:
d = avgY; decimal128Val = avgY;
break; break;
case TYPE_REGR_INTERCEPT: case TYPE_REGR_INTERCEPT:
if (varPopX.compare(decSt, CDecimal128(0)) == 0) if (varPopX.compare(decSt, CDecimal128(0)) == 0)
return NULL; return NULL;
else else
d = avgY.sub(decSt, slope.mul(decSt, avgX)); decimal128Val = avgY.sub(decSt, slope.mul(decSt, avgX));
break; break;
case TYPE_REGR_R2: case TYPE_REGR_R2:
if (varPopX.compare(decSt, CDecimal128(0)) == 0) if (varPopX.compare(decSt, CDecimal128(0)) == 0)
return NULL; return NULL;
else if (varPopY.compare(decSt, CDecimal128(0)) == 0) else if (varPopY.compare(decSt, CDecimal128(0)) == 0)
d.set(1, decSt, 0); decimal128Val.set(1, decSt, 0);
else if (sq.compare(decSt, CDecimal128(0)) == 0) else if (sq.compare(decSt, CDecimal128(0)) == 0)
return NULL; return NULL;
else else
d = corr.mul(decSt, corr); decimal128Val = corr.mul(decSt, corr);
break; break;
case TYPE_REGR_SLOPE: case TYPE_REGR_SLOPE:
if (varPopX.compare(decSt, CDecimal128(0)) == 0) if (varPopX.compare(decSt, CDecimal128(0)) == 0)
return NULL; return NULL;
else else
d = slope; decimal128Val = slope;
break; break;
case TYPE_REGR_SXX: case TYPE_REGR_SXX:
d = sxx; decimal128Val = sxx;
break; break;
case TYPE_REGR_SXY: case TYPE_REGR_SXY:
d = sxy; decimal128Val = sxy;
break; break;
case TYPE_REGR_SYY: case TYPE_REGR_SYY:
d = syy; decimal128Val = syy;
break; break;
} }
temp.makeDecimal128(&d); temp.makeDecimal128(&decimal128Val);
} }
else else
{ {
@ -2117,57 +2118,55 @@ dsc* RegrAggNode::aggExecute(thread_db* tdbb, jrd_req* request) const
const double sq = sqrt(varPopX) * sqrt(varPopY); const double sq = sqrt(varPopX) * sqrt(varPopY);
const double corr = covarPop / sq; const double corr = covarPop / sq;
double d;
switch (type) switch (type)
{ {
case TYPE_REGR_AVGX: case TYPE_REGR_AVGX:
d = avgX; doubleVal = avgX;
break; break;
case TYPE_REGR_AVGY: case TYPE_REGR_AVGY:
d = avgY; doubleVal = avgY;
break; break;
case TYPE_REGR_INTERCEPT: case TYPE_REGR_INTERCEPT:
if (varPopX == 0.0) if (varPopX == 0.0)
return NULL; return NULL;
else else
d = avgY - slope * avgX; doubleVal = avgY - slope * avgX;
break; break;
case TYPE_REGR_R2: case TYPE_REGR_R2:
if (varPopX == 0.0) if (varPopX == 0.0)
return NULL; return NULL;
else if (varPopY == 0.0) else if (varPopY == 0.0)
d = 1.0; doubleVal = 1.0;
else if (sq == 0.0) else if (sq == 0.0)
return NULL; return NULL;
else else
d = corr * corr; doubleVal = corr * corr;
break; break;
case TYPE_REGR_SLOPE: case TYPE_REGR_SLOPE:
if (varPopX == 0.0) if (varPopX == 0.0)
return NULL; return NULL;
else else
d = covarPop / varPopX; doubleVal = covarPop / varPopX;
break; break;
case TYPE_REGR_SXX: case TYPE_REGR_SXX:
d = impure->vlux_count * varPopX; doubleVal = impure->vlux_count * varPopX;
break; break;
case TYPE_REGR_SXY: case TYPE_REGR_SXY:
d = impure->vlux_count * covarPop; doubleVal = impure->vlux_count * covarPop;
break; break;
case TYPE_REGR_SYY: case TYPE_REGR_SYY:
d = impure->vlux_count * varPopY; doubleVal = impure->vlux_count * varPopY;
break; break;
} }
temp.makeDouble(&d); temp.makeDouble(&doubleVal);
} }
EVL_make_value(tdbb, &temp, impure); EVL_make_value(tdbb, &temp, impure);