using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Runtime.Serialization;
using CategoryTheory;
using DiagramUI;
using DiagramUI.Interfaces;
using RealMatrixProcessor;
using BaseTypes;
using DataPerformer;
using DataPerformer.Interfaces;
namespace Regression
{
/// <summary>
/// General linear method with iterator
/// </summary>
[Serializable()]
public class IteratorGLM : CategoryObject, ISerializable, IDataConsumer,
IIteratorConsumer, IPostSetArrow
{
#region Fields
protected List<string> sAliases = new List<string>();
protected List<string> sLeft = new List<string>();
protected List<string> sRight = new List<string>();
protected List<List<string>> sR = new List<List<string>>();
protected double[] dx;
protected double[,] d;
protected List<IIterator> iterators = new List<IIterator>();
protected IAlias[] aliases;
protected string[] keys;
protected IMeasure[] left;
protected IMeasure[] right;
protected double[,] ht;
protected double[,] a;
protected int[] indxa;
protected double[] z;
protected double[,] mr;
protected double[,] mr1;
protected IMeasure[,] r;
protected double[] y;
protected double[] y1;
protected double[] yr;
protected double[,] htr;
protected double[,] ad;
protected double[] correct;
protected List<IIterator> ownIterators = new List<IIterator>();
static private readonly ConstMeasure zero = new ConstMeasure(0);
static private readonly ConstMeasure unity = new ConstMeasure(1);
protected object obj;
protected IDataConsumer consumer;
List<IMeasurements> measurements = new List<IMeasurements>();
#endregion
#region Constuctors
public IteratorGLM()
{
consumer = this;
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
protected IteratorGLM(SerializationInfo info, StreamingContext context)
: this()
{
sAliases = info.GetValue("Aliases", typeof(List<string>)) as List<string>;
sLeft = info.GetValue("Left", typeof(List<string>)) as List<string>;
sRight = info.GetValue("Right", typeof(List<string>)) as List<string>;
sR = info.GetValue("R", typeof(List<List<string>>)) as List<List<string>>;
dx = info.GetValue("Dx", typeof(double[])) as double[];
d = info.GetValue("D", typeof(double[,])) as double[,];
}
#endregion
#region ISerializable Members
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Aliases", sAliases, typeof(List<string>));
info.AddValue("Left", sLeft, typeof(List<string>));
info.AddValue("Right", sRight, typeof(List<string>));
info.AddValue("R", sR, typeof(List<List<string>>));
info.AddValue("Dx", dx, typeof(double[]));
info.AddValue("D", d, typeof(double[,]));
}
#endregion
#region IPostSetArrow Members
void IPostSetArrow.PostSetArrow()
{
createArrays();
setZeros();
prepare();
}
#endregion
#region IDataConsumer Members
void IDataConsumer.Add(IMeasurements mea)
{
measurements.Add(mea);
}
void IDataConsumer.Remove(IMeasurements mea)
{
measurements.Remove(mea);
}
void IDataConsumer.UpdateChildrenData()
{
foreach (IMeasurements m in measurements)
{
m.UpdateMeasurements();
}
}
int IDataConsumer.Count
{
get { return measurements.Count; }
}
IMeasurements IDataConsumer.this[int n]
{
get { return measurements[n]; }
}
void IDataConsumer.Reset()
{
StaticDataPerformer.Reset(this);
}
#endregion
#region IIteratorConsumer Members
void IIteratorConsumer.Add(IIterator iterator)
{
ownIterators.Add(iterator);
}
void IIteratorConsumer.Remove(IIterator iterator)
{
ownIterators.Remove(iterator);
}
#endregion
#region Specific Members
public void Set(List<string> aliases, List<string> left,
List<string> right, List<List<string>> r,
double[] dx, double[,] d)
{
this.sAliases = aliases;
this.sLeft = left;
this.sRight = right;
this.sR = r;
this.dx = dx;
this.d = d;
createArrays();
setZeros();
prepare();
}
public int DataCount
{
get
{
return sLeft.Count;
}
}
public int AliasesCount
{
get
{
return sAliases.Count;
}
}
public List<string> AllAliases
{
get
{
List<string> l = new List<string>();
StaticDataPerformer.GetAliases(this, l, null);
return l;
}
}
public string GetAliasName(int i)
{
return sAliases[i];
}
public string GetLeftName(int i)
{
return sLeft[i];
}
public string GetRightName(int i)
{
return sRight[i];
}
public List<string> AllMeasurements
{
get
{
IDataConsumer c = this;
List<string> list = new List<string>();
for (int i = 0; i < c.Count; i++)
{
IMeasurements m = c[i];
IAssociatedObject ao = m as IAssociatedObject;
string on = PureDesktop.GetRelativeName(this, ao) + ".";
for (int j = 0; j < m.Count; j++)
{
string s = on + m[j].Name;
list.Add(s);
}
}
return list;
}
}
public double[,] CorrectionMatrix
{
get
{
return d;
}
set
{
if (value == null)
{
throw new Exception();
}
int n = sAliases.Count;
if (value.GetLength(0) != n | value.GetLength(1) != n)
{
throw new Exception();
}
d = value;
}
}
public static void GetIterators(IDataConsumer consumer, List<IIterator> iterators)
{
getIterators(consumer, iterators);
}
public double Iterate()
{
double sigma = 0;
List<IIterator> iterators;
if (ownIterators.Count != 0)
{
iterators = ownIterators;
}
else
{
iterators = this.iterators;
}
if (iterators.Count == 0)
{
return 1;
}
foreach (IIterator it in iterators)
{
it.Reset();
}
for (int i = 0; i < a.GetLength(0); i++)
{
for (int j = 0; j < a.GetLength(1); j++)
{
a[i, j] = d[i, j];
}
}
for (int i = 0; i < z.Length; i++)
{
z[i] = 0;
}
while (true)
{
consumer.Reset();
try
{
consumer.UpdateChildrenData();
}
catch (Exception)
{
goto cycle;
}
for (int i = 0; i < y.Length; i++)
{
object o = left[i].Parameter();
if (o == null)
{
goto cycle;
}
y[i] = (double)o;
o = right[i].Parameter();
if (o == null | o is DBNull)
{
goto cycle;
}
double res = (double)o - y[i];
yr[i] = res;
sigma += res * res;
}
for (int i = 0; i < aliases.Length; i++)
{
IAlias a = aliases[i];
string key = keys[i];
double delta = dx[i];
setDelta(a, key, delta);
consumer.Reset();
consumer.UpdateChildrenData();
for (int j = 0; j < y.Length; j++)
{
object obj = left[j].Parameter();
if (obj == null)
{
setDelta(a, key, -delta);
goto cycle;
}
ht[i, j] = ((double)obj - y[j]) / delta;
}
setDelta(a, key, -delta);
}
for (int i = 0; i < y.Length; i++)
{
for (int j = 0; j <= i; j++)
{
mr[i, j] = (double)r[i, j].Parameter();
mr[j, i] = mr[i, j];
}
}
RealMatrix.Invert(mr, mr1);
RealMatrix.Multiply(ht, mr1, htr);
for (int i = 0; i < a.GetLength(0); i++)
{
for (int k = 0; k < htr.GetLength(1); k++)
{
z[i] += htr[i, k] * yr[k];
for (int j = 0; j < a.GetLength(1); j++)
{
a[i, j] += htr[i, k] * ht[j, k];
}
}
}
cycle:
foreach (IIterator it in iterators)
{
if (!it.Next())
{
goto m;
}
}
}
m:
RealMatrix.Solve(a, z, indxa);
for (int i = 0; i < z.Length; i++)
{
setDelta(aliases[i], keys[i], z[i]);
}
return sigma;
}
public double Iterate(int n)
{
Dictionary<double, double[]> d = new Dictionary<double, double[]>();
double[] res = null;
double a = 0;
for (int i = 0; i < n; i++)
{
Iterate();
res = new double[z.Length];
for (int j = 0; j < res.Length; j++)
{
res[j] = getValue(aliases[j], keys[j]);
}
d[CalculatedSigma] = res;
}
List<double> l = new List<double>(d.Keys);
l.Sort();
a = l[0];
res = d[a];
for (int i = 0; i < res.Length; i++)
{
setValue(aliases[i], keys[i], res[i]);
}
double ss = CalculatedSigma;
return a;
}
public static void Test(IDesktop desktop, int n)
{
IList<ICategoryObject> objs = desktop.CategoryObjects;
IList<IteratorGLM> l = new List<IteratorGLM>();
foreach (object o in objs)
{
if (o.GetType().FullName.Equals("DataPerformer.IteratorGLM"))
{
IteratorGLM it = o as IteratorGLM;
l.Add(it);
}
}
foreach (IteratorGLM it in l)
{
for (int i = 0; i < n; i++)
{
it.Iterate();
}
}
l = null;
GC.Collect();
}
public double CalculatedSigma
{
get
{
double sigma = 0;
List<IIterator> iterators;
if (ownIterators.Count != 0)
{
iterators = ownIterators;
}
else
{
iterators = this.iterators;
}
if (iterators.Count == 0)
{
return 1;
}
foreach (IIterator it in iterators)
{
it.Reset();
}
while (true)
{
consumer.Reset();
try
{
consumer.UpdateChildrenData();
}
catch (Exception)
{
goto cycle;
}
for (int i = 0; i < y.Length; i++)
{
object o = left[i].Parameter();
if (o == null)
{
goto cycle;
}
y[i] = (double)o;
o = right[i].Parameter();
if (o == null | o is DBNull)
{
goto cycle;
}
double res = (double)o - y[i];
yr[i] = res;
sigma += res * res;
}
cycle:
foreach (IIterator it in iterators)
{
if (!it.Next())
{
goto m;
}
}
}
m:
return sigma;
}
}
void setDelta(IAlias a, string s, double delta)
{
double x = (double)a[s];
a[s] = x + delta;
}
void setValue(IAlias a, string s, double val)
{
a[s] = val;
}
double getValue(IAlias a, string s)
{
return (double)a[s];
}
static void getIterators(IDataConsumer consumer, List<IIterator> list)
{
for (int i = 0; i < consumer.Count; i++)
{
IMeasurements m = consumer[i];
if (m is IIterator)
{
IIterator it = m as IIterator;
if (!list.Contains(it))
{
list.Add(it);
}
}
if (m is IDataConsumer)
{
IDataConsumer c = m as IDataConsumer;
getIterators(c, list);
}
}
}
void setZeros()
{
if (left != null)
{
for (int i = 0; i < left.Length; i++)
{
left[i] = zero;
right[i] = zero;
}
}
if (r != null)
{
for (int i = 0; i < r.GetLength(0); i++)
{
for (int j = 0; j < r.GetLength(1); j++)
{
r[i, j] = (i == j) ? unity : zero;
}
}
}
return;
for (int i = 0; i < sAliases.Count; i++)
{
for (int j = 0; j < sAliases.Count; j++)
{
d[i, j] = 0;
}
}
for (int i = 0; i < sAliases.Count; i++)
{
dx[i] = 0.000001;
}
}
protected void prepare()
{
getIterators(this, iterators);
setZeros();
aliases = new IAlias[sAliases.Count];
keys = new string[sAliases.Count];
for (int i = 0; i < sAliases.Count; i++)
{
object[] o = StaticDataPerformer.FindAlias(this, sAliases[i]);
aliases[i] = o[0] as IAlias;
keys[i] = o[1] + "";
}
z = new double[sAliases.Count];
indxa = new int[sAliases.Count];
a = new double[sAliases.Count, sAliases.Count];
for (int i = 0; i < sLeft.Count; i++)
{
IMeasure m = find(sLeft[i]);
left[i] = m;
}
for (int i = 0; i < sRight.Count; i++)
{
IMeasure m = find(sRight[i]);
right[i] = m;
}
int n = sR.Count;
int k = sLeft.Count;
mr = new double[k, k];
mr1 = new double[k, k];
y = new double[k];
y1 = new double[k];
yr = new double[k];
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
string sr = sR[i][j];
IMeasure mea = find(sr);
if (mea != null)
{
r[i, j] = mea;
}
}
}
}
private IMeasure find(string name)
{
int n = name.LastIndexOf(".");
if (n < 0)
{
return null;
}
string cn = name.Substring(0, n);
string suff = name.Substring(n + 1);
for (int i = 0; i < measurements.Count; i++)
{
IMeasurements mea = measurements[i];
IAssociatedObject ao = mea as IAssociatedObject;
string na = PureDesktop.GetRelativeName(this, ao);
if (cn.Equals(na))
{
for (int j = 0; j < mea.Count; j++)
{
IMeasure m = mea[j];
if (suff.Equals(m.Name))
{
return m;
}
}
}
}
return null;
}
private void createArrays()
{
if (dx != null)
{
if (dx.Length > 0)
{
a = new double[dx.Length, dx.Length];
indxa = new int[dx.Length];
}
}
if (sLeft.Count > 0)
{
left = new IMeasure[sLeft.Count];
right = new IMeasure[sLeft.Count];
r = new IMeasure[left.Length, left.Length];
if (sAliases.Count > 0)
{
ht = new double[sAliases.Count, sLeft.Count];
htr = new double[sAliases.Count, sLeft.Count];
}
}
}
#endregion
#region ConstMeasure
class ConstMeasure : IMeasure, IDerivation
{
const Double t = 0;
private double c;
const double z = 0;
Func<object> par;
Func<object> der;
public ConstMeasure(double c)
{
this.c = c;
par = getP;
der = getD;
}
#region IMeasure Members
Func<object> IMeasure.Parameter
{
get { return par; }
}
string IMeasure.Name
{
get { return "const" + c; }
}
object IMeasure.Type
{
get { return t; }
}
#endregion
object getP()
{
return c;
}
object getD()
{
return z;
}
#region IDerivation Members
IMeasure IDerivation.Derivation
{
get { return DataPerformer.ConstantMeasure.Zero; }
}
#endregion
}
#endregion
}
}