using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using CategoryTheory;
using DiagramUI;
using FormulaEditor;
using GeneralLinearMethod;
using AnalyticPolynom;
namespace DataPerformer
{
[Serializable()]
public class Series : ISerializable, ICategoryObject,
IArgumentSelection, IMeasure, IMeasurements, IStructuredSelectionCollection,
IUnary, IObjectOperation, IOperationAcceptor, IComments
{
#region Fields
private static readonly Double a = 0;
private readonly string[] var = {"x"};
private readonly double eps = 1e-9;
static public readonly string[] HasEqualStepString = new string[] {"This series has equal steps",
"This series has no equal steps"};
protected List<double[]> points = new List<double[]>();
protected string x = "";
protected string y = "";
public double[] parameter = new double[2];
private object obj;
private double step = 0;
protected int[] pointStart = new int[2];
protected int[] pointFinish = new int[2];
private ArrayList comments = new ArrayList();
private object type = new object[] {a, a};
private object[] meaX = new object[2];
private object[] meaY = new object[2];
private DataPerformer.MeasureParameter[] measureParameter = new MeasureParameter[2];
private IMeasure measureY;
private IStructuredSelection[] selections;
#endregion
#region Constructors
public Series()
{
initialize();
selections = new IStructuredSelection[]{new XSelection(this), this};
}
/// <summary>
/// Deserialization constructor
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
protected Series(SerializationInfo info, StreamingContext context)
{
try
{
points = info.GetValue("Points", typeof(List<double[]>)) as List<double[]>;
}
catch (Exception)
{
ArrayList p = info.GetValue("Points", typeof(ArrayList)) as ArrayList;
for (int i = 0; i < p.Count; i++)
{
double[] d = p[i] as double[];
points.Add(d);
}
}
try
{
comments = (ArrayList)info.GetValue("Comments", typeof(ArrayList));
}
catch (Exception)
{
}
Post();
}
#endregion
#region ISerializable Members
/// <summary>
/// ISerializable interface implementation
/// </summary>
/// <param name="info">Serialization info</param>
/// <param name="context">Streaming context</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Points", points);
info.AddValue("Comments", comments);
}
#endregion
#region IStructuredSelectionCollection Members
int IStructuredSelectionCollection.Count
{
get
{
return 2;
}
}
IStructuredSelection IStructuredSelectionCollection.this[int i]
{
get
{
return selections[i];
}
}
#endregion
#region IMeasurements Members
IMeasure DataPerformer.IMeasurements.this[int n]
{
get
{
if (n == 0)
{
return this;
}
return measureY;
}
}
public void UpdateMeasurements()
{
}
public string SourceName
{
get
{
IObjectLabel l = obj as IObjectLabel;
return l.Name;
}
}
public bool IsUpdated
{
get
{
return true;
}
set
{
}
}
int IMeasurements.Count
{
get
{
return 2;
}
}
#endregion
#region IMeasure Members
public DataPerformer.MeasureParameter Parameter
{
get
{
return measureParameter[0];
}
}
public DataPerformer.MeasureParameter Derivation
{
get
{
return null;
}
}
public string Name
{
get
{
return "X";
}
}
public double Factor
{
get
{
return 1;
}
}
public object Type
{
get
{
initMea();
return type;
}
}
#endregion
#region IXmlCreator Members
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
public XmlElement CreateXml(XmlDocument doc)
{
XmlElement el = doc.CreateElement("Plot");
XmlAttribute nx = doc.CreateAttribute("X");
nx.Value = X;
el.Attributes.Append(nx);
XmlAttribute ny = doc.CreateAttribute("Y");
ny.Value = Y;
el.Attributes.Append(ny);
foreach(double[] p in points)
{
XmlElement ep = doc.CreateElement("PlotPoint");
XmlAttribute ax = doc.CreateAttribute("PlotX");
ax.Value = "" + p[0];
ep.Attributes.Append(ax);
XmlAttribute ay = doc.CreateAttribute("PlotY");
ay.Value = "" + p[1];
ep.Attributes.Append(ay);
el.AppendChild(ep);
}
return el;
}
#endregion
#region ICategoryObject members
/// <summary>
/// The category of this object
/// </summary>
public ICategory Category
{
get
{
return null;
}
}
/// <summary>
/// The identical arrow of this object
/// </summary>
public ICategoryArrow Id
{
get
{
return null;
}
}
#endregion
#region IAssociatedObject members
/// <summary>
/// Associated object
/// </summary>
public object Object
{
get
{
return obj;
}
set
{
obj = value;
}
}
#endregion
#region IObjectOperation Members
object IObjectOperation.this[object[] x]
{
get
{
double a = (double) x[0];
return GetValue(a);
}
}
public object ReturnType
{
get
{
return a;
}
}
public int Arity
{
get
{
return 1;
}
}
public bool IsPowered
{
get
{
return true;
}
}
#endregion
#region IOperationAcceptor Members
public IObjectOperation Accept(object type)
{
if (type.Equals(a))
{
return this;
}
return null;
}
#endregion
#region IUnary Members
/// <summary>
/// Gets value of function
/// </summary>
/// <param name="x">Argument</param>
/// <returns></returns>
public double GetValue(double x)
{
return this[x][0];
}
/// <summary>
/// Gets derivation of function
/// </summary>
/// <param name="x">Argument</param>
/// <returns></returns>
public double GetDerivation(double x)
{
return this[x][1];
}
#endregion
public List<double[]> Points
{
get { return points; }
}
protected void Post()
{
measureParameter[0] = new DataPerformer.MeasureParameter(parX);
measureParameter[1] = new DataPerformer.MeasureParameter(parY);
measureY = YMeasure.getMeasure(this);
selections = new IStructuredSelection[] { new XSelection(this), this };
checkEqualStep();
}
/// <summary>
/// Calculates synchronized selection
/// </summary>
/// <param name="selection">The etalon selection</param>
/// <returns>Synchronized selection</returns>
public IArgumentSelection SynchronizedSelection(IArgumentSelection selection)
{
if (!(selection is Series))
{
throw new Exception("Incompatible selections");
}
Series etalon = selection as Series;
Series s = new Series();
for (int i = 0; i < etalon.PointsCount; i++)
{
double x = etalon[i, 0];
double a = this[0, 0];
if (x < a)
{
s.AddXY(x, this[0, 1]);
continue;
}
double b = this[PointsCount - 1, 0];
if (x > b)
{
s.AddXY(x, this[PointsCount - 1, 1]);
continue;
}
s.AddXY(x, this[x][1]);
}
return s;
}
public string HasEqualSteps
{
get
{
if (step == 0)
{
return PureDesktop.GetResourceString(HasEqualStepString[1]);
}
return PureDesktop.GetResourceString(HasEqualStepString[0]);
}
}
#region IStructuredSelection Members
/// <summary>
/// Dimension of data
/// </summary>
public int DataDimension
{
get
{
return points.Count;
}
}
/// <summary>
/// Access to n - th element
/// </summary>
double? IStructuredSelection.this[int n]
{
get
{
return this[n, 1];
}
}
/// <summary>
/// Weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetWeight(int n)
{
return 1;
}
/// <summary>
/// Aprior weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetApriorWeight(int n)
{
return 1;
}
/// <summary>
/// Tolerance of it - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>Tolerance</returns>
public int GetTolerance(int n)
{
return 1;
}
/// <summary>
/// Sets tolerance of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <param name="tolerance">Tolerance to set</param>
public void SetTolerance(int n, int tolerance)
{
}
/// <summary>
/// The "is fixed amount" sign
/// </summary>
public bool HasFixedAmount
{
get
{
return true;
}
}
string IStructuredSelection.Name
{
get
{
return "Y";
}
}
/// <summary>
/// Count of points
/// </summary>
public int PointsCount
{
get
{
return points.Count;
}
}
/// <summary>
/// Free variables
/// </summary>
public string[] Variables
{
get
{
return var;
}
}
/// <summary>
/// Dimension of output vector
/// </summary>
public int VectorDimension
{
get
{
return 1;
}
}
#endregion
/// <summary>
/// Gets value of variable
/// </summary>
double IArgumentSelection.this[int i, string str]
{
get
{
return this[i, 0];
}
}
#region Specific Members
/// <summary>
/// Copies from another series
/// </summary>
/// <param name="s">Pattern series</param>
public void CopyFrom(Series s)
{
points.Clear();
for (int i = 0; i < s.Count; i++)
{
AddXY(s[i, 0], s[i, 1]);
}
step = 0;
checkEqualStep();
}
/// <summary>
/// Gets or sets comments
/// </summary>
public ArrayList Comments
{
get
{
return comments;
}
set
{
if (value != null)
{
comments.Clear();
foreach (ICloneable c in value)
comments.Add(c.Clone());
}
}
}
/// <summary>
/// Adds point
/// </summary>
/// <param name="x">x - coordinate</param>
/// <param name="y">y - coordinate</param>
public void AddXY(double x, double y)
{
points.Add(new double[]{x, y});
}
/// <summary>
/// Access to i - th point (j = 0 access to x - coordinate, j = 1 access to y coordinate)
/// </summary>
public double this[int i, int j]
{
get
{
double[] x = points[i] as double[];
return x[j];
}
}
/// <summary>
/// Clears itself
/// </summary>
public virtual void Clear()
{
points.Clear();
}
/// <summary>
/// Count of points
/// </summary>
public int Count
{
get
{
return points.Count;
}
}
/// <summary>
/// Size of this series
/// </summary>
public double[,] Size
{
get
{
double[,] size = new double[2, 2];
for (int i = 0; i < points.Count; i++)
{
double[] x = (double[])points[i];
if (i == 0)
{
size[0, 0] = x[0];
size[0, 1] = x[1];
size[1, 0] = x[0];
size[1, 1] = x[1];
continue;
}
for (int j = 0; j < 2; j++)
{
if (x[j] < size[0, j])
{
size[0, j] = x[j];
}
if (x[j] > size[1, j])
{
size[1, j] = x[j];
}
}
}
return size;
}
}
/// <summary>
/// Creates correspond xml
/// </summary>
/// <param name="doc">document to create element</param>
/// <returns>The created element</returns>
public XmlElement CreateXmlPoint(int n, XmlDocument doc)
{
XmlElement el = doc.CreateElement("CommonPlotPoint");
XmlAttribute nx = doc.CreateAttribute("NX");
nx.Value = X;
el.Attributes.Append(nx);
XmlAttribute ny = doc.CreateAttribute("NY");
ny.Value = Y;
el.Attributes.Append(ny);
double[] p = points[n] as double[];
XmlAttribute x = doc.CreateAttribute("X");
x.Value = p[0] + "";
el.Attributes.Append(x);
XmlAttribute y = doc.CreateAttribute("Y");
y.Value = p[1] + "";
el.Attributes.Append(y);
return el;
}
/// <summary>
/// Access to value of function and its derivation
/// </summary>
public double[] this[double x]
{
get
{
if (this[0, 0] > x)
{
//throw new Exception("Argument too small");
parameter[0] = this[0, 1];
parameter[1] = 0;
return parameter;
}
if (this[Count - 1, 0] < x)
{
//throw new Exception("Argument too large");
parameter[0] = this[Count - 1, 1];
parameter[1] = 0;
return parameter;
}
if (step != 0)
{
int i = (int)(Math.Floor((x - this[0, 0]) / step));
if (i == Count - 1)
{
--i;
}
double x1 = this[i, 0];
double x2 = this[i + 1, 0];
double y1 = this[i, 1];
double y2 = this[i + 1, 1];
parameter[1] = (y2 - y1) / (x2 - x1);
parameter[0] = y1 + parameter[1] * (x - x1);
return parameter;
}
for (int i = 1; i < Count; i++)
{
double x2 = this[i, 0];
if (x2 > x)
{
double x1 = this[i - 1, 0];
double y1 = this[i - 1, 1];
double y2 = this[i, 1];
parameter[1] = (y2 - y1) / (x2 - x1);
parameter[0] = y1 + parameter[1] * (x - x1);
break;
}
}
return parameter;
}
}
public string X
{
get
{
return x;
}
set
{
x = value;
}
}
public string Y
{
get
{
return y;
}
set
{
y = value;
}
}
private object parX()
{
initMea();
return meaX;
}
private object parY()
{
initMea();
return meaY;
}
private void initMea()
{
if (meaX.Length == points.Count)
{
return;
}
meaX = new object[points.Count];
meaY = new object[meaX.Length];
type = new object[meaX.Length];
for (int i = 0; i < meaX.Length; i++)
{
meaX[i] = this[i, 0];
meaY[i] = this[i, 1];
}
Double a = 0;
type = new ArrayReturnType(a, new int[] { points.Count });
}
/// <summary>
/// Checks whether series has equal step
/// </summary>
private void checkEqualStep()
{
if (points.Count < 2)
{
return;
}
double s = 0;
double t = 0;
for (int i = 0; i < points.Count; i++)
{
double[] p = points[i] as double[];
if (i == 1)
{
s = p[0] - t;
}
if (i > 1)
{
if (Math.Abs(s - (p[0] - t)) > (eps * Math.Abs(s)))
{
return;
}
}
t = p[0];
}
step = s;
}
/// <summary>
/// Initialization
/// </summary>
private void initialize()
{
measureParameter[0] = new DataPerformer.MeasureParameter(parX);
measureParameter[1] = new DataPerformer.MeasureParameter(parY);
measureY = YMeasure.getMeasure(this);
points = new List<double[]>();
pointStart = new int[2];
pointFinish = new int[2];
}
#endregion
class YMeasure : IMeasure
{
private Series s;
public static IMeasure getMeasure(Series s)
{
return new YMeasure(s);
}
YMeasure(Series s)
{
this.s = s;
}
#region IMeasure Members
public DataPerformer.MeasureParameter Parameter
{
get
{
return s.measureParameter[1];
}
}
public DataPerformer.MeasureParameter Derivation
{
get
{
return null;
}
}
public string Name
{
get
{
return "Y";
}
}
public double Factor
{
get
{
return 1;
}
}
public object Type
{
get
{
return s.Type;
}
}
#endregion
}
class XSelection : IStructuredSelection
{
private Series s;
#region IStructuredSelection Members
public XSelection(Series s)
{
this.s = s;
}
/// <summary>
/// Dimension of data
/// </summary>
public int DataDimension
{
get
{
return s.points.Count;
}
}
/// <summary>
/// Access to n - th element
/// </summary>
double? IStructuredSelection.this[int n]
{
get
{
return s[n, 0];
}
}
/// <summary>
/// Weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetWeight(int n)
{
return 1;
}
/// <summary>
/// Aprior weight of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>The weight</returns>
public double GetApriorWeight(int n)
{
return 1;
}
/// <summary>
/// Tolerance of it - th element
/// </summary>
/// <param name="n">Element number</param>
/// <returns>Tolerance</returns>
public int GetTolerance(int n)
{
return 1;
}
/// <summary>
/// Sets tolerance of n - th element
/// </summary>
/// <param name="n">Element number</param>
/// <param name="tolerance">Tolerance to set</param>
public void SetTolerance(int n, int tolerance)
{
}
/// <summary>
/// The "is fixed amount" sign
/// </summary>
public bool HasFixedAmount
{
get
{
return true;
}
}
/// <summary>
/// Count of points
/// </summary>
public int PointsCount
{
get
{
return s.points.Count;
}
}
/// <summary>
/// Free variables
/// </summary>
public string[] Variables
{
get
{
return s.var;
}
}
/// <summary>
/// Dimension of output vector
/// </summary>
public int VectorDimension
{
get
{
return 1;
}
}
/// <summary>
/// Gets value of variable
/// </summary>
/*double IArgumentSelection.this[int i, string str]
{
get
{
return this[i, 0];
}
}*/
public string Name
{
get
{
return "X";
}
}
#endregion
}
}
}