/// <summary> /// 与えられた横ベクトル配列から行列を作ります。 /// 全てのベクトルは同じ大きさである必要があります。 /// </summary> /// <param name="Vectors">横ベクトル配列</param> public Matrix(RowVector[] 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[0].Length]; for (int i = 0; i < this.Vectors.Length; i++) { this.Vectors[i] = new ColumnVector(Vectors.Length); for (int j = 0; j < Vectors.Length; j++) this[j, i] = Vectors[j][i]; } }
public virtual Matrix SetRowVectorAt(int Index, RowVector RowVector) { Matrix ResultMatrix = this.RemoveRowElemntAt(Index); return ResultMatrix.InsertRowVectorAt(Index, RowVector); }
/// <summary> /// 指定した行インデックス要素を削除した行列を取得します /// </summary> /// <param name="RowIndex">削除する行インデックス</param> /// <returns>指定した行インデックス要素を削除した行列</returns> public virtual Matrix RemoveRowElemntAt(int RowIndex) { if (RowIndex > this.RowSize) throw new ApplicationException("インデックスが範囲外です"); RowVector[] Vectors = new RowVector[this.RowSize - 1]; for (int i = 0; i < RowIndex; i++) Vectors[i] = this.GetRowVector(i); for (int i = RowIndex; i < Vectors.Length; i++) Vectors[i] = this.GetRowVector(i + 1); return new Matrix(Vectors); }
public static RowVector operator -(RowVector LeftVector, RowVector RightVector) { if (LeftVector.Length != RightVector.Length) throw new ApplicationException("要素の数が一致しません。"); RowVector ReturnVector = new RowVector(LeftVector); for (int i = 0; i < ReturnVector.Length; i++) ReturnVector[i] -= RightVector[i]; return ReturnVector; }
/// <summary> /// 指定した横ベクトルを最初に挿入します /// </summary> /// <param name="RowVector">挿入する縦ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertRowVectorAtStart(RowVector RowVector) { return this.InsertRowVectorAt(0, RowVector); }
/// <summary> /// 指定した横ベクトルを指定した位置に挿入します /// </summary> /// <param name="Index">0から始まるインデックス</param> /// <param name="RowVector">挿入する縦ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertRowVectorAt(int Index, RowVector RowVector) { if (this.ColSize != RowVector.Length) throw new ApplicationException("要素の数が違います"); if (Index < 0 || Index > RowSize) throw new ApplicationException("インデックスが範囲外です"); RowVector[] Vectors = new RowVector[this.RowSize + 1]; for (int i = 0; i < Index; i++) Vectors[i] = this.GetRowVector(i); Vectors[Index] = RowVector; for (int i = Index + 1; i < Vectors.Length; i++) Vectors[i] = this.GetRowVector(i - 1); return new Matrix(Vectors); }
/// <summary> /// 指定された行範囲の部分行列を取得します /// </summary> /// <param name="StartRowIndex">開始行</param> /// <param name="EndRowIndex">終了行</param> /// <returns>指定された行範囲の部分行列</returns> public virtual Matrix GetMatrixRowBetween(int StartRowIndex, int EndRowIndex) { if (StartRowIndex > EndRowIndex || StartRowIndex >= this.RowSize || StartRowIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndRowIndex < 0 || EndRowIndex >= this.RowSize) throw new ApplicationException("指定位置が正しくありません"); RowVector[] Vectors = new RowVector[EndRowIndex - StartRowIndex + 1]; for (int i = StartRowIndex; i <= EndRowIndex; i++) Vectors[i - StartRowIndex] = this.GetRowVector(i); return new Matrix(Vectors); }
public virtual Matrix GetIndexRowVectorMatrix(int[] Index) { RowVector[] ResultVector = new RowVector[Index.Length]; for (int i = 0; i < ResultVector.Length; i++) ResultVector[i] = this.GetRowVector(Index[i]); return new Matrix(ResultVector); }
/// <summary> /// 与えられたベクトルと同一の横ベクトルを作成します。 /// </summary> /// <param name="Vector">コピー元のベクトル</param> public RowVector(RowVector Vector) : base((Vector)Vector) { }
/// <summary> /// 指定した場所にスカラー値を挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Scalar">スカラー値</param> /// <returns>値が挿入されたベクトル</returns> public virtual RowVector InsertAt(int Index, double Scalar) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); RowVector ReturnVector = new RowVector(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="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>部分ベクトル</returns> public virtual RowVector 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("指定位置が正しくありません"); RowVector ReturnVector = new RowVector(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 RowVector[] GetSeparatedVector(int Length) { if (this.Length % Length != 0) throw new ApplicationException("要素が割り切れません"); //TODO 新規追加場所 RowVector[] ResultVector = new RowVector[Length]; for (int i = 0; i < ResultVector.Length; i++) { ResultVector[i] = new RowVector(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 virtual RowVector GetNormlizeVector() { double Norm = this.GetNorm(); if (Norm == 0) { //エラーを投げても良い //throw new ApplicationException("ベクトルの大きさが0です。"); //一応、このバージョンは自分と同じベクトル(要素が全部0)を戻す事にする return new RowVector(this); } RowVector ReturnVector = new RowVector(this); ReturnVector /= Norm; return ReturnVector; }
/// <summary> /// ベクトルの微分を取得するメソッドです。 /// </summary> /// <returns>微分値ベクトル</returns> public virtual RowVector GetDifferential() { //TODO 新規追加場所 RowVector ResultVector = new RowVector(this.Length - 1); for (int i = 0; i < ResultVector.Length; i++) ResultVector[i] = this[i] - this[i + 1]; return ResultVector; }
/// <summary> /// ベクトルの『要素毎』のかけ算です(内積ではありません)内積は『InnerProduct』で求めて下さい。 /// </summary> /// <param name="LeftVector">最初のベクトル</param> /// <param name="RightVector">二個目のベクトル</param> /// <returns>『要素毎』にかけ算されたベクトル</returns> public static RowVector Multiply(RowVector LeftVector, RowVector 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 RowVector(Element); }
/// <summary> /// 指定した個数の行ベクトルが並んだ行列を取得します。 /// 主に平均ベクトルに対して使ったりします。 /// </summary> /// <param name="Vector">行ベクトル</param> /// <param name="Size">個数</param> /// <returns>指定した個数の行ベクトルが並んだ行列</returns> public static Matrix GetSameElementMatrix(RowVector Vector, int Size) { return Matrix.GetSameElementMatrix((Vector)Vector, Size).GetTranspose(); }
/// <summary> /// 行列の横ベクトル要素をすべて連結した横ベクトルを取得します(涼子作成) /// </summary> /// <returns>連結された横ベクトル</returns> public virtual RowVector GetConbineRowVector() { RowVector ResultVector = this.GetRowVector(0); for (int i = 1; i < this.RowSize; i++) ResultVector = new RowVector(ResultVector.InsertAtEnd(this.GetRowVector(i))); return ResultVector; }
/// <summary> /// 指定した場所にベクトルを挿入します /// </summary> /// <param name="Index">0から始まる挿入位置</param> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual RowVector InsertAt(int Index, RowVector Vector) { if (Index < 0 | Index > this.Length) throw new ApplicationException("指定位置が正しくありません"); RowVector ReturnVector = new RowVector(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> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual RowVector InsertAtEnd(RowVector Vector) { return this.InsertAt(this.Length, Vector); }
/// <summary> /// ベクトルの最初にベクトルを追加します /// </summary> /// <param name="Vector">ベクトル</param> /// <returns>ベクトルが挿入されたベクトル</returns> public virtual RowVector InsertAtStart(RowVector Vector) { return this.InsertAt(0, Vector); }
/// <summary> /// 指定した行の位置に行列を挿入します /// </summary> /// <param name="RowIndex">0から始まる行のインデックス</param> /// <param name="Matrix">挿入する行列</param> /// <returns>指定した行位置に行列を挿入された行列</returns> public virtual Matrix InsertMatrixAtRowIndex(int RowIndex, Matrix Matrix) { if (this.ColSize != Matrix.ColSize) throw new ApplicationException("列のサイズが異なっています"); if (RowIndex < 0 | RowIndex > this.RowSize) throw new ApplicationException("インデックスが範囲外です"); RowVector[] Vectors = new RowVector[this.RowSize + Matrix.RowSize]; for (int i = 0; i < RowIndex; i++) Vectors[i] = this.GetRowVector(i); for (int i = RowIndex; i < RowIndex + Matrix.RowSize; i++) Vectors[i] = Matrix.GetRowVector(i - RowIndex); for (int i = RowIndex + Matrix.RowSize; i < Vectors.Length; i++) Vectors[i] = this.GetRowVector(i - Matrix.RowSize); return new Matrix(Vectors); }
/// <summary> /// 指定されたインデックス配列の要素を削除したベクトルを取得します。 /// インデックスは配列でなく1個(ただのint型)でも大丈夫です。 /// </summary> /// <param name="Index">削除する要素のインデックス配列</param> /// <returns>指定されたインデックス配列の要素を削除したベクトル</returns> public virtual RowVector RemoveElementAt(params int[] Index) { //↓このコードでも実行可能。でも速度の面で難ありかも。 /* Vector Vector = new Vector(this); for (int i = IndexArray.Length - 1 ; i >= 0; i--) Vector = Vector.RemoveElementAt(IndexArray[i]); */ //あんまり綺麗じゃないけどこっちの方が速度は速いはず RowVector ReturnVector = new RowVector(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="RowVector">挿入する縦ベクトル</param> /// <returns>指定したベクトルが挿入された行列</returns> public virtual Matrix InsertRowVectorAtEnd(RowVector RowVector) { return this.InsertRowVectorAt(this.RowSize, RowVector); }
/// <summary> /// 指定した範囲の要素を削除したベクトルを取得します /// </summary> /// <param name="StartIndex">開始位置</param> /// <param name="EndIndex">終了位置</param> /// <returns>指定した範囲の要素を削除したベクトル</returns> public virtual RowVector 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("指定位置が正しくありません"); RowVector ReturnVector = new RowVector(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="StartIndex">削除開始行インデックス</param> /// <param name="EndIndex">削除終了行インデックス</param> /// <returns>指定した範囲の行要素を削除した行列</returns> public virtual Matrix RemoveRowElementRange(int StartIndex, int EndIndex) { if (StartIndex > EndIndex || StartIndex >= this.RowSize || StartIndex < 0) throw new ApplicationException("指定位置が正しくありません"); if (EndIndex < 0 || EndIndex >= this.RowSize) throw new ApplicationException("指定位置が正しくありません"); RowVector[] Vectors = new RowVector[this.RowSize - (EndIndex - StartIndex) - 1]; for (int i = 0; i < StartIndex; i++) Vectors[i] = this.GetRowVector(i); for (int i = 1; i < this.RowSize - EndIndex; i++) Vectors[i + StartIndex - 1] = this.GetRowVector(i + EndIndex); return new Matrix(Vectors); }
/// <summary> /// 与えられたベクトルと同一の横ベクトルを作成します。 /// </summary> /// <param name="Vector">コピー元のベクトル</param> public ColumnVector(RowVector Vector) : base((Vector)Vector) { }