C#で要素が分数の行列
これまでに書いたコード。
Class1.cs
using System; using MyMath; namespace ConsoleApplication2 { /// <summary> /// Class1 の概要の説明です。 /// </summary> class Class1 { /// <summary> /// アプリケーションのメイン エントリ ポイントです。 /// </summary> [STAThread] static void Main(string[] args) { Fraction a = new Fraction( 1, -2 ); Fraction zero = new Fraction( 0, 1 ); Fraction[,] Array = new Fraction[2,2]; for( int i = 0; i < 2; ++i ) for( int j = 0; j < 2; ++j ) if( i == j ) Array[i, j] = a; else Array[i, j] = zero; Matrix m = new Matrix( Array ); m.Disp(); m = m.Inverse(); m.Disp(); } // End of Main() } }
Function.cs
using System; using System.Collections; namespace MyMath { /// <summary> /// 関数 /// </summary> public class Function { public static ArrayList Factorization( int n ) { ArrayList factor_elements = new ArrayList(); int a = 2; while( n >= a*a ) { if( 0 == n % a ) { factor_elements.Add( a ); n /= a; } else ++a; } factor_elements.Add( n ); return factor_elements; } } }
Fraction.cs
using System; using System.Collections; namespace MyMath { /// <summary> /// 分数クラスです。 /// </summary> public class Fraction { private int m_numerator; private int m_denominator; private int m_sign; // +:1, -:0 // コンストラクタ public Fraction( int num, int dem ) { this.m_numerator = num; this.m_denominator = dem; Sign(); } public Fraction() : this( 0, 1 ) { Sign(); } ~Fraction() { } public int GetNumerator() { return this.m_numerator; } public int GetDenominator() { return this.m_denominator; } public void SetNumerator( int num ) { this.m_numerator = num; } public void SetDenominator( int den ) { this.m_denominator = den; } public override string ToString() { //return ( this.m_numerator + "/" + this.m_denominator ); return ( string.Format( "{0}/{1}", this.m_numerator, this.m_denominator ) ); } public void Disp() { Console.WriteLine( "{0}/{1}", m_numerator, m_denominator ); } // 符号について public void Sign() { // 符号を分子に if( this.m_denominator < 0 ) { this.m_numerator *= -1; this.m_denominator *= -1; } // +:1, -:0 this.m_sign = ( ( this.m_numerator < 0 ) ? 0 : 1 ); } // 約分 public Fraction Reduction() { Sign(); if( 0 == m_sign ) m_numerator *= -1; // 分子が0なら計算しない if( 0 == m_numerator ) { m_denominator = 1; return new Fraction( m_numerator, m_denominator ); } ArrayList n_factor = Function.Factorization( m_numerator ); ArrayList d_factor = Function.Factorization( m_denominator ); int j = 0, save_index = 0; for( int i = 0; i < n_factor.Count; ++i ) { j = save_index; while( j < d_factor.Count ) { if( (int)n_factor[i] == (int)d_factor[j] ) { n_factor[i] = d_factor[j] = 1; save_index = j+1; break; } ++j; } } int num = 1; int den = 1; for( int i = 0; i < n_factor.Count; ++i ) num *= (int)n_factor[i]; for( int i = 0; i < d_factor.Count; ++i ) den *= (int)d_factor[i]; if( 0 == m_sign ) num *= -1; return new Fraction( num, den ); } // 演算子 public static Fraction operator+( Fraction a, Fraction b ) { Fraction t = new Fraction( a.GetNumerator()*b.GetDenominator() + a.GetDenominator()*b.GetNumerator(), a.GetDenominator()*b.GetDenominator() ); t = t.Reduction(); return t; } public static Fraction operator-( Fraction a, Fraction b ) { Fraction t =new Fraction( a.GetNumerator()*b.GetDenominator() - b.GetNumerator()*a.GetDenominator(), a.GetDenominator()*b.GetDenominator() ); t = t.Reduction(); return t; } public static Fraction operator*( Fraction a, Fraction b ) { Fraction t = new Fraction( a.GetNumerator()*b.GetNumerator(), a.GetDenominator()*b.GetDenominator() ); t = t.Reduction(); return t; } public static Fraction operator/( Fraction a, Fraction b ) { Fraction t = new Fraction( a.GetNumerator()*b.GetDenominator(), a.GetDenominator()*b.GetNumerator() ); t = t.Reduction(); return t; } } }
Matrix.cs
for( int j = 0; j < this.GetColumn(); ++j ) { Console.Write( "{0,6}", this[i, j] ); } Console.WriteLine(); } } // 演算子 public static Matrix operator+( Matrix a, Matrix b ) { int row = a.GetRow(); int column = a.GetColumn(); if( a.GetRow() < b.GetRow() ) row = b.GetRow(); if( a.GetColumn() < b.GetColumn() ) column = b.GetColumn(); Fraction[,] array = new Fraction[row,column]; for( int i = 0; i < row; ++i ) for( int j = 0; j < column; ++j ) array[i, j] = a[i, j] + b[i, j]; return new Matrix( array ); } public static Matrix operator-( Matrix a, Matrix b ) { int row = a.GetRow(); int column = a.GetColumn(); if( a.GetRow() < b.GetRow() ) row = b.GetRow(); if( a.GetColumn() < b.GetColumn() ) column = b.GetColumn(); Fraction[,] array = new Fraction[row,column]; for( int i = 0; i < row; ++i ) for( int j = 0; j < column; ++j ) array[i, j] = a[i, j] - b[i, j]; return new Matrix( array ); } public static Matrix operator *( Matrix a, Matrix b ) { int row = a.GetRow(); int column = a.GetColumn(); if( a.GetRow() < b.GetRow() ) row = b.GetRow(); if( a.GetColumn() < b.GetColumn() ) column = b.GetColumn(); Fraction[,] array = new Fraction[row,column]; for( int i = 0; i < row; ++i ) for( int j = 0; j < column; ++j ) { Fraction zero = new Fraction( 0, 1 ); array[i, j] = zero; for( int k = 0; k < column; ++k ) array[i, j] += a[i, k] * b[k, j]; } return new Matrix( array ); } public static bool operator ==( Matrix a, Matrix b ) { for( int i = 0; i < a.GetRow(); ++i ) for( int j = 0; j < a.GetColumn(); ++j ) if( a[i, j] != b[i, j] ) return false; return true; } public static bool operator !=( Matrix a, Matrix b ) { if( a == b ) return false; return true; } public override bool Equals( object obj ) { if( !(obj is Matrix) ) return false; else return this == (Matrix)obj; } public override int GetHashCode() { return base.GetHashCode (); } public Matrix Inverse() { Fraction one = new Fraction( 1, 1 ); Fraction zero = new Fraction( 0, 1 ); // 拡大行列 int row = this.GetRow(); int column = this.GetColumn(); Fraction[,] array = new Fraction[row, 2*column]; for( int i = 0; i < row; ++i ) { for( int j = 0; j < column; ++j ) { array[i, j] = this.m_elements[i, j]; } for( int j = column; j < 2*column; ++j ) { if( (i+column) != j ) array[i, j] = zero; else array[i, j] = one; } } Fraction pivot, d; for( int k = 0; k < row; ++k ) { pivot = array[k,k]; for( int j = k; j < 2*column; ++j ) array[k,j] = array[k,j]/pivot; for( int i = 0; i < row; ++i ) { if( i != k ) { d = array[i,k]; for( int j = k; j < 2*column; ++j ) array[i,j] = array[i,j] - d * array[k,j]; } } } Fraction[,] ret = new Fraction[row, column]; for( int i = 0; i < row; ++i ) { for( int j = 0; j < column; ++j ) { ret[i,j] = array[i,column+j]; } } return new Matrix( ret ); } } }