private static LAPCFGrammar MergeRuleTable(LAPCFGrammar rules, double[][] tagProb, int[][] subtagMap, bool[][] isMerged, int[] newSubTagCounts) { var newRules = rules.CreateRuleTable (newSubTagCounts); foreach (var x in rules.brules) { if (x == null) { continue; } foreach (var y in x) { if (y == null) { continue; } foreach (var rule in y) { if (rule == null) { continue; } int l = rule.ltag; int r = rule.rtag; int p = rule.ptag; for (int sl = 0; sl < rule.scores.Length; ++sl) { for (int sr = 0; sr < rule.scores[sl].Length; ++sr) { for (int sp = 0; sp < rule.scores[sl][sr].Length; ++sp) { double s = rule.scores [sl] [sr] [sp]; int nsl = subtagMap [l] [sl]; int nsr = subtagMap [r] [sr]; int nsp = subtagMap [p] [sp]; if (isMerged [p] [sp]) { s += tagProb [p] [sp]; } var xs = newRules.brules [l] [r] [p].scores [nsl] [nsr] [nsp]; newRules.brules [l] [r] [p].scores [nsl] [nsr] [nsp] = MathHelper.LogAdd (xs, s); } } } } } } foreach (var x in rules.urules) { if (x == null) { continue; } foreach (var rule in x) { if (rule == null) { continue; } int c = rule.ctag; int p = rule.ptag; for (int sc = 0; sc < rule.scores.Length; ++sc) { for (int sp = 0; sp < rule.scores[sc].Length; ++sp) { double s = rule.scores [sc] [sp]; int nsc = subtagMap [c] [sc]; int nsp = subtagMap [p] [sp]; if (isMerged [p] [sp]) { s += tagProb [p] [sp]; } var xs = newRules.urules [c] [p].scores [nsc] [nsp]; newRules.urules [c] [p].scores [nsc] [nsp] = MathHelper.LogAdd (xs, s); } } } } foreach (var x in rules.trules) { if (x == null) { continue; } foreach (var rule in x) { if (rule == null) { continue; } int w = rule.word; int t = rule.tag; for (int st = 0; st < rule.scores.Length; ++st) { double s = rule.scores [st]; int nsp = subtagMap [t] [st]; if (isMerged [t] [st]) { s += tagProb [t] [st]; } var xs = newRules.trules [w] [t].scores [nsp]; newRules.trules [w] [t].scores [nsp] = MathHelper.LogAdd (xs, s); } } } double[][] expects = newRules.subTagCounts.Select (x => new double[x]).ToArray (); ArrayHelper.Fill (expects, double.NegativeInfinity); LAPCFGrammar.CollectTagMass (expects, newRules.trules); LAPCFGrammar.CollectTagMass (expects, newRules.urules); LAPCFGrammar.CollectTagMass (expects, newRules.brules); LAPCFGrammar.Normalize (expects, newRules.trules); LAPCFGrammar.Normalize (expects, newRules.urules); LAPCFGrammar.Normalize (expects, newRules.brules); foreach (var trace in rules.subtagTraces) { newRules.subtagTraces.Add (trace); } int[][] oldTrace = newRules.subtagTraces [newRules.subtagTraces.Count - 1]; int[][] newTrace = new int[oldTrace.Length][]; for (int i = 0; i < newTrace.Length; ++i) { newTrace [i] = new int[newRules.subTagCounts [i]]; for (int j = 0; j < oldTrace[i].Length; ++j) { newTrace [i] [subtagMap [i] [j]] = oldTrace [i] [j]; } } newRules.subtagTraces [newRules.subtagTraces.Count - 1] = newTrace; return newRules; }