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); }
/// <summary> /// Computes the LU decomposition for a matrix. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <returns>The LU decomposition object.</returns> public static LU LU(this Matrix <double> matrix) { return((LU)LU <double> .Create(matrix)); }
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); }
// ---------------------------------------------- TIESINĖ ALGEBRA ---------------------------------------------- /// <summary> /// Tiesine algebra (naudojama MathNet) /// </summary> private void button2_Click(object sender, EventArgs e) { ClearForm(); double[,] x = { { 1, 2, 3 }, { 3, 4, 5 }, { 6, 5, 8 } }; // iš masyvo sugeneruoja matricą, is matricos išskiria eilutę - suformuoja vektorių Matrix <double> m = Matrix <double> .Build.DenseOfArray(x); Vector <double> v = m.Row(1); richTextBox1.AppendText("\nMatrica m:\n"); richTextBox1.AppendText(m.ToString()); richTextBox1.AppendText("\nVektorius v:\n"); richTextBox1.AppendText(v.ToString()); richTextBox1.AppendText("\ntranspose(m):\n"); richTextBox1.AppendText(m.Transpose().ToString()); Matrix <double> vm = v.ToRowMatrix(); richTextBox1.AppendText("\nvm = v' - toRowMatrix()\n"); richTextBox1.AppendText(vm.ToString()); Vector <double> v1 = m * v; richTextBox1.AppendText("\nv1 = m * v\n"); richTextBox1.AppendText(v1.ToString()); richTextBox1.AppendText("\nmin(v1)\n"); richTextBox1.AppendText(v1.Min().ToString()); Matrix <double> m1 = m.Inverse(); richTextBox1.AppendText("\ninverse(m)\n"); richTextBox1.AppendText(m1.ToString()); richTextBox1.AppendText("\ndet(m)\n"); richTextBox1.AppendText(m.Determinant().ToString()); // you must add reference to assembly system.Numerics Evd <double> eigenv = m.Evd(); richTextBox1.AppendText("\neigenvalues(m)\n"); richTextBox1.AppendText(eigenv.EigenValues.ToString()); LU <double> LUanswer = m.LU(); richTextBox1.AppendText("\nMatricos M LU skaida\n"); richTextBox1.AppendText("\nMatrica L:\n"); richTextBox1.AppendText(LUanswer.L.ToString()); richTextBox1.AppendText("\nMatrica U:\n"); richTextBox1.AppendText(LUanswer.U.ToString()); QR <double> QRanswer = m.QR(); richTextBox1.AppendText("\nMatricos M QR skaida\n"); richTextBox1.AppendText("\nMatrica Q:\n"); richTextBox1.AppendText(QRanswer.Q.ToString()); richTextBox1.AppendText("\nMatrica R:\n"); richTextBox1.AppendText(QRanswer.R.ToString()); Vector <double> v3 = m.Solve(v); richTextBox1.AppendText("\nm*v3 = v sprendziama QR metodu\n"); richTextBox1.AppendText(v3.ToString()); richTextBox1.AppendText("Patikrinimas\n"); richTextBox1.AppendText((m * v3 - v).ToString()); }
/// <summary> /// Computes the LU decomposition for a matrix. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <returns>The LU decomposition object.</returns> public static LU LU(this Matrix <Complex> matrix) { return((LU)LU <Complex> .Create(matrix)); }
/// <summary> /// Computes the LU decomposition for a matrix. /// </summary> /// <param name="matrix">The matrix to factor.</param> /// <returns>The LU decomposition object.</returns> public static LU LU(this Matrix <float> matrix) { return((LU)LU <float> .Create(matrix)); }
internal void ParsePipelineString() { if (PipelineString == null) { return; } const char lhsDelimiter = '['; const char rhsDelimiter = ']'; const char engineDelimiter = '-'; Debug.Assert(PipelineString[0] == lhsDelimiter && PipelineString[PipelineString.Length - 1] == rhsDelimiter); string[] engines = PipelineString.Substring(1, PipelineString.Length - 2).Split(engineDelimiter); foreach (string engineStr in engines) { int lhsDelimiterIdx = engineStr.IndexOf(lhsDelimiter); string engine; if (lhsDelimiterIdx != -1) { engine = engineStr.Substring(0, lhsDelimiterIdx); } else { engine = engineStr; } if (engine.ToUpper().Equals(VanillaHoudini.Name)) { // The user wants to override Houdini settings used in the cruncher string parameterStr = engineStr.Substring(VanillaHoudini.Name.Length); Dictionary <string, string> parameters = GetParameters(VanillaHoudini.Name, VanillaHoudini.GetAllowedParameters(), VanillaHoudini.GetRequiredParameters(), parameterStr); CheckForMutuallyExclusiveParameters(VanillaHoudini.Name, VanillaHoudini.GetMutuallyExclusiveParameters(), parameters); int errorLimit = ParseIntParameter(parameters, SMTEngine.GetErrorLimitParameter().Name, SMTEngine.GetErrorLimitParameter().DefaultValue); VanillaHoudini houdiniEngine = new VanillaHoudini(Pipeline.GetNextSMTEngineID(), GetSolverValue(parameters), errorLimit); Pipeline.AddEngine(houdiniEngine); houdiniEngine.Delay = ParseIntParameter(parameters, VanillaHoudini.GetDelayParameter().Name, VanillaHoudini.GetDelayParameter().DefaultValue); houdiniEngine.SlidingSeconds = ParseIntParameter(parameters, VanillaHoudini.GetSlidingSecondsParameter().Name, VanillaHoudini.GetSlidingSecondsParameter().DefaultValue); houdiniEngine.SlidingLimit = ParseIntParameter(parameters, VanillaHoudini.GetSlidingLimitParameter().Name, VanillaHoudini.GetSlidingLimitParameter().DefaultValue); } else if (engine.ToUpper().Equals(SBASE.Name)) { string parameterStr = engineStr.Substring(SBASE.Name.Length); Dictionary <string, string> parameters = GetParameters(SBASE.Name, SBASE.GetAllowedParameters(), SBASE.GetRequiredParameters(), parameterStr); int errorLimit = ParseIntParameter(parameters, SMTEngine.GetErrorLimitParameter().Name, SMTEngine.GetErrorLimitParameter().DefaultValue); Pipeline.AddEngine(new SBASE(Pipeline.GetNextSMTEngineID(), GetSolverValue(parameters), errorLimit)); } else if (engine.ToUpper().Equals(SSTEP.Name)) { string parameterStr = engineStr.Substring(SSTEP.Name.Length); Dictionary <string, string> parameters = GetParameters(SSTEP.Name, SSTEP.GetAllowedParameters(), SSTEP.GetRequiredParameters(), parameterStr); int errorLimit = ParseIntParameter(parameters, SMTEngine.GetErrorLimitParameter().Name, SMTEngine.GetErrorLimitParameter().DefaultValue); Pipeline.AddEngine(new SSTEP(Pipeline.GetNextSMTEngineID(), GetSolverValue(parameters), errorLimit)); } else if (engine.ToUpper().Equals(LU.Name)) { string parameterStr = engineStr.Substring(LU.Name.Length); Dictionary <string, string> parameters = GetParameters(LU.Name, LU.GetAllowedParameters(), LU.GetRequiredParameters(), parameterStr); int errorLimit = ParseIntParameter(parameters, SMTEngine.GetErrorLimitParameter().Name, SMTEngine.GetErrorLimitParameter().DefaultValue); Pipeline.AddEngine(new LU(Pipeline.GetNextSMTEngineID(), GetSolverValue(parameters), errorLimit, ParseIntParameter(parameters, LU.GetUnrollParameter().Name, 1))); } else if (engine.ToUpper().Equals(DynamicAnalysis.Name)) { string parameterStr = engineStr.Substring(DynamicAnalysis.Name.Length); Dictionary <string, string> parameters = GetParameters(DynamicAnalysis.Name, DynamicAnalysis.GetAllowedParameters(), DynamicAnalysis.GetRequiredParameters(), parameterStr); DynamicAnalysis dynamicEngine = new DynamicAnalysis(); dynamicEngine.LoopHeaderLimit = ParseIntParameter(parameters, DynamicAnalysis.GetLoopHeaderLimitParameter().Name, DynamicAnalysis.GetLoopHeaderLimitParameter().DefaultValue); dynamicEngine.LoopEscape = ParseIntParameter(parameters, DynamicAnalysis.GetLoopEscapingParameter().Name, DynamicAnalysis.GetLoopEscapingParameter().DefaultValue); dynamicEngine.TimeLimit = ParseIntParameter(parameters, DynamicAnalysis.GetTimeLimitParameter().Name, DynamicAnalysis.GetTimeLimitParameter().DefaultValue); Pipeline.AddEngine(dynamicEngine); } else { Console.WriteLine(string.Format("Unknown cruncher engine: '{0}'", engine)); System.Environment.Exit((int)ToolExitCodes.OTHER_ERROR); } } }
public Matrix(double[,] array) : base(array) { decomposition = new LU(this); }
public void DeformationPreprocess(Vector3 target_position, int target_idx) { //free_indices.Remove(target_idx); //fixed_indices.Add(target_idx); Matrix <double> meshMatrix = Matrix <double> .Build.Dense( mesh_vertices.Count, 3); Matrix <double> fixedMatrix = Matrix <double> .Build.Dense( fixed_indices.Count, 3); Matrix <double> deformedMatrix = Matrix <double> .Build.Dense(mesh_vertices.Count, 3); for (int i = 0; i < mesh_vertices.Count; i++) { meshMatrix.SetRow(i, mesh_vertices[i]); deformedMatrix.SetRow(i, mesh_vertices[i]); if (i < fixed_indices.Count) { fixedMatrix.SetRow(i, mesh_vertices[fixed_indices[i]]); } } fixedMatrix.SetRow(fixed_indices.Count - 1, Utilities.ConvertFromUVectorToMNVector(target_position)); Matrix <double> A = Matrix <double> .Build.Sparse(mesh_vertices.Count, free_indices.Count); Matrix <double> B = Matrix <double> .Build.Sparse(mesh_vertices.Count, fixed_indices.Count); for (int i = 0; i < mesh_vertices.Count; i++) { for (int j = 0; j < free_indices.Count; j++) { A[i, j] = weights[i, free_indices[j]]; } for (int j = 0; j < fixed_indices.Count; j++) { B[i, j] = weights[i, fixed_indices[j]]; } } Matrix <double> left = A.Transpose() * A; LU <double> naive_lap_solver = left.LU(); for (int c = 0; c < 3; c++) { Vector <double> b = weights * meshMatrix.Column(c) - B * fixedMatrix.Column(c); Vector <double> right = A.Transpose() * b; Vector <double> x = naive_lap_solver.Solve(right); for (int i = 0; i < free_indices.Count; ++i) { deformedMatrix[free_indices[i], c] = x[i]; } } //// simple initial guess //List<Vector<double>> def_vertices = mesh_vertices; //Vector<double> targetDistance = Utilities.ConvertFromUVectorToMNVector(target_position) - def_vertices[target_idx]; //Vector<double> startPosition = def_vertices[target_idx]; //double maxDistance = 0.0f; //for (int i = 0; i < def_vertices.Count; i++) //{ // double dist = (def_vertices[i] - def_vertices[target_idx]).L2Norm() * // (def_vertices[i] - def_vertices[target_idx]).L2Norm(); // if (dist > maxDistance) // { // maxDistance = (def_vertices[i] - def_vertices[target_idx]).L2Norm(); // } //} //for (int i = 0; i < def_vertices.Count; i++) //{ // double dist = (def_vertices[i] - startPosition).L2Norm() * // (def_vertices[i] - startPosition).L2Norm(); // double originalDistance = dist / maxDistance; // def_vertices[i] += targetDistance * (1 - originalDistance); // for (int c = 0; c < 3; c++) // { // deformedMatrix[i, c] = def_vertices[i][c]; // } //} // initial rotation deformed_vertices = new List <Vector <double> >(); for (int i = 0; i < mesh_vertices.Count; i++) { deformed_vertices.Add(deformedMatrix.Row(i)); } for (int i = 0; i < fixed_indices.Count; i++) { deformed_vertices[fixed_indices[i]] = fixedMatrix.Row(i); } List <Matrix <double> > edge_product = new List <Matrix <double> >(); for (int i = 0; i < mesh_vertices.Count; i++) { Matrix <double> edge_product_ = Matrix <double> .Build.Dense(3, 3); foreach (int j in neighbors[i]) { double weight = weights[i, j]; Matrix <double> edge = mesh_vertices[i].ToRowMatrix() - mesh_vertices[j].ToRowMatrix(); Matrix <double> edge_update = deformed_vertices[i].ToRowMatrix() - deformed_vertices[j].ToRowMatrix(); edge_product_ += weight * edge.Transpose() * edge_update; edge_product.Add(edge_product_); } } rotations = new List <Matrix <double> >(); for (int v = 0; v < mesh_vertices.Count; ++v) { Svd <double> svd = edge_product[v].Svd(true); Matrix <double> rotation = svd.U.Transpose() * svd.VT.Transpose(); rotations.Add(rotation); } }
/// <summary> /// Perform one iteration of training. /// </summary> public void Iteration() { int rowCount = _trainingData.Count; int coeffCount = _algorithm.LongTermMemory.Length; var working = new double[rowCount, coeffCount]; var errors = new double[rowCount]; var weights = new double[rowCount]; for (int i = 0; i < rowCount; i++) { BasicData element = _trainingData[i]; working[i, 0] = 1; for (int j = 0; j < element.Input.Length; j++) { working[i, j + 1] = element.Input[j]; } } for (int i = 0; i < rowCount; i++) { BasicData element = _trainingData[i]; double y = _algorithm.ComputeRegression(element.Input)[0]; errors[i] = y - element.Ideal[0]; weights[i] = y * (1.0 - y); } for (int i = 0; i < coeffCount; i++) { _gradient[i, 0] = 0; for (int j = 0; j < coeffCount; j++) { _hessian[i, j] = 0; } } for (int j = 0; j < rowCount; j++) { for (int i = 0; i < coeffCount; i++) { _gradient[i, 0] += working[j, i] * errors[j]; } } for (int k = 0; k < weights.Length; k++) { for (int j = 0; j < coeffCount; j++) { for (int i = 0; i < coeffCount; i++) { _hessian[j, i] += working[k, i] * working[k, j] * weights[k]; } } } LU <double> lu = _hessian.LU(); Matrix <double> deltas = lu.Solve(_gradient); var prev = (double[])_algorithm.LongTermMemory.Clone(); for (int i = 0; i < _algorithm.LongTermMemory.Length; i++) { _algorithm.LongTermMemory[i] -= deltas[i, 0]; } double max = 0; for (int i = 0; i < deltas.ColumnCount; i++) { max = Math.Max(Math.Abs(deltas[i, 0]) / Math.Abs(prev[i]), max); } _error = max; }
private static void test06() //****************************************************************************80 // // Purpose: // // TEST06 tests L1DD_LU and similar routines. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 02 November 2013 // // Author: // // John Burkardt // { const int n = 5; int test; Console.WriteLine(""); Console.WriteLine("TEST06"); Console.WriteLine(" Compute LU factors for the Laplacian:"); Console.WriteLine(" L1DD_LU for Dirichlet/Dirichlet BC;"); Console.WriteLine(" L1DN_LU for Dirichlet/Neumann BC;"); Console.WriteLine(" L1ND_LU for Neumann/Dirichlet BC;"); Console.WriteLine(" L1NN_LU for Neumann/Neumann BC;"); Console.WriteLine(" L1PP_LU for Periodic BC;"); double[] l = new double[n * n]; double[] u = new double[n * n]; for (test = 1; test <= 2; test++) { double h = test switch { 1 => 1.0, _ => 1.0 / (n + 1) }; Console.WriteLine(""); Console.WriteLine(" Using spacing H = " + h + ""); double[] a = L1DD.l1dd(n, h); L1DD.l1dd_lu(n, h, ref l, ref u); typeMethods.r8mat_print(n, n, l, " L1DD L factor:"); typeMethods.r8mat_print(n, n, u, " L1DD U factor:"); double err = LU.lu_error(n, a, l, u); Console.WriteLine(""); Console.WriteLine(" L1DD LU error = " + err + ""); a = L1DN.l1dn(n, h); L1DN.l1dn_lu(n, h, ref l, ref u); typeMethods.r8mat_print(n, n, l, " L1DN L factor:"); typeMethods.r8mat_print(n, n, u, " L1DN U factor:"); err = LU.lu_error(n, a, l, u); Console.WriteLine(""); Console.WriteLine(" L1DN LU error = " + err + ""); a = L1ND.l1nd(n, h); L1ND.l1nd_lu(n, h, ref l, ref u); typeMethods.r8mat_print(n, n, l, " L1ND L factor:"); typeMethods.r8mat_print(n, n, u, " L1ND U factor:"); err = LU.lu_error(n, a, l, u); Console.WriteLine(""); Console.WriteLine(" L1ND LU error = " + err + ""); a = L1NN.l1nn(n, h); L1NN.l1nn_lu(n, h, ref l, ref u); typeMethods.r8mat_print(n, n, l, " L1NN L factor:"); typeMethods.r8mat_print(n, n, u, " L1NN U factor:"); err = LU.lu_error(n, a, l, u); Console.WriteLine(""); Console.WriteLine(" L1NN LU error = " + err + ""); a = L1PP.l1pp(n, h); L1PP.l1pp_lu(n, h, ref l, ref u); typeMethods.r8mat_print(n, n, l, " L1PP L factor:"); typeMethods.r8mat_print(n, n, u, " L1PP U factor:"); err = LU.lu_error(n, a, l, u); Console.WriteLine(""); Console.WriteLine(" L1PP LU error = " + err + ""); } } }
/// <summary> /// Validates VAT number /// </summary> /// <returns>Corrected VAT number in VatNumber object</returns> public static VatNumber Validate(string vat, EUCountry euCountry) { string countryCode = euCountry.ToString().ToUpper(); vat = vat.ToUpper(); CountryBase countryBase; switch (euCountry) { case EUCountry.AT: countryBase = new AT(); break; case EUCountry.BE: countryBase = new BE(); break; case EUCountry.BG: countryBase = new BG(); break; case EUCountry.CY: countryBase = new CY(); break; case EUCountry.CZ: countryBase = new CZ(); break; case EUCountry.DE: countryBase = new DE(); break; case EUCountry.DK: countryBase = new DK(); break; case EUCountry.EE: countryBase = new EE(); break; case EUCountry.EL: countryBase = new EL(); break; case EUCountry.ES: countryBase = new ES(); break; case EUCountry.FI: countryBase = new FI(); break; case EUCountry.FR: countryBase = new FR(); break; case EUCountry.GB: countryBase = new GB(); break; case EUCountry.HR: countryBase = new HR(); break; case EUCountry.HU: countryBase = new HU(); break; case EUCountry.IE: countryBase = new IE(); break; case EUCountry.IT: countryBase = new IT(); break; case EUCountry.LT: countryBase = new LT(); break; case EUCountry.LU: countryBase = new LU(); break; case EUCountry.LV: countryBase = new LV(); break; case EUCountry.MT: countryBase = new MT(); break; case EUCountry.NL: countryBase = new NL(); break; case EUCountry.PL: countryBase = new PL(); break; case EUCountry.PT: countryBase = new PT(); break; case EUCountry.RO: countryBase = new RO(); break; case EUCountry.SE: countryBase = new SE(); break; case EUCountry.SI: countryBase = new SI(); break; case EUCountry.SK: countryBase = new SK(); break; default: throw new InvalidCountryException(); } if (countryBase.StripLetters) { return(new VatNumber(euCountry, countryBase.Validate(Strip(vat)))); } return(new VatNumber(euCountry, countryBase.Validate(StripNoLetters(vat, countryCode)))); }
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); } }