using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SMAT_CE.Matlab
{
    /// <summary>
    /// Double 向量
    /// </summary>
    public class DoubleVector : IComparable, IComparable<DoubleVector>, IEquatable<DoubleVector>
    {
        #region 构造函数
        /// <summary>
        /// 基本构造函数
        /// </summary>
        public DoubleVector()
            : this(1)
        {

        }
        /// <summary>
        /// 指定长度的构造函数
        /// </summary>
        /// <param name="length">长度</param>
        public DoubleVector(int length)
        {
            _length = length;
            Init(_length);
        }
        /// <summary>
        /// 指定数据的构造函数
        /// </summary>
        /// <param name="value">数据</param>
        public DoubleVector(double[] value)
        {
            _length = value.Length;
            Init(_length);
            SetData(value);
        }
        #endregion

        #region 私有变量
        private double[] _data;
        private int _length;
        #endregion

        #region 公共属性
        /// <summary>
        /// 数据
        /// </summary>
        public double[] Data
        {
            get { return _data; }
        }
        /// <summary>
        /// 长度
        /// </summary>
        public int Length
        {
            get { return _length; }
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="length">指定长度</param>
        public bool Init(int length)
        {
            _length = length;
            if (length < 0)
            {
                return false;
            }
            _data = new double[length];
            return true;
        }
        /// <summary>
        /// 设置数组的值
        /// </summary>
        /// <param name="value">数据</param>
        public void SetData(double[] value)
        {
            _data = (double[])value.Clone();
            //value.CopyTo(_data, 0);
        }
        #endregion

        #region IComparable 成员
        /// <summary>
        /// 比较大小
        /// </summary>
        /// <param name="obj">其它对象</param>
        public int CompareTo(object obj)
        {
            DoubleVector other = obj as DoubleVector;
            if (other == null)
            {
                return 1;
            }
            return CompareTo(other);
        }
        #endregion

        #region IComparable<DoubleArray> 成员
        /// <summary>
        /// 比较大小
        /// </summary>
        /// <param name="other">另一实例</param>
        public int CompareTo(DoubleVector other)
        {
            double tmp = 0.0;
            for (int i = 0; i < _length; i++)
            {
                tmp = _data[i] - other.Data[i];
                if (tmp > 0.0)
                {
                    return 1;
                }
                else if (tmp < 0.0)
                {
                    return -1;
                }
            }
            return 0;
        }
        #endregion

        #region IEquatable<DoubleArray> 成员
        /// <summary>
        /// 相等判断
        /// </summary>
        /// <param name="other">另一实例</param>
        public bool Equals(DoubleVector other)
        {
            if (_length != other.Length)
            {
                return false;
            }
            double tmp = 0.0;
            for (int i = 0; i < _length; i++)
            {
                tmp = _data[i] - other.Data[i];
                if (tmp != 0.0)
                {
                    return false;
                }
            }
            return true;
        }
        #endregion

        #region 重写Equals
        /// <summary>
        /// 重写Equals
        /// </summary>
        /// <param name="obj">其它对象</param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            DoubleVector other = obj as DoubleVector;
            if (other == null)
            {
                return false;
            }
            return Equals(other);
        }
        #endregion

        #region 重写GetHashCode
        /// <summary>
        /// 重写GetHashCode
        /// </summary>
        public override int GetHashCode()
        {
            double sum = 0.0;
            for (int i = 0; i < _length; i++)
            {
                sum += (i + 1) * _data[i] * _data[i];
            }
            return (int)Math.Sqrt(sum);
        }
        #endregion

        #region 重写ToString
        /// <summary>
        /// 重写ToString
        /// </summary>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < _length; i++)
            {
                sb.AppendFormat("{0},", _data[i]);
            }
            sb.Remove(sb.Length - 1, 1);
            return sb.ToString();
        }
        #endregion
    }
}
