using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GenericOperator { /// /// Operator を使った例ということで、ジェネリックな複素数型を実装。 /// /// 実部・虚部の型 public struct Complex where T: IComparable { #region フィールド private T re; private T im; #endregion #region 初期化 /// /// 実部・虚部を与えて初期化。 /// /// 実部の値。 /// 虚部の値。 public Complex(T re, T im) { this.re = re; this.im = im; } #endregion #region プロパティ /// /// 実部。 /// public T Re { get { return re; } set { re = value; } } /// /// 虚部。 /// public T Im { get { return im; } set { im = value; } } #endregion #region タイピング量を減らすための簡単なラッパー static T Add(T x, T y) { return Operator.Add(x, y); } static T Sub(T x, T y) { return Operator.Subtract(x, y); } static T Mul(T x, T y) { return Operator.Multiply(x, y); } static T Div(T x, T y) { return Operator.Divide(x, y); } static T Neg(T x) { return Operator.Negate(x); } static T Acc(T x, T y, T z, T w) { return Operator.ProductSum(x, y, z, w); } static T Det(T x, T y, T z, T w) { return Operator.ProductDifference(x, y, z, w); } static T Norm(T x, T y) { return Operator.ProductSum(x, y, x, y); } #endregion #region 加減乗除 public static Complex operator +(Complex x, Complex y) { return new Complex(Add(x.re, y.re), Add(x.im, y.im)); } public static Complex operator +(T x, Complex y) { return new Complex(Add(x, y.re), y.im); } public static Complex operator +(Complex x, T y) { return new Complex(Add(x.re, y), x.im); } public static Complex operator -(Complex x) { return new Complex(Neg(x.re), Neg(x.im)); } public static Complex operator -(Complex x, Complex y) { return new Complex(Sub(x.re, y.re), Sub(x.im, y.im)); } public static Complex operator -(T x, Complex y) { return new Complex(Sub(x, y.re), y.im); } public static Complex operator -(Complex x, T y) { return new Complex(Sub(x.re, y), x.im); } public static Complex operator *(Complex x, Complex y) { return new Complex( Det(x.re, y.re, x.im, y.im), Acc(x.re, y.im, x.im, y.re)); } public static Complex operator *(T x, Complex y) { return new Complex(Mul(x, y.re), Mul(x, y.im)); } public static Complex operator *(Complex x, T y) { return new Complex(Mul(x.re, y), Mul(x.im, y)); } /// /// 逆数を求める。 /// /// 逆数。 public Complex Inverse() { T norm = Norm(this.re, this.im); T re = Div(this.re, norm); T im = Neg(Div(this.im, norm)); return new Complex(re, im); } public static Complex operator /(Complex x, Complex y) { return x * y.Inverse(); } public static Complex operator /(T x, Complex y) { return x * y.Inverse(); } public static Complex operator /(Complex x, T y) { return new Complex(Div(x.re, y), Div(x.im, y)); } #endregion #region 文字列化 public override string ToString() { if (this.im.CompareTo(default(T)) < 0) { return string.Format("{0} - i{1}", this.re, Neg(this.im)); } else { return string.Format("{0} + i{1}", this.re, this.im); } } #endregion } /// /// Complex に付随する拡張メソッド。 /// public static class ComplexExtensions { /// /// 5.I() みたいな書き方で純虚数を作れるようするための拡張メソッド。 /// /// 虚部の型。 /// 虚部の値。 /// 純虚数 ix public static Complex I(this T x) where T : IComparable { return new Complex(default(T), x); } /// /// 3 .I(4) みたいな書き方で複素数 3 + i4 を作れるようにするための拡張メソッド。 /// /// 実部・虚部の型。 /// 実部。 /// 虚部。 /// 複素数 x + iy public static Complex I(this T x, T y) where T : IComparable { return new Complex(x, y); } } }