// 缩放bBar和 bbBar val bBar = summary.bBar / bStd val bbBar = summary.bbBar / (bStd * bStd)
val aStd = summary.aStd val aStdValues = aStd.values // 缩放aBar val aBar = { val _aBar = summary.aBar val _aBarValues = _aBar.values var i = 0 // scale aBar to standardized space in-place while (i < numFeatures) { if (aStdValues(i) == 0.0) { _aBarValues(i) = 0.0 } else { _aBarValues(i) /= aStdValues(i) } i += 1 } _aBar } val aBarValues = aBar.values // 缩放 abBar val abBar = { val _abBar = summary.abBar val _abBarValues = _abBar.values var i = 0 // scale abBar to standardized space in-place while (i < numFeatures) { if (aStdValues(i) == 0.0) { _abBarValues(i) = 0.0 } else { _abBarValues(i) /= (aStdValues(i) * bStd) } i += 1 } _abBar } val abBarValues = abBar.values // 缩放aaBar val aaBar = { val _aaBar = summary.aaBar val _aaBarValues = _aaBar.values var j = 0 var p = 0 // scale aaBar to standardized space in-place while (j < numFeatures) { val aStdJ = aStdValues(j) var i = 0 while (i <= j) { val aStdI = aStdValues(i) if (aStdJ == 0.0 || aStdI == 0.0) { _aaBarValues(p) = 0.0 } else { _aaBarValues(p) /= (aStdI * aStdJ) } p += 1 i += 1 } j += 1 } _aaBar } val aaBarValues = aaBar.values
val solution = solver match { case cholesky: CholeskySolver => try { cholesky.solve(bBar, bbBar, ab, aa, aBar) } catch { // if Auto solver is used and Cholesky fails due to singular AtA, then fall back to // Quasi-Newton solver. case _: SingularMatrixExceptionif solverType == WeightedLeastSquares.Auto => logWarning("Cholesky solver failed due to singular covariance matrix. " + "Retrying with Quasi-Newton solver.") // ab and aa were modified in place, so reconstruct them val _aa = getAtA(aaBarValues, aBarValues) val _ab = getAtB(abBarValues, bBar) val newSolver = newQuasiNewtonSolver(fitIntercept, maxIter, tol, None) newSolver.solve(bBar, bbBar, _ab, _aa, aBar) } case qn: QuasiNewtonSolver => qn.solve(bBar, bbBar, ab, aa, aBar) }
val (coefficientArray, intercept) = if (fitIntercept) { (solution.coefficients.slice(0, solution.coefficients.length - 1), solution.coefficients.last * bStd) } else { (solution.coefficients, 0.0) }
// convert the coefficients from the scaled space to the original space var q = 0 val len = coefficientArray.length while (q < len) { coefficientArray(q) *= { if (aStdValues(q) != 0.0) bStd / aStdValues(q) else0.0 } q += 1 }