sum_i := sum_(i-1) + <u_i, v> + <u_i, t>
u_i := u_(i-1) * sum_i

References:
sum_i := sum_(i-1) + <u_i, v> + <u_i, t>
u_i := u_(i-1) * sum_i
1: // a vector in R^n
2: class Vector<T>
3: {
4: T[] components;
5:
6: // ctors, properties etc. ...
7:
8: // operator defintion, here: vector addition
9: public staticVector<T> operator +(Vector<T> lhs,
10: Vector<T> rhs)
11: {
12: Vector<T> res = new Vector<T>(lhs.Length);
13:
14: for (int i = 0; i < res.Length; ++i)
15: {
16: // compiler error!
17: res[i] = lhs[i] + rhs[i];
18: }
19:
20: return res;
21: }
22: }
1: interface INumeric<T>
2: {
3: T Add(T rhs);
4: T Sub(T rhs);
5: T Mul(T rhs);
6: T Div(T rhs);
7: // etc.
1: // a vector in R^n
2: class Vector<T> where T: INumeric<T>
3: {
4: T[] components;
5:
6: // ctors, properties ...
7:
8: public static Vector<T> operator +(Vector<T> lhs, Vector<T> rhs)
9: {
10: Vector<T> res = new Vector<T>(lhs.Length);
11:
12: for (int i = 0; i < res.Length; ++i)
13: {
14: res[i] = lhs[i].Add(rhs[i]); // OK, T implements INumeric<T>
15: }
16:
17: return res;
18: }
19: }
1: T sum = Operator<T>.Add(lhs, rhs);
1: Vector<float> v = VectorModule.Generic.create<float>(3, 3, 0f);
1: namespace GenericMath
2: {
3: public interface INumeric<T>
4: {
5: T Add(T lhs, T rhs);
6: T Sub(T lhs, T rhs);
7: T Mul(T lhs, T rhs);
8: T Div(T lhs, T rhs);
9: T Abs(T x);
10: T Zero { get; }
11: T One { get; }
12: }
13:
14: class FloatNumerics: INumeric<float>
15: {
16: public float Add(float lhs, float rhs)
17: {
18: return lhs + rhs;
19: }
20:
21: public float Sub(float lhs, float rhs)
22: {
23: return lhs - rhs;
24: }
25:
26: public float Mul(float lhs, float rhs)
27: {
28: return lhs * rhs;
29: }
30:
31: public float Div(float lhs, float rhs)
32: {
33: return lhs / rhs;
34: }
35:
36: public float Abs(float x)
37: {
38: return Math.Abs(x);
39: }
40:
41: public float Zero
42: {
43: get { return 0f; }
44: }
45:
46: public float One
47: {
48: get { return 1f; }
49: }
50: }
51:
52: // implementations for other types ...
53:
54: public static class ArithmeticAssociations
55: {
56: static readonly IDictionary<Type, object> operationsDict = new Dictionary<Type, object>
57: {
58: { typeof(float), new FloatNumerics() },
59: { typeof(double), new DoubleNumerics() },
60: { typeof(int), new Int32Numerics() }
61: };
62:
63: static string numericIfaceName = typeof(INumeric<>).FullName;
64: static string numericIfaceNameShort = typeof(INumeric<>).Name;
65:
66: public static bool UnregisterType<T>()
67: {
68: return operationsDict.Remove(typeof(T));
69: }
70:
71: public static void RegisterType<T>(INumeric<T> arithmetics)
72: {
73: operationsDict[typeof(T)] = arithmetics;
74: }
75:
76: public static INumeric<T> TryGetNumericOps<T>()
77: {
78: Type t = typeof(T);
79:
80: if (!operationsDict.ContainsKey(t))
81: {
82: throw new ArgumentException("No implementation of "
83: + numericIfaceNameShort + "<" + t.Name + "> registered.");
84: }
85:
86: Type opsType = operationsDict[t].GetType();
87:
88: if (opsType.GetInterface(numericIfaceName) == null)
89: {
90: throw new ArgumentException("Arithmetic object associated with "
91: + t.Name + " does not implement " + numericIfaceNameShort);
92: }
93:
94: return (INumeric<T>)operationsDict[t];
95: }
96: }
97:
98: // a sample class that uses INumeric + ArithmeticAssociations
99: public sealed class Vector<T>
100: {
101: static INumeric<T> ops = ArithmeticAssociations.TryGetNumericOps<T>();
102:
103: T[] components;
104:
105: public T this[int i]
106: {
107: get { return components[i]; }
108: set { components[i] = value; }
109: }
110:
111: public int Length { get { return components.Length; } }
112:
113: public Vector(int size)
114: {
115: components = new T[size];
116: }
117:
118: public static T operator *(Vector<T> lhs, Vector<T> rhs)
119: {
120: T res = ops.Zero;
121:
122: for (int i = 0; i < lhs.Length; ++i)
123: {
124: res = ops.Add(res, ops.Mul(lhs[i], rhs[i]));
125: }
126:
127: return res;
128: }
129:
130: public static Vector<T> operator *(T lambda, Vector<T> vec)
131: {
132: Vector<T> result = new Vector<T>(vec.Length);
133:
134: for (int i = 0; i < result.Length; ++i)
135: {
136: result[i] = ops.Mul(vec[i], lambda);
137: }
138:
139: return result;
140: }
141:
142: // other properties, methods and operators ...
143: }
144:
145: // ...
146: }
1: Vector<float> v = new Vector<float>(3);