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);
}
}
}