/// <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(ColumnVector[] 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]); }
public Matrix GetTransitionProbabilityMatrix() { Matrix ResultMatrix = new Matrix(this.RowSize, this.ColSize); ColumnVector SumVector = new ColumnVector(this.RowSize); for (int i = 0; i < SumVector.Length; i++) SumVector[i] = this.GetRowVector(i).GetSum(); for (int i = 0; i < ResultMatrix.RowSize; i++) if (SumVector[i] != 0) ResultMatrix = ResultMatrix.SetRowVectorAt(i, this.GetRowVector(i) / SumVector[i]); return ResultMatrix; }
/// <summary> /// csvファイルのデータを読み込んで行列(Matrix)として返す関数 /// </summary> /// <param name="FileName">読み込むファイルの名前</param> /// <returns>読み込んだデータをMatrix型に入れたもの</returns> public static Matrix LoadCSVWithLabel(string FileName) { List<ColumnVector> Vectors = new List<ColumnVector>(); string[] Datas; using (System.IO.StreamReader sr = new System.IO.StreamReader(FileName)) { string Data = sr.ReadToEnd();//与えられたFileNameの中身を全部読み込む Data = Data.Replace("\r", "");//\rがあれば消す(空白に置き換える) Data = Data.TrimEnd('\n');//末尾の\nを消す Datas = Data.Split('\n');//改行ごとに分割して配列に入れる } foreach (string Data in Datas) { string[] sValues = Data.Split(',');//Dateを,で分割して配列に入れていく ColumnVector Vector = new ColumnVector(sValues.Length);//縦ベクトル for (int i = 0; i < sValues.Length; i++) Vector[i] = double.Parse(sValues[i]); Vectors.Add(Vector);//リストに加えていく。縦ベクトルが繋がってく感じ? } return new Matrix(Vectors.ToArray()); }
/// <summary> /// 行列の縦ベクトル要素をすべて連結した縦ベクトルを取得します /// </summary> /// <returns>連結された縦ベクトル</returns> public virtual ColumnVector GetConbineColumnVector() { ColumnVector ResultVector = this.GetColVector(0); for (int i = 1; i < this.ColSize; i++) ResultVector = new ColumnVector(ResultVector.InsertAtEnd(this.GetColVector(i))); return ResultVector; }
/// <summary> /// 指定された範囲の部分ベクトルを取得します /// </summary> /// <param name="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>部分ベクトル</returns> public virtual ColumnVector 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("指定位置が正しくありません"); ColumnVector ReturnVector = new ColumnVector(EndIndex - StartIndex + 1); for (int i = StartIndex; i <= EndIndex; i++) ReturnVector[i - StartIndex] = this[i]; return ReturnVector; }
/// <summary> /// ベクトルを指定した個数に分割するメソッドです。 /// </summary> /// <param name="Length">分割後のベクトル数</param> /// <returns>指定した要素数に分割されたベクトル</returns> public virtual ColumnVector[] GetSeparatedVector(int Length) { if (this.Length % Length != 0) throw new ApplicationException("要素が割り切れません"); //TODO 新規追加場所 ColumnVector[] ResultVector = new ColumnVector[Length]; for (int i = 0; i < ResultVector.Length; i++) { ResultVector[i] = new ColumnVector(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> /// <param name="ColumnIndex">0から始まる列のインデックス</param> /// <param name="Matrix">挿入する行列</param> /// <returns>指定した列位置に行列を挿入した行列</returns> public virtual Matrix InsertMatrixAtColumnIndex(int ColumnIndex, Matrix Matrix) { if (this.RowSize != Matrix.RowSize) throw new ApplicationException("行のサイズが異なっています"); if (ColumnIndex < 0 | ColumnIndex > this.ColSize) throw new ApplicationException("インデックスが範囲外です"); ColumnVector[] Vectors = new ColumnVector[this.ColSize + Matrix.ColSize]; for (int i = 0; i < ColumnIndex; i++) Vectors[i] = this.GetColVector(i); for (int i = ColumnIndex; i < ColumnIndex + Matrix.ColSize; i++) Vectors[i] = Matrix.GetColVector(i - ColumnIndex); for (int i = ColumnIndex + Matrix.ColSize; i < Vectors.Length; i++) Vectors[i] = this.GetColVector(i - Matrix.ColSize); return new Matrix(Vectors); }
/// <summary> /// 指定した列インデックス要素を削除した行列を取得します /// </summary> /// <param name="ColumnIndex">削除する列インデックス</param> /// <returns>指定した列インデックス要素を削除した行列</returns> public virtual Matrix RemoveColumnElementAt(int ColumnIndex) { if (ColumnIndex > this.ColSize) throw new ApplicationException("インデックスが範囲外です"); ColumnVector[] Vectors = new ColumnVector[this.ColSize - 1]; for (int i = 0; i < ColumnIndex; i++) Vectors[i] = this.GetColVector(i); for (int i = ColumnIndex; i < Vectors.Length; i++) Vectors[i] = this.GetColVector(i + 1); return new Matrix(Vectors); }
/// <summary> /// 列方向のノルムを1にした行列を返します。 /// </summary> /// <returns>列方向のノルムが1の行列</returns> public virtual Matrix GetNormalizedMatrixCol() { ColumnVector[] ReturnVector = new ColumnVector[ColSize]; //現在の行列の要素ベクトルの要素を1にしたベクトルを取得 for (int i = 0; i < ColSize; i++) ReturnVector[i] = Vectors[i].GetNormlizeVector(); return new Matrix(ReturnVector); }
/// <summary> /// 指定した場所にスカラー値を挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Scalar">スカラー値</param> /// <returns>値が挿入されたベクトル</returns> public virtual ColumnVector InsertAt(int Index, double Scalar) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); ColumnVector ReturnVector = new ColumnVector(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> /// 指定されたインデックス配列の要素を削除したベクトルを取得します。 /// インデックスは配列でなく1個(ただのint型)でも大丈夫です。 /// </summary> /// <param name="Index">削除する要素のインデックス配列</param> /// <returns>指定されたインデックス配列の要素を削除したベクトル</returns> public virtual ColumnVector RemoveElementAt(params int[] Index) { //↓このコードでも実行可能。でも速度の面で難ありかも。 /* Vector Vector = new Vector(this); for (int i = IndexArray.Length - 1 ; i >= 0; i--) Vector = Vector.RemoveElementAt(IndexArray[i]); */ //あんまり綺麗じゃないけどこっちの方が速度は速いはず ColumnVector ReturnVector = new ColumnVector(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="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>指定した範囲の要素を削除したベクトル</returns> public virtual ColumnVector 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("指定位置が正しくありません"); ColumnVector ReturnVector = new ColumnVector(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="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual ColumnVector InsertAtStart(ColumnVector Vector) { return this.InsertAt(0, Vector); }
/// <summary> /// ベクトルの最後にベクトルを追加します /// </summary> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual ColumnVector InsertAtEnd(ColumnVector Vector) { return this.InsertAt(this.Length, Vector); }
/// <summary> /// 指定した場所にベクトルを挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual ColumnVector InsertAt(int Index, ColumnVector Vector) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); ColumnVector ReturnVector = new ColumnVector(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; }
public virtual Matrix GetIndexColumnVectorMatrix(int[] Index) { ColumnVector[] ResultVector = new ColumnVector[Index.Length]; for (int i = 0; i < ResultVector.Length; i++) ResultVector[i] = this.GetColVector(Index[i]); return new Matrix(ResultVector); }
/// <summary> /// 指定した縦ベクトルを最後に挿入します /// </summary> /// <param name="ColumnVector">挿入する横ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertColumnVectorAtEnd(ColumnVector ColumnVector) { return this.InsertColumnVectorAt(this.ColSize, ColumnVector); }
/// <summary> /// 指定された列範囲の部分行列を取得します /// </summary> /// <param name="StartColumnIndex">開始列</param> /// <param name="EndColumnIndex">終了列</param> /// <returns>指定された列範囲の部分行列</returns> public virtual Matrix GetMatrixColumnBetween(int StartColumnIndex, int EndColumnIndex) { if (StartColumnIndex > EndColumnIndex || StartColumnIndex >= this.ColSize || StartColumnIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndColumnIndex < 0 || EndColumnIndex >= this.ColSize) throw new ApplicationException("指定位置が正しくありません"); ColumnVector[] Vectors = new ColumnVector[EndColumnIndex - StartColumnIndex + 1]; for (int i = StartColumnIndex; i <= EndColumnIndex; i++) Vectors[i - StartColumnIndex] = this.GetColVector(i); return new Matrix(Vectors); }
/// <summary> /// 指定したベクトルとの内積を求めます。ベクトルの次元数は等しくないとエラーが発生します。 /// </summary> /// <param name="Vector">内積を求めるための対象となるベクトル</param> /// <returns>内積</returns> public double InnerProduct(ColumnVector 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="ColumnVector">挿入する横ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertColumnVectorAt(int Index, ColumnVector ColumnVector) { if (this.RowSize != ColumnVector.Length) throw new ApplicationException("要素の数が違います"); if (Index < 0 || Index > ColSize) throw new ApplicationException("インデックスが範囲外です"); ColumnVector[] Vectors = new ColumnVector[this.ColSize + 1]; for (int i = 0; i < Index; i++) Vectors[i] = this.GetColVector(i); Vectors[Index] = ColumnVector; for (int i = Index + 1; i < Vectors.Length; i++) Vectors[i] = this.GetColVector(i - 1); return new Matrix(Vectors); }
public ColumnVector GetEigenValues() { ColumnVector ReturnVector = new ColumnVector(EigenListData.Count); for (int i = 0; i < EigenListData.Count; i++) ReturnVector[i] = EigenListData[i].EigenValue; return ReturnVector; }
/// <summary> /// 指定した縦ベクトルを最初に挿入します /// </summary> /// <param name="ColumnVector">挿入する横ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertColumnVectorAtStart(ColumnVector ColumnVector) { return this.InsertColumnVectorAt(0, ColumnVector); }
/// <summary> /// 与えられたベクトルと同一の横ベクトルを作成します。 /// </summary> /// <param name="Vector">コピー元のベクトル</param> public RowVector(ColumnVector Vector) : base((Vector)Vector) { }
public virtual Matrix SetColumnVectorAt(int Index, ColumnVector ColumnVector) { Matrix ResultMatrix = this.RemoveColumnElementAt(Index); return ResultMatrix.InsertColumnVectorAt(Index, ColumnVector); }
/// <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> /// 指定した範囲の列要素を削除した行列を取得します /// </summary> /// <param name="StartIndex">削除開始列インデックス</param> /// <param name="EndIndex">削除終了列インデックス</param> /// <returns>指定した範囲の列要素を削除した行列</returns> public virtual Matrix RemoveColumnElementRange(int StartIndex, int EndIndex) { if (StartIndex > EndIndex || StartIndex >= this.ColSize || StartIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndIndex < 0 || EndIndex >= this.ColSize) throw new ApplicationException("指定位置が正しくありません"); ColumnVector[] Vectors = new ColumnVector[this.ColSize - (EndIndex - StartIndex) - 1]; for (int i = 0; i < StartIndex; i++) Vectors[i] = this.GetColVector(i); for (int i = 1; i < this.ColSize - EndIndex; i++) Vectors[i + StartIndex - 1] = this.GetColVector(i + EndIndex); return new Matrix(Vectors); }
/// <summary> /// 指定した個数の列ベクトルが並んだ行列を取得します。 /// 主に平均ベクトルに対して使ったりします。 /// </summary> /// <param name="Vector">列ベクトル</param> /// <param name="Size">個数</param> /// <returns>指定した個数の列ベクトルが並んだ行列</returns> public static Matrix GetSameElementMatrix(ColumnVector Vector, int Size) { return Matrix.GetSameElementMatrix((Vector)Vector, Size); }
/// <summary> /// Fisherの正確確率検定 /// </summary> /// <param name="Matrix">データ表</param> /// <param name="test">両側検定か片側検定か</param> /// <returns>p値</returns> internal static double FishersExact(Matrix Matrix, bool test) { int sum = 0; if ((int)Matrix.GetRowVector(0).GetSum() > (int)Matrix.GetColVector(0).GetSum()) sum = (int)Matrix.GetColVector(0).GetSum() + 1; else sum = (int)Matrix.GetRowVector(0).GetSum() + 1; ColumnVector AVector = new ColumnVector(sum); ColumnVector BVector = new ColumnVector(sum); ColumnVector CVector = new ColumnVector(sum); ColumnVector DVector = new ColumnVector(sum); ColumnVector ADBC = new ColumnVector(sum); ColumnVector OccurrenceProbabilityVector = new ColumnVector(sum); int DataNumber = (int)Matrix[0, 0]; for (int i = 0; i < AVector.Length; i++) { AVector[i] = i; BVector[i] = Matrix.GetRowVector(0).GetSum() - AVector[i]; CVector[i] = Matrix.GetColVector(0).GetSum() - AVector[i]; DVector[i] = Matrix.GetColVector(1).GetSum() - BVector[i]; ADBC[i] = AVector[i] * DVector[i] - BVector[i] * CVector[i]; OccurrenceProbabilityVector[i] = GetFishersExactProbability((int)AVector[i], (int)BVector[i], (int)CVector[i], (int)DVector[i]); } double P = 0; //両側検定(true) if (test) { for (int i = 0; i < AVector.Length; i++) if (ADBC[DataNumber] > System.Math.Abs(ADBC[i])) P += ADBC[i]; } //片側検定(false) else { for (int i = 0; i < AVector.Length; i++) if (ADBC[DataNumber] <= ADBC[i]) P += OccurrenceProbabilityVector[i]; } return P; }
/// <summary> /// 正規化したベクトルを取得するメソッドです。 /// </summary> /// <returns>正規化されたベクトル</returns> public virtual ColumnVector GetNormlizeVector() { double Norm = this.GetNorm(); if (Norm == 0) { //エラーを投げても良い //throw new ApplicationException("ベクトルの大きさが0です。"); //一応、このバージョンは自分と同じベクトル(要素が全部0)を戻す事にする return new ColumnVector(this); } ColumnVector ReturnVector = new ColumnVector(this); ReturnVector /= Norm; return ReturnVector; }