Compare commits

...

5 Commits

Author SHA1 Message Date
fc0393436f Document ShapeND.asArray() 2024-04-15 18:01:58 +03:00
9228e6019c Update Attributes version 2024-04-15 17:57:00 +03:00
edbf8c05be cleanup Minuit 2024-04-15 17:52:15 +03:00
SPC-code
f335d63659
Update docs/buffers.md
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-04-15 17:42:52 +03:00
SPC-code
c696a22f62
Update kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt
Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com>
2024-04-15 17:41:52 +03:00
13 changed files with 94 additions and 108 deletions

View File

@ -6,7 +6,7 @@ plugins {
id("org.jetbrains.kotlinx.kover") version "0.7.6" id("org.jetbrains.kotlinx.kover") version "0.7.6"
} }
val attributesVersion by extra("0.1.0") val attributesVersion by extra("0.2.0")
allprojects { allprojects {
repositories { repositories {

View File

@ -17,4 +17,4 @@ own `MemoryBuffer.create()` factory).
## Buffer performance ## Buffer performance
One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers
instead . instead.

View File

@ -68,6 +68,9 @@ public operator fun ShapeND.component3(): Int = get(2)
*/ */
public fun ShapeND.toArray(): IntArray = array.copyOf() public fun ShapeND.toArray(): IntArray = array.copyOf()
/**
* Provide internal content of [ShapeND]. Must not be modified.
*/
@UnsafeKMathAPI @UnsafeKMathAPI
public fun ShapeND.asArray(): IntArray = array public fun ShapeND.asArray(): IntArray = array

View File

@ -38,9 +38,9 @@ class MinuitParameter {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
constructor(num: Int, name: String, `val`: Double) { constructor(num: Int, name: String, value: Double) {
theNum = num theNum = num
theValue = `val` theValue = value
theConst = true theConst = true
theName = name theName = name
} }
@ -53,9 +53,9 @@ class MinuitParameter {
* @param val a double. * @param val a double.
* @param err a double. * @param err a double.
*/ */
constructor(num: Int, name: String, `val`: Double, err: Double) { constructor(num: Int, name: String, value: Double, err: Double) {
theNum = num theNum = num
theValue = `val` theValue = value
theError = err theError = err
theName = name theName = name
} }
@ -70,9 +70,9 @@ class MinuitParameter {
* @param min a double. * @param min a double.
* @param max a double. * @param max a double.
*/ */
constructor(num: Int, name: String, `val`: Double, err: Double, min: Double, max: Double) { constructor(num: Int, name: String, value: Double, err: Double, min: Double, max: Double) {
theNum = num theNum = num
theValue = `val` theValue = value
theError = err theError = err
theLoLimit = min theLoLimit = min
theUpLimit = max theUpLimit = max
@ -288,8 +288,8 @@ class MinuitParameter {
* *
* @param val a double. * @param val a double.
*/ */
fun setValue(`val`: Double) { fun setValue(value: Double) {
theValue = `val` theValue = value
} }
/** /**

View File

@ -77,8 +77,8 @@ abstract class MnApplication {
* @param val a double. * @param val a double.
* @param name a [String] object. * @param name a [String] object.
*/ */
fun add(name: String, `val`: Double, err: Double) { fun add(name: String, value: Double, err: Double) {
theState.add(name, `val`, err) theState.add(name, value, err)
} }
/** /**
@ -90,8 +90,8 @@ abstract class MnApplication {
* @param val a double. * @param val a double.
* @param err a double. * @param err a double.
*/ */
fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { fun add(name: String, value: Double, err: Double, low: Double, up: Double) {
theState.add(name, `val`, err, low, up) theState.add(name, value, err, low, up)
} }
/** /**
@ -100,8 +100,8 @@ abstract class MnApplication {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun add(name: String, `val`: Double) { fun add(name: String, value: Double) {
theState.add(name, `val`) theState.add(name, value)
} }
/** /**
@ -471,8 +471,8 @@ abstract class MnApplication {
* @param index a int. * @param index a int.
* @param val a double. * @param val a double.
*/ */
fun setValue(index: Int, `val`: Double) { fun setValue(index: Int, value: Double) {
theState.setValue(index, `val`) theState.setValue(index, value)
} }
/** /**
@ -482,8 +482,8 @@ abstract class MnApplication {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun setValue(name: String?, `val`: Double) { fun setValue(name: String?, value: Double) {
theState.setValue(name, `val`) theState.setValue(name, value)
} }
/** /**

View File

@ -106,8 +106,8 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) {
val para = intArrayOf(par) val para = intArrayOf(par)
val upar: MnUserParameterState = theMinimum!!.userState().copy() val upar: MnUserParameterState = theMinimum!!.userState().copy()
val err: Double = upar.error(par) val err: Double = upar.error(par)
val `val`: Double = upar.value(par) - err val value: Double = upar.value(par) - err
val xmid = doubleArrayOf(`val`) val xmid = doubleArrayOf(value)
val xdir = doubleArrayOf(-err) val xdir = doubleArrayOf(-err)
val ind: Int = upar.intOfExt(par) val ind: Int = upar.intOfExt(par)
val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix() val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix()
@ -121,7 +121,7 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) {
upar.setValue(ext, upar.value(ext) - xdev) upar.setValue(ext, upar.value(ext) - xdev)
} }
upar.fix(par) upar.fix(par)
upar.setValue(par, `val`) upar.setValue(par, value)
val toler = 0.1 val toler = 0.1
val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef) val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef)
val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls) val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls)
@ -330,8 +330,8 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) {
val para = intArrayOf(par) val para = intArrayOf(par)
val upar: MnUserParameterState = theMinimum!!.userState().copy() val upar: MnUserParameterState = theMinimum!!.userState().copy()
val err: Double = upar.error(par) val err: Double = upar.error(par)
val `val`: Double = upar.value(par) + err val value: Double = upar.value(par) + err
val xmid = doubleArrayOf(`val`) val xmid = doubleArrayOf(value)
val xdir = doubleArrayOf(err) val xdir = doubleArrayOf(err)
val ind: Int = upar.intOfExt(par) val ind: Int = upar.intOfExt(par)
val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix() val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix()
@ -345,7 +345,7 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) {
upar.setValue(ext, upar.value(ext) + xdev) upar.setValue(ext, upar.value(ext) + xdev)
} }
upar.fix(par) upar.fix(par)
upar.setValue(par, `val`) upar.setValue(par, value)
val toler = 0.1 val toler = 0.1
val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef) val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef)
val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls) val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls)

View File

@ -52,17 +52,9 @@ internal class MnSeedGenerator : MinimumSeedGenerator {
val delta: Double = hgrd.getSecond().getEntry(i) val delta: Double = hgrd.getSecond().getEntry(i)
if (abs(calculated - provided) > delta) { if (abs(calculated - provided) > delta) {
MINUITPlugin.logStatic( MINUITPlugin.logStatic(
"" """gradient discrepancy of external parameter "%d" (internal parameter "%d") too large. Expected: "%f", provided: "%f"""",
+ "gradient discrepancy of external parameter \"%d\" "
+ "(internal parameter \"%d\") too large. Expected: \"%f\", provided: \"%f\"",
st.getTransformation().extOfInt(i), i, provided, calculated st.getTransformation().extOfInt(i), i, provided, calculated
) )
//
// MINUITPlugin.logStatic("gradient discrepancy of external parameter "
// + st.getTransformation().extOfInt(i)
// + " (internal parameter " + i + ") too large.");
// good = false;
} }
} }
if (!good) { if (!good) {
@ -84,10 +76,7 @@ internal class MnSeedGenerator : MinimumSeedGenerator {
dcovar = 0.0 dcovar = 0.0
} else { } else {
for (i in 0 until n) { for (i in 0 until n) {
mat[i, i] = if (abs( mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2()
dgrad.getGradientDerivative()
.getEntry(i)
) > prec.eps2()
) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0
} }
} }

View File

@ -235,9 +235,9 @@ class MnUserParameterState {
* @param val a double. * @param val a double.
* @param name a [String] object. * @param name a [String] object.
*/ */
fun add(name: String, `val`: Double, err: Double) { fun add(name: String, value: Double, err: Double) {
theParameters.add(name, `val`, err) theParameters.add(name, value, err)
theIntParameters.add(`val`) theIntParameters.add(value)
theCovarianceValid = false theCovarianceValid = false
theGCCValid = false theGCCValid = false
theValid = true theValid = true
@ -252,10 +252,10 @@ class MnUserParameterState {
* @param err a double. * @param err a double.
* @param up a double. * @param up a double.
*/ */
fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { fun add(name: String, value: Double, err: Double, low: Double, up: Double) {
theParameters.add(name, `val`, err, low, up) theParameters.add(name, value, err, low, up)
theCovarianceValid = false theCovarianceValid = false
theIntParameters.add(ext2int(index(name), `val`)) theIntParameters.add(ext2int(index(name), value))
theGCCValid = false theGCCValid = false
theValid = true theValid = true
} }
@ -266,8 +266,8 @@ class MnUserParameterState {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun add(name: String, `val`: Double) { fun add(name: String, value: Double) {
theParameters.add(name, `val`) theParameters.add(name, value)
theValid = true theValid = true
} }
@ -331,8 +331,8 @@ class MnUserParameterState {
return theParameters.errors() return theParameters.errors()
} }
fun ext2int(i: Int, `val`: Double): Double { fun ext2int(i: Int, value: Double): Double {
return theParameters.trafo().ext2int(i, `val`) return theParameters.trafo().ext2int(i, value)
} }
/** /**
@ -426,8 +426,8 @@ class MnUserParameterState {
} }
// transformation internal <-> external // transformation internal <-> external
fun int2ext(i: Int, `val`: Double): Double { fun int2ext(i: Int, value: Double): Double {
return theParameters.trafo().int2ext(i, `val`) return theParameters.trafo().int2ext(i, value)
} }
fun intCovariance(): MnUserCovariance { fun intCovariance(): MnUserCovariance {
@ -700,14 +700,14 @@ class MnUserParameterState {
* @param e a int. * @param e a int.
* @param val a double. * @param val a double.
*/ */
fun setValue(e: Int, `val`: Double) { fun setValue(e: Int, value: Double) {
theParameters.setValue(e, `val`) theParameters.setValue(e, value)
if (!parameter(e).isFixed() && !parameter(e).isConst()) { if (!parameter(e).isFixed() && !parameter(e).isConst()) {
val i = intOfExt(e) val i = intOfExt(e)
if (parameter(e).hasLimits()) { if (parameter(e).hasLimits()) {
theIntParameters[i] = ext2int(e, `val`) theIntParameters[i] = ext2int(e, value)
} else { } else {
theIntParameters[i] = `val` theIntParameters[i] = value
} }
} }
} }
@ -719,8 +719,8 @@ class MnUserParameterState {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun setValue(name: String?, `val`: Double) { fun setValue(name: String?, value: Double) {
setValue(index(name), `val`) setValue(index(name), value)
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@ -65,8 +65,8 @@ class MnUserParameters {
* @param val a double. * @param val a double.
* @param name a [String] object. * @param name a [String] object.
*/ */
fun add(name: String, `val`: Double, err: Double) { fun add(name: String, value: Double, err: Double) {
theTransformation.add(name, `val`, err) theTransformation.add(name, value, err)
} }
/** /**
@ -78,8 +78,8 @@ class MnUserParameters {
* @param val a double. * @param val a double.
* @param err a double. * @param err a double.
*/ */
fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { fun add(name: String, value: Double, err: Double, low: Double, up: Double) {
theTransformation.add(name, `val`, err, low, up) theTransformation.add(name, value, err, low, up)
} }
/** /**
@ -88,8 +88,8 @@ class MnUserParameters {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun add(name: String, `val`: Double) { fun add(name: String, value: Double) {
theTransformation.add(name, `val`) theTransformation.add(name, value)
} }
/** /**
@ -344,8 +344,8 @@ class MnUserParameters {
* @param index a int. * @param index a int.
* @param val a double. * @param val a double.
*/ */
fun setValue(index: Int, `val`: Double) { fun setValue(index: Int, value: Double) {
theTransformation.setValue(index, `val`) theTransformation.setValue(index, value)
} }
/** /**
@ -355,8 +355,8 @@ class MnUserParameters {
* @param name a [String] object. * @param name a [String] object.
* @param val a double. * @param val a double.
*/ */
fun setValue(name: String?, `val`: Double) { fun setValue(name: String?, value: Double) {
theTransformation.setValue(name, `val`) theTransformation.setValue(name, value)
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@ -64,12 +64,12 @@ class MnUserTransformation {
* @param err * @param err
* @param val * @param val
*/ */
fun add(name: String, `val`: Double, err: Double) { fun add(name: String, value: Double, err: Double) {
require(!nameMap.containsKey(name)) { "duplicate name: $name" } require(!nameMap.containsKey(name)) { "duplicate name: $name" }
nameMap[name] = theParameters.size nameMap[name] = theParameters.size
theExtOfInt.add(theParameters.size) theExtOfInt.add(theParameters.size)
theCache.add(`val`) theCache.add(value)
theParameters.add(MinuitParameter(theParameters.size, name, `val`, err)) theParameters.add(MinuitParameter(theParameters.size, name, value, err))
} }
/** /**
@ -77,12 +77,12 @@ class MnUserTransformation {
* @param up * @param up
* @param low * @param low
*/ */
fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { fun add(name: String, value: Double, err: Double, low: Double, up: Double) {
require(!nameMap.containsKey(name)) { "duplicate name: $name" } require(!nameMap.containsKey(name)) { "duplicate name: $name" }
nameMap[name] = theParameters.size nameMap[name] = theParameters.size
theExtOfInt.add(theParameters.size) theExtOfInt.add(theParameters.size)
theCache.add(`val`) theCache.add(value)
theParameters.add(MinuitParameter(theParameters.size, name, `val`, err, low, up)) theParameters.add(MinuitParameter(theParameters.size, name, value, err, low, up))
} }
/** /**
@ -90,11 +90,11 @@ class MnUserTransformation {
* @param name * @param name
* @param val * @param val
*/ */
fun add(name: String, `val`: Double) { fun add(name: String, value: Double) {
require(!nameMap.containsKey(name)) { "duplicate name: $name" } require(!nameMap.containsKey(name)) { "duplicate name: $name" }
nameMap[name] = theParameters.size nameMap[name] = theParameters.size
theCache.add(`val`) theCache.add(value)
theParameters.add(MinuitParameter(theParameters.size, name, `val`)) theParameters.add(MinuitParameter(theParameters.size, name, value))
} }
/** /**
@ -107,20 +107,20 @@ class MnUserTransformation {
return MnUserTransformation(this) return MnUserTransformation(this)
} }
fun dInt2Ext(i: Int, `val`: Double): Double { fun dInt2Ext(i: Int, value: Double): Double {
var dd = 1.0 var dd = 1.0
val parm: MinuitParameter = theParameters[theExtOfInt[i]] val parm: MinuitParameter = theParameters[theExtOfInt[i]]
if (parm.hasLimits()) { if (parm.hasLimits()) {
dd = if (parm.hasUpperLimit() && parm.hasLowerLimit()) { dd = if (parm.hasUpperLimit() && parm.hasLowerLimit()) {
theDoubleLimTrafo.dInt2Ext( theDoubleLimTrafo.dInt2Ext(
`val`, value,
parm.upperLimit(), parm.upperLimit(),
parm.lowerLimit() parm.lowerLimit()
) )
} else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) {
theUpperLimTrafo.dInt2Ext(`val`, parm.upperLimit()) theUpperLimTrafo.dInt2Ext(value, parm.upperLimit())
} else { } else {
theLowerLimTrafo.dInt2Ext(`val`, parm.lowerLimit()) theLowerLimTrafo.dInt2Ext(value, parm.lowerLimit())
} }
} }
return dd return dd
@ -143,30 +143,30 @@ class MnUserTransformation {
return result return result
} }
fun ext2int(i: Int, `val`: Double): Double { fun ext2int(i: Int, value: Double): Double {
val parm: MinuitParameter = theParameters[i] val parm: MinuitParameter = theParameters[i]
return if (parm.hasLimits()) { return if (parm.hasLimits()) {
if (parm.hasUpperLimit() && parm.hasLowerLimit()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) {
theDoubleLimTrafo.ext2int( theDoubleLimTrafo.ext2int(
`val`, value,
parm.upperLimit(), parm.upperLimit(),
parm.lowerLimit(), parm.lowerLimit(),
precision() precision()
) )
} else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) {
theUpperLimTrafo.ext2int( theUpperLimTrafo.ext2int(
`val`, value,
parm.upperLimit(), parm.upperLimit(),
precision() precision()
) )
} else { } else {
theLowerLimTrafo.ext2int( theLowerLimTrafo.ext2int(
`val`, value,
parm.lowerLimit(), parm.lowerLimit(),
precision() precision()
) )
} }
} else `val` } else value
} }
fun extOfInt(internal: Int): Int { fun extOfInt(internal: Int): Int {
@ -200,21 +200,21 @@ class MnUserTransformation {
return nameMap[name]!! return nameMap[name]!!
} }
fun int2ext(i: Int, `val`: Double): Double { fun int2ext(i: Int, value: Double): Double {
val parm: MinuitParameter = theParameters[theExtOfInt[i]] val parm: MinuitParameter = theParameters[theExtOfInt[i]]
return if (parm.hasLimits()) { return if (parm.hasLimits()) {
if (parm.hasUpperLimit() && parm.hasLowerLimit()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) {
theDoubleLimTrafo.int2ext( theDoubleLimTrafo.int2ext(
`val`, value,
parm.upperLimit(), parm.upperLimit(),
parm.lowerLimit() parm.lowerLimit()
) )
} else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) {
theUpperLimTrafo.int2ext(`val`, parm.upperLimit()) theUpperLimTrafo.int2ext(value, parm.upperLimit())
} else { } else {
theLowerLimTrafo.int2ext(`val`, parm.lowerLimit()) theLowerLimTrafo.int2ext(value, parm.lowerLimit())
} }
} else `val` } else value
} }
fun int2extCovariance(vec: RealVector, cov: MnAlgebraicSymMatrix): MnUserCovariance { fun int2extCovariance(vec: RealVector, cov: MnAlgebraicSymMatrix): MnUserCovariance {
@ -235,13 +235,13 @@ class MnUserTransformation {
return result return result
} }
fun int2extError(i: Int, `val`: Double, err: Double): Double { fun int2extError(i: Int, value: Double, err: Double): Double {
var dx = err var dx = err
val parm: MinuitParameter = theParameters[theExtOfInt[i]] val parm: MinuitParameter = theParameters[theExtOfInt[i]]
if (parm.hasLimits()) { if (parm.hasLimits()) {
val ui = int2ext(i, `val`) val ui = int2ext(i, value)
var du1 = int2ext(i, `val` + dx) - ui var du1 = int2ext(i, value + dx) - ui
val du2 = int2ext(i, `val` - dx) - ui val du2 = int2ext(i, value - dx) - ui
if (parm.hasUpperLimit() && parm.hasLowerLimit()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) {
if (dx > 1.0) { if (dx > 1.0) {
du1 = parm.upperLimit() - parm.lowerLimit() du1 = parm.upperLimit() - parm.lowerLimit()
@ -354,13 +354,13 @@ class MnUserTransformation {
setUpperLimit(index(name), up) setUpperLimit(index(name), up)
} }
fun setValue(index: Int, `val`: Double) { fun setValue(index: Int, value: Double) {
theParameters[index].setValue(`val`) theParameters[index].setValue(value)
theCache[index] = `val` theCache[index] = value
} }
fun setValue(name: String?, `val`: Double) { fun setValue(name: String?, value: Double) {
setValue(index(name), `val`) setValue(index(name), value)
} }
fun transform(pstates: RealVector): ArrayRealVector { fun transform(pstates: RealVector): ArrayRealVector {

View File

@ -71,10 +71,7 @@ internal object NegativeG2LineSearch {
} while (iter++ < 2 * n && iterate) } while (iter++ < 2 * n && iterate)
val mat = MnAlgebraicSymMatrix(n) val mat = MnAlgebraicSymMatrix(n)
for (i in 0 until n) { for (i in 0 until n) {
mat[i, i] = if (abs( mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2()
dgrad.getGradientDerivative()
.getEntry(i)
) > prec.eps2()
) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0
} }
val err = MinimumError(mat, 1.0) val err = MinimumError(mat, 1.0)

View File

@ -41,10 +41,7 @@ internal class SimplexSeedGenerator : MinimumSeedGenerator {
val mat = MnAlgebraicSymMatrix(n) val mat = MnAlgebraicSymMatrix(n)
val dcovar = 1.0 val dcovar = 1.0
for (i in 0 until n) { for (i in 0 until n) {
mat[i, i] = if (abs( mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2()
dgrad.getGradientDerivative()
.getEntry(i)
) > prec.eps2()
) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0
} }
val err = MinimumError(mat, dcovar) val err = MinimumError(mat, dcovar)