using System;
namespace Legalsoft.Truffer
{
///
/// general linear fit using SVD
///
public class Fitsvd
{
private int ndat { get; set; }
private int ma { get; set; }
private double tol { get; set; }
private double[] x { get; set; }
private double[] y { get; set; }
private double[] sig { get; set; }
private double[] a;
private double[,] covar { get; set; }
private double chisq { get; set; }
private double[,] xmd { get; set; }
public UniVarRealMultiValueFun funcs;
public RealMultiValueFun funcsmd;
public Fitsvd(double[] xx, double[] yy, double[] ssig, UniVarRealMultiValueFun funks, double TOL = 1.0e-12)
{
this.ndat = yy.Length;
this.x = xx;
this.xmd = null;
this.y = yy;
this.sig = ssig;
this.funcs = funks;
this.tol = TOL;
}
public void fit()
{
if (x != null)
{
ma = funcs.funk(x[0]).Length;
}
else
{
ma = funcsmd.funk(row(xmd, 0)).Length;
}
//a.resize(ma);
a = new double[ma];
//covar.resize(ma, ma);
covar = new double[ma, ma];
double[,] aa = new double[ndat, ma];
double[] b = new double[ndat];
double[] afunc = new double[ma];
for (int i = 0; i < ndat; i++)
{
if (x != null)
{
afunc = funcs.funk(x[i]);
}
else
{
afunc = funcsmd.funk(row(xmd, i));
}
double tmp = 1.0 / sig[i];
for (int j = 0; j < ma; j++)
{
aa[i, j] = afunc[j] * tmp;
}
b[i] = y[i] * tmp;
}
SVD svd = new SVD(aa);
double thresh = (tol > 0.0 ? tol * svd.w[0] : -1.0);
svd.solve(b, a, thresh);
chisq = 0.0;
for (int i = 0; i < ndat; i++)
{
double sum = 0.0;
for (int j = 0; j < ma; j++)
{
sum += aa[i, j] * a[j];
}
chisq += Globals.SQR(sum - b[i]);
}
for (int i = 0; i < ma; i++)
{
for (int j = 0; j < i + 1; j++)
{
double sum = 0.0;
for (int k = 0; k < ma; k++)
{
if (svd.w[k] > svd.tsh)
{
sum += svd.v[i, k] * svd.v[j, k] / Globals.SQR(svd.w[k]);
}
}
covar[j, i] = covar[i, j] = sum;
}
}
}
public double[] row(double[,] a, int i)
{
int n = a.GetLength(1);
double[] ans = new double[n];
for (int j = 0; j < n; j++)
{
ans[j] = a[i, j];
}
return ans;
}
}
}
using System;
namespace Legalsoft.Truffer
{
///
/// general linear fit using SVD
///
public class Fitsvd
{
private int ndat { get; set; }
private int ma { get; set; }
private double tol { get; set; }
private double[] x { get; set; }
private double[] y { get; set; }
private double[] sig { get; set; }
private double[] a;
private double[,] covar { get; set; }
private double chisq { get; set; }
private double[,] xmd { get; set; }
public UniVarRealMultiValueFun funcs;
public RealMultiValueFun funcsmd;
public Fitsvd(double[] xx, double[] yy, double[] ssig, UniVarRealMultiValueFun funks, double TOL = 1.0e-12)
{
this.ndat = yy.Length;
this.x = xx;
this.xmd = null;
this.y = yy;
this.sig = ssig;
this.funcs = funks;
this.tol = TOL;
}
public void fit()
{
if (x != null)
{
ma = funcs.funk(x[0]).Length;
}
else
{
ma = funcsmd.funk(row(xmd, 0)).Length;
}
//a.resize(ma);
a = new double[ma];
//covar.resize(ma, ma);
covar = new double[ma, ma];
double[,] aa = new double[ndat, ma];
double[] b = new double[ndat];
double[] afunc = new double[ma];
for (int i = 0; i < ndat; i++)
{
if (x != null)
{
afunc = funcs.funk(x[i]);
}
else
{
afunc = funcsmd.funk(row(xmd, i));
}
double tmp = 1.0 / sig[i];
for (int j = 0; j < ma; j++)
{
aa[i, j] = afunc[j] * tmp;
}
b[i] = y[i] * tmp;
}
SVD svd = new SVD(aa);
double thresh = (tol > 0.0 ? tol * svd.w[0] : -1.0);
svd.solve(b, a, thresh);
chisq = 0.0;
for (int i = 0; i < ndat; i++)
{
double sum = 0.0;
for (int j = 0; j < ma; j++)
{
sum += aa[i, j] * a[j];
}
chisq += Globals.SQR(sum - b[i]);
}
for (int i = 0; i < ma; i++)
{
for (int j = 0; j < i + 1; j++)
{
double sum = 0.0;
for (int k = 0; k < ma; k++)
{
if (svd.w[k] > svd.tsh)
{
sum += svd.v[i, k] * svd.v[j, k] / Globals.SQR(svd.w[k]);
}
}
covar[j, i] = covar[i, j] = sum;
}
}
}
public double[] row(double[,] a, int i)
{
int n = a.GetLength(1);
double[] ans = new double[n];
for (int j = 0; j < n; j++)
{
ans[j] = a[i, j];
}
return ans;
}
}
}