/// <summary> /// 与えられたデータからインスタンスを作成します /// </summary> /// <param name="EigenSystem">固有値・固有ベクトル</param> /// <param name="CoefficientMatrix">展開係数</param> /// <param name="AverageVector">平均ベクトル(Vector型から変更したので注意してね!!)</param> /// <param name="Tag">その他データ</param> public PCAData(EigenSystem EigenSystem, Matrix CoefficientMatrix, ColumnVector AverageVector, object Tag) { this.EigenSystemData = new EigenSystem(EigenSystem); this.CoefficientMatrix = new Matrix(CoefficientMatrix); this.AverageVector = new ColumnVector(AverageVector); this.Tag = (object)Tag; }
/// <summary> /// 与えられたベクトル配列から行列を作ります。 /// 全てのベクトルは同じ大きさである必要があります。 /// 与えられたベクトルは縦ベクトルとして扱われます。 /// </summary> /// <param name="Vectors">ベクトル配列</param> public Matrix(Vector[] Vectors) { for (int i = 1; i < Vectors.Length; i++) if (Vectors[i - 1].Length != Vectors[i].Length) throw new ApplicationException("配列の要素数が異なっています"); this.Vectors = new ColumnVector[Vectors.Length]; for (int i = 0; i < Vectors.Length; i++) this.Vectors[i] = new ColumnVector(Vectors[i]); }
/// <summary> /// 与えられたベクトルと同一のベクトルを作成します。 /// </summary> /// <param name="vector">コピー元のベクトル</param> public Vector(Vector vector) { this.element = (double[])vector.element.Clone(); this.Tag = vector.Tag; }
public void AddTransitionVector(Vector TransitionVector) { for (int i = 1; i < TransitionVector.Length; i++) this[(int)TransitionVector[i - 1], (int)TransitionVector[i]]++; }
/// <summary> /// 指定した場所にベクトルを挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual Vector InsertAt(int Index, Vector Vector) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); Vector ReturnVector = new Vector(this.Length + Vector.Length); int Count = 0; while (Count < Index) ReturnVector[Count] = this[Count++]; while (Count - Index < Vector.Length) { ReturnVector[Count] = Vector[Count - Index]; Count++; } while (Count < ReturnVector.Length) { ReturnVector[Count] = this[Count - Vector.Length]; Count++; } return ReturnVector; }
/// <summary> /// 与えられたベクトルと同一の横ベクトルを作成します。 /// </summary> /// <param name="Vector">コピー元のベクトル</param> public RowVector(Vector Vector) : base(Vector) { }
/// <summary> /// 与えられたベクトル配列から正方行列を作成します。 /// </summary> /// <param name="Vectors">ベクトル配列</param> public SquareMatrix(Vector[] Vectors) : base(Vectors) { if (this.ColSize != this.RowSize) throw new ApplicationException("行と列の大きさが違います"); }
/// <summary> /// 指定されたインデックス配列の要素を削除したベクトルを取得します。 /// インデックスは配列でなく1個(ただのint型)でも大丈夫です。 /// </summary> /// <param name="Index">削除する要素のインデックス配列</param> /// <returns>指定されたインデックス配列の要素を削除したベクトル</returns> public virtual Vector RemoveElementAt(params int[] Index) { //↓このコードでも実行可能。でも速度の面で難ありかも。 /* Vector Vector = new Vector(this); for (int i = IndexArray.Length - 1 ; i >= 0; i--) Vector = Vector.RemoveElementAt(IndexArray[i]); */ //あんまり綺麗じゃないけどこっちの方が速度は速いはず Vector ReturnVector = new Vector(this.Length - Index.Length); int Count = 0; for (int i = 0; i < this.Length; i++) { bool flag = true; for (int j = 0; j < Index.Length; j++) if (i == Index[j]) { flag = false; break; } if (flag) ReturnVector[Count++] = this[i]; } return ReturnVector; }
/// <summary> /// 指定した個数の行ベクトルが並んだ行列を取得します。 /// </summary> /// <param name="Vector">ベクトル</param> /// <param name="Size">個数</param> /// <returns>指定した個数のベクトルが並んだ行列</returns> private static Matrix GetSameElementMatrix(Vector Vector, int Size) { ColumnVector[] MatrixElement = new ColumnVector[Size]; for (int i = 0; i < Size; i++) MatrixElement[i] = new ColumnVector(Vector); return new Matrix(MatrixElement); }
/// <summary> /// ベクトルの『要素毎』のかけ算です(内積ではありません)内積は『InnerProduct』で求めて下さい。 /// </summary> /// <param name="LeftVector">最初のベクトル</param> /// <param name="RightVector">二個目のベクトル</param> /// <returns>『要素毎』にかけ算されたベクトル</returns> public static Vector Multiply(Vector LeftVector, Vector RightVector) { if (LeftVector.Length != RightVector.Length) throw new ApplicationException("要素の数が等しくありません"); double[] Element = new double[LeftVector.Length]; for (int i = 0; i < LeftVector.Length; i++) Element[i] = LeftVector[i] * RightVector[i]; return new Vector(Element); }
/// <summary> /// ベクトルの微分を取得するメソッドです。 /// </summary> /// <returns>微分値ベクトル</returns> public virtual Vector GetDifferential() { //TODO 新規追加場所 Vector ResultVector = new Vector(this.Length - 1); for (int i = 0; i < ResultVector.Length; i++) ResultVector[i] = this[i] - this[i + 1]; return ResultVector; }
public static Vector operator /(Vector vector, double scalar) { Vector ReturnVector = new Vector(vector); for (int i = 0; i < vector.Length; i++) ReturnVector.element[i] /= scalar; return ReturnVector; }
/// <summary> /// ベクトルファイルを指定したファイルから読み込みます /// </summary> /// <param name="LoadFileName">読み込みファイル名</param> public static Vector Load(string LoadFileName) { string LoadData; using (System.IO.StreamReader sr = new System.IO.StreamReader(LoadFileName)) { LoadData = sr.ReadToEnd(); } LoadData = LoadData.Replace("\r", ""); LoadData = LoadData.Trim('\n'); string[] StringElement = LoadData.Split('\n'); Vector ReturnVector = new Vector(StringElement.Length); for (int i = 0; i < ReturnVector.Length; i++) ReturnVector[i] = double.Parse(StringElement[i]); return ReturnVector; }
public static Vector operator -(Vector LeftVector, Vector RightVector) { if (LeftVector.Length != RightVector.Length) throw new ApplicationException("要素の数が一致しません。"); Vector ReturnVector = new Vector(LeftVector); for (int i = 0; i < ReturnVector.Length; i++) ReturnVector[i] -= RightVector[i]; return ReturnVector; }
/// <summary> /// スカラー配列をベクトルの前に追加します /// </summary> /// <param name="Scalar">スカラー配列</param> /// <param name="Vector">ベクトル</param> public Vector(double[] Scalar, Vector Vector) { this.element = new double[Scalar.Length + Vector.Length]; for (int i = 0; i < Scalar.Length; i++) this.element[i] = Scalar[i]; for (int i = Scalar.Length; i < this.Length; i++) this.element[i] = Vector[i - Scalar.Length]; }
/// <summary> /// ベクトルの後ろにスカラーを追加します /// </summary> /// <param name="Vector">ベクトル</param> /// <param name="Scalar">スカラー</param> public Vector(Vector Vector, params double[] Scalar) { this.element = new double[Vector.Length + Scalar.Length]; for (int i = 0; i < Vector.Length; i++) this.element[i] = Vector[i]; for (int i = Vector.Length; i < element.Length; i++) this.element[i] = Scalar[i - Vector.Length]; }
/// <summary> /// ベクトルの最後にベクトルを追加します /// </summary> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual Vector InsertAtEnd(Vector Vector) { return this.InsertAt(this.Length, Vector); }
/// <summary> /// 正規化したベクトルを取得するメソッドです。 /// </summary> /// <returns>正規化されたベクトル</returns> public virtual Vector GetNormlizeVector() { double Norm = this.GetNorm(); if (Norm == 0) { //エラーを投げても良い //throw new ApplicationException("ベクトルの大きさが0です。"); //一応、このバージョンは自分と同じベクトル(要素が全部0)を戻す事にする return new Vector(this); } Vector ReturnVector = new Vector(this); ReturnVector /= Norm; return ReturnVector; }
/// <summary> /// ベクトルの最初にベクトルを追加します /// </summary> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual Vector InsertAtStart(Vector Vector) { return this.InsertAt(0, Vector); }
/// <summary> /// 転置行列を取得します。 /// </summary> /// <returns>転置された行列</returns> public virtual Matrix GetTranspose() { Vector[] CulcVec = new Vector[this.RowSize]; for (int i = 0; i < this.RowSize; i++) CulcVec[i] = this.GetRowVector(i); return new Matrix(CulcVec); }
/// <summary> /// 指定した範囲の要素を削除したベクトルを取得します /// </summary> /// <param name="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>指定した範囲の要素を削除したベクトル</returns> public virtual Vector RemoveRange(int StartIndex, int EndIndex) { if (StartIndex > EndIndex || StartIndex >= this.Length || StartIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndIndex < 0 || EndIndex >= this.Length) throw new ApplicationException("指定位置が正しくありません"); Vector ReturnVector = new Vector(this.Length - (EndIndex - StartIndex) - 1); for (int i = 0; i < StartIndex; i++) ReturnVector[i] = this[i]; for (int i = 1; i < this.Length - EndIndex; i++) ReturnVector[i + StartIndex -1] = this[i + EndIndex]; return ReturnVector; }
/// <summary> /// 与えられた固有ベクトルと固有値からクラスを作成します /// </summary> /// <param name="EigenVector">固有ベクトル</param> /// <param name="EigenValue">固有値</param> public EigenVectorAndValue(Vector EigenVector, double EigenValue) { this.Vector = new Vector(EigenVector); this.Value = EigenValue; }
/// <summary> /// ベクトルを指定した個数に分割するメソッドです。 /// </summary> /// <param name="Length">分割後のベクトル数</param> /// <returns>指定した要素数に分割されたベクトル</returns> public virtual Vector[] GetSeparatedVector(int Length) { if (this.Length % Length != 0) throw new ApplicationException("要素が割り切れません"); //TODO 新規追加場所 Vector[] ResultVector = new Vector[Length]; for (int i = 0; i < ResultVector.Length; i++) { ResultVector[i] = new Vector(this.Length / Length); for (int j = 0; j < ResultVector[i].Length; j++) ResultVector[i][j] = this[i * ResultVector[i].Length + j]; } return ResultVector; }
/// <summary> /// 全ての固有ベクトルを行列形式で取得します。 /// </summary> /// <returns>全ての固有ベクトル</returns> public Matrix GetEigenVectors() { Vector[] ReturnVector = new Vector[EigenListData.Count]; for (int i = 0; i < EigenListData.Count; i++) ReturnVector[i] = EigenListData[i].EigenVector; return new Matrix(ReturnVector); }
/// <summary> /// 固有ベクトルの大きさを正規化するメソッドです。 /// </summary> public void Normlize() { Vector = Vector.GetNormlizeVector(); }
/// <summary> /// 指定された範囲の部分ベクトルを取得します /// </summary> /// <param name="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>部分ベクトル</returns> public virtual Vector GetVectorBetween(int StartIndex, int EndIndex) { if (StartIndex > EndIndex || StartIndex >= this.Length || StartIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndIndex < 0 || EndIndex >= this.Length) throw new ApplicationException("指定位置が正しくありません"); Vector ReturnVector = new Vector(EndIndex - StartIndex + 1); for (int i = StartIndex; i <= EndIndex; i++) ReturnVector[i - StartIndex] = this[i]; return ReturnVector; }
/// <summary> /// コピーコンストラクタ /// </summary> /// <param name="BaseData">コピー元データ</param> public EigenVectorAndValue(EigenVectorAndValue BaseData) { this.Vector = BaseData.EigenVector; this.Value = BaseData.EigenValue; }
/// <summary> /// 指定したベクトルとの内積を求めます。ベクトルの次元数は等しくないとエラーが発生します。 /// </summary> /// <param name="Vector">内積を求めるための対象となるベクトル</param> /// <returns>内積</returns> public virtual double InnerProduct(Vector Vector) { if (this.Length != Vector.Length) throw new ApplicationException("要素の数が一致しません。"); double Sum = 0; for (int i = 0; i < this.Length; i++) Sum += this[i] * Vector[i]; return Sum; }
/// <summary> /// 指定した場所にスカラー値を挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Scalar">スカラー値</param> /// <returns>値が挿入されたベクトル</returns> public virtual Vector InsertAt(int Index, double Scalar) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); Vector ReturnVector = new Vector(this.Length + 1); int Count = 0; while (Count < Index) ReturnVector[Count] = this[Count++]; ReturnVector[Count++] = Scalar; while (Count < ReturnVector.Length) { ReturnVector[Count] = this[Count - 1]; Count++; } return ReturnVector; }
/// <summary> /// 与えられたベクトル配列から対称行列を作成します /// </summary> /// <param name="Vectors">ベクトル配列</param> public SymmetricMatrix(Vector[] Vectors) : base(Vectors) { if (!this.CheckElement()) throw new ApplicationException("行列が対称行列ではありません"); }