public unsafe double[] GetAverageTimeToEnd(Predicate <State <TAbility> > endingState) #endif { int size = StateSpace.Count; LU.ArraySet arraySet = ArrayPool <LU.ArraySet> .RequestArraySet(); LU M = new LU(size, arraySet); double[] ret = new double[size]; #if SILVERLIGHT M.BeginSafe(); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (State <TAbility> state in StateSpace) { if (endingState(state)) { arraySet.LU_U[state.Index * size + state.Index] = 1.0; } else { foreach (StateTransition <TAbility> transition in state.Transitions) { arraySet.LU_U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; ret[state.Index] -= transition.TransitionProbability * transition.TransitionDuration; } arraySet.LU_U[state.Index * size + state.Index] -= 1.0; } } M.Decompose(); M.FSolve(ret); M.EndUnsafe(); #else fixed(double *U = arraySet.LU_U, x = ret) fixed(double *sL = arraySet.LUsparseL, column = arraySet.LUcolumn, column2 = arraySet.LUcolumn2) fixed(int *P = arraySet.LU_P, Q = arraySet.LU_Q, LJ = arraySet.LU_LJ, sLI = arraySet.LUsparseLI, sLstart = arraySet.LUsparseLstart) { M.BeginUnsafe(U, sL, P, Q, LJ, sLI, sLstart, column, column2); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (State <TAbility> state in StateSpace) { if (endingState(state)) { U[state.Index * size + state.Index] = 1.0; } else { foreach (StateTransition <TAbility> transition in state.Transitions) { U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; x[state.Index] -= transition.TransitionProbability * transition.TransitionDuration; } U[state.Index * size + state.Index] -= 1.0; } } M.Decompose(); M.BSolve(x); M.EndUnsafe(); } #endif ArrayPool <LU.ArraySet> .ReleaseArraySet(arraySet); return(ret); }
public unsafe MarkovProcess(List <State <TAbility> > stateSpace) #endif { StateSpace = stateSpace; for (int i = 0; i < StateSpace.Count; i++) { StateSpace[i].Index = i; } int size = StateSpace.Count + 1; LU.ArraySet arraySet = ArrayPool <LU.ArraySet> .RequestArraySet(); LU M = new LU(size, arraySet); StateWeight = new double[size]; #if SILVERLIGHT M.BeginSafe(); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (State <TAbility> state in StateSpace) { foreach (StateTransition <TAbility> transition in state.Transitions) { arraySet.LU_U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; } arraySet.LU_U[state.Index * size + state.Index] -= 1.0; } for (int i = 0; i < size - 1; i++) { arraySet.LU_U[(size - 1) * size + i] = 1; } StateWeight[size - 1] = 1; M.Decompose(); M.FSolve(StateWeight); M.EndUnsafe(); #else fixed(double *U = arraySet.LU_U, x = StateWeight) fixed(double *sL = arraySet.LUsparseL, column = arraySet.LUcolumn, column2 = arraySet.LUcolumn2) fixed(int *P = arraySet.LU_P, Q = arraySet.LU_Q, LJ = arraySet.LU_LJ, sLI = arraySet.LUsparseLI, sLstart = arraySet.LUsparseLstart) { M.BeginUnsafe(U, sL, P, Q, LJ, sLI, sLstart, column, column2); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (State <TAbility> state in StateSpace) { foreach (StateTransition <TAbility> transition in state.Transitions) { U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; } U[state.Index * size + state.Index] -= 1.0; } for (int i = 0; i < size - 1; i++) { U[(size - 1) * size + i] = 1; } x[size - 1] = 1; M.Decompose(); M.FSolve(x); M.EndUnsafe(); } #endif AbilityWeight = new Dictionary <TAbility, double>(); foreach (State <TAbility> state in StateSpace) { double stateWeight = StateWeight[state.Index]; if (stateWeight > 0) { foreach (StateTransition <TAbility> transition in state.Transitions) { double transitionProbability = transition.TransitionProbability; if (transitionProbability > 0) { double p = stateWeight * transitionProbability; if (transition.Ability != null) { double weight; AbilityWeight.TryGetValue(transition.Ability, out weight); AbilityWeight[transition.Ability] = weight + p; } AverageTransitionDuration += p * transition.TransitionDuration; } } } } ArrayPool <LU.ArraySet> .ReleaseArraySet(arraySet); }
public unsafe GenericCycle(string name, CastingState castingState, List<CycleState> stateDescription, bool needsDisplayCalculations) #endif : base(needsDisplayCalculations, castingState) { Name = name; StateList = stateDescription; for (int i = 0; i < StateList.Count; i++) { StateList[i].Index = i; } int size = StateList.Count + 1; ArraySet arraySet = ArrayPool.RequestArraySet(false); try { LU M = new LU(size, arraySet); StateWeight = new double[size]; #if SILVERLIGHT M.BeginSafe(); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (CycleState state in StateList) { foreach (CycleStateTransition transition in state.Transitions) { arraySet.LU_U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; } arraySet.LU_U[state.Index * size + state.Index] -= 1.0; } for (int i = 0; i < size - 1; i++) { arraySet.LU_U[(size - 1) * size + i] = 1; } StateWeight[size - 1] = 1; M.Decompose(); M.FSolve(StateWeight); M.EndUnsafe(); #else fixed (double* U = arraySet.LU_U, x = StateWeight) fixed (double* sL = arraySet.LUsparseL, column = arraySet.LUcolumn, column2 = arraySet.LUcolumn2) fixed (int* P = arraySet.LU_P, Q = arraySet.LU_Q, LJ = arraySet.LU_LJ, sLI = arraySet.LUsparseLI, sLstart = arraySet.LUsparseLstart) { M.BeginUnsafe(U, sL, P, Q, LJ, sLI, sLstart, column, column2); Array.Clear(arraySet.LU_U, 0, size * size); //U[i * rows + j] foreach (CycleState state in StateList) { foreach (CycleStateTransition transition in state.Transitions) { U[transition.TargetState.Index * size + state.Index] += transition.TransitionProbability; } U[state.Index * size + state.Index] -= 1.0; } for (int i = 0; i < size - 1; i++) { U[(size - 1) * size + i] = 1; } x[size - 1] = 1; M.Decompose(); M.FSolve(x); M.EndUnsafe(); } #endif SpellWeight = new Dictionary<Spell, double>(); CycleWeight = new Dictionary<Cycle, double>(); DWSpellWeight = new Dictionary<Spell, double>(); foreach (CycleState state in StateList) { double stateWeight = StateWeight[state.Index]; if (stateWeight > 0) { foreach (CycleStateTransition transition in state.Transitions) { float transitionProbability = transition.TransitionProbability; if (transitionProbability > 0) { if (transition.Spell != null) { double weight; SpellWeight.TryGetValue(transition.Spell, out weight); SpellWeight[transition.Spell] = weight + stateWeight * transitionProbability; } if (transition.DWSpell != null) { double weight; DWSpellWeight.TryGetValue(transition.DWSpell, out weight); DWSpellWeight[transition.DWSpell] = weight + stateWeight * transitionProbability; } if (transition.Cycle != null) { double weight; CycleWeight.TryGetValue(transition.Cycle, out weight); CycleWeight[transition.Cycle] = weight + stateWeight * transitionProbability; } if (transition.Pause > 0) { AddPause(transition.Pause, (float)(stateWeight * transitionProbability)); } } } } } StringBuilder sb = new StringBuilder(); foreach (KeyValuePair<Spell, double> kvp in SpellWeight) { AddSpell(needsDisplayCalculations, kvp.Key, (float)kvp.Value); if (kvp.Value > 0) sb.AppendFormat("{0}:\t{1:F}%\r\n", kvp.Key.Label ?? kvp.Key.SpellId.ToString(), 100.0 * kvp.Value); } foreach (KeyValuePair<Spell, double> kvp in DWSpellWeight) { AddSpell(needsDisplayCalculations, kvp.Key, (float)kvp.Value); } foreach (KeyValuePair<Cycle, double> kvp in CycleWeight) { AddCycle(needsDisplayCalculations, kvp.Key, (float)kvp.Value); if (kvp.Value > 0) sb.AppendFormat("{0}:\t{1:F}%\r\n", kvp.Key.CycleId, 100.0 * kvp.Value); } Calculate(); SpellDistribution = sb.ToString(); } finally { ArrayPool.ReleaseArraySet(arraySet); } }