/// <remarks> /// 同じ種類の関数ごとに足していった方が最適な構造が得られるため、 /// 関数のリストを一度ソートしてから足しなおす。 /// あと、定数 0 が混ざってたら消す。 /// </remarks> public override Function Optimize() { Hashtable table = new Hashtable(); // 種類わけ foreach (Function f in this.functions) { Function g = f.Optimize(); Type t = g.GetType(); if (table[t] == null) { table[t] = g; } else { table[t] = (Function)table[t] + g; } } // 繋ぎなおす ArrayList func = new ArrayList(); foreach (Function f in table.Values) { if (f is Sum) { Sum s = f as Sum; func.AddRange(s.functions); } else { if (!f.Equals((Constant)0)) { func.Add(f); } } } // 特殊な場合 if (func.Count == 0) { return((Constant)0); } if (func.Count == 1) { return(func[0] as Function); } // 足しなおす。 Function h = func[0] as Function; for (int i = 1; i < func.Count; ++i) { h += func[i] as Function; } return(h); }
/// <remarks> /// 同じ種類の関数ごとに掛けていった方が最適な構造が得られるため、 /// 関数のリストを一度ソートしてから掛けなおす。 /// あと、Constant とか Variable とか Function の辺りの乗算を最適化。 /// </remarks> public override Function Optimize() { Hashtable table = new Hashtable(); // 種類わけ foreach (Function f in this.functions) { Function g = f.Optimize(); Type t = g.GetType(); if (table[t] == null) { table[t] = g; } else { table[t] = (Function)table[t] * g; } } // 繋ぎなおす Constant c = table[typeof(Constant)] as Constant; if (c != null && c.Equals((Constant)0)) { return((Constant)0); } Function v = table[typeof(Variable)] as Function; Multiple m = table[typeof(Multiple)] as Multiple; Function h = (Constant)1; if (v != null) { h = Sort(v); table.Remove(typeof(Variable)); } if (c != null) { table.Remove(typeof(Constant)); } if (m != null) { if (c == null) { c = (Constant)m.Factor; } else { c = (Constant)(c.Value * m.Factor); } h *= m.Inner; table.Remove(typeof(Multiple)); } ArrayList func = new ArrayList(); if (!h.Equals((Constant)1)) { func.Add(h); } foreach (Function f in table.Values) { if (f is Product) { Product p = f as Product; func.AddRange(p.functions); } else { if (!f.Equals((Constant)1)) { func.Add(f); } } } // 特殊な場合 if (c == null) { if (func.Count == 0) { return((Constant)1); } if (func.Count == 1) { return(func[0] as Function); } } // 掛けなおす。 h = func[0] as Function; for (int i = 1; i < func.Count; ++i) { h *= func[i] as Function; } if (c == null || c.Equals((Constant)1)) { return(h); } return(new Multiple(c.Value, h)); }