public void SetupSolver() { depth = parameter_names.Count; width = (int)Mathf.Pow(PARTICLE_COUNT, 1f / (float)depth); for (int i = 0; i < depth; i++) { string name = parameter_names[i]; indexedParam[i] = name; parameterMin[name] = (float)solver.EvaluateExpression(parameter_min[name]); parameterMax[name] = (float)solver.EvaluateExpression(parameter_max[name]); solver.SetGlobalVariable(name, 0); } expr1 = solver.SymbolicateExpression(expression1); expr2 = solver.SymbolicateExpression(expression2); expr3 = solver.SymbolicateExpression(expression3); for (int i = 0; i < depth; i++) { string name = parameter_names[i]; AK.Variable var = solver.GetGlobalVariable(name); //vars.Add(var); vars[name] = var; } }
// Evaluate all equations for a given x (called by a thread), and popluate arrays with the results void ThreadedEvaluate(float x_temp, int inOrderCount) { AK.ExpressionSolver subSolver = new AK.ExpressionSolver(); AK.Expression subExp = new AK.Expression(); subSolver.SetGlobalVariable("x", 0); subSolver.SetGlobalVariable("y", 0); subSolver.SetGlobalVariable("z", 0); AK.Variable subX = subSolver.GetGlobalVariable("x"); AK.Variable subY = subSolver.GetGlobalVariable("y"); AK.Variable subZ = subSolver.GetGlobalVariable("z"); subExp = subSolver.SymbolicateExpression(es.expressions["X"].expression); for (float y_temp = ymin; y_temp < ymax; y_temp += delta) { for (float z_temp = zmin; z_temp < zmax; z_temp += delta) { if ((int)((z_temp - zmin) / delta) % sleepInterval == 0) { Thread.Sleep(1); } subX.value = x_temp; subY.value = z_temp; subZ.value = y_temp; float x = (float)subExp.Evaluate(); //Mathf.Clamp(x, -Mathf.Exp(20), Mathf.Exp(20)); //float y = (float)expY.Evaluate(); //Mathf.Clamp(y, -Mathf.Exp(20), Mathf.Exp(20)); //float z = (float)expZ.Evaluate(); //Mathf.Clamp(z, -Mathf.Exp(20), Mathf.Exp(20)); Vector3 target = new Vector3(x_temp, y_temp, z_temp); Vector3 result = new Vector3(x, 0, 0); if (float.IsNaN(x) // || float.IsNaN(y) // || float.IsNaN(z) || Mathf.Abs(x) == 0) { result = new Vector3(0, 0, 0); } //Vector3 direction = result.normalized; lock (lck) { max_magnitude = (Mathf.Abs(x) > max_magnitude) ? Mathf.Abs(x) : max_magnitude; } startPts[inOrderCount] = target; offsets[inOrderCount] = result; inOrderCount++; } } // numComplete++; }
// Use this for initialization void Start() { vectors = new List <Transform>(); startPts = new List <Vector3>(); offsets = new List <Vector3>(); solver = new AK.ExpressionSolver(); expX = new AK.Expression(); expY = new AK.Expression(); expZ = new AK.Expression(); solver.SetGlobalVariable("x", 0); solver.SetGlobalVariable("y", 0); solver.SetGlobalVariable("z", 0); varX = solver.GetGlobalVariable("x"); varY = solver.GetGlobalVariable("y"); varZ = solver.GetGlobalVariable("z"); max_magnitude = 0f; //CalculateVectors(); //DrawVectorField(); }
void ThreadedEvaluate(int TID, int chunkSize, int extra) { AK.ExpressionSolver solver_ = new AK.ExpressionSolver(); AK.Variable u_ = solver_.SetGlobalVariable("theta", 0); AK.Variable v_ = solver_.SetGlobalVariable("phi", 0); AK.Expression exp_ = solver_.SymbolicateExpression(expr); float umin = (float)solver_.EvaluateExpression(uminExpr); float umax = (float)solver_.EvaluateExpression(umaxExpr); float vmin = (float)solver_.EvaluateExpression(vminExpr); float vmax = (float)solver_.EvaluateExpression(vmaxExpr); System.Random rand = new System.Random(); for (int i = 0; i < chunkSize + extra; i++) { float u = (float)(chunkSize * TID + i) / (resolution - 1); u_.value = umin + (umax - umin) * u; for (int j = 0; j < resolution; j++) { float v = (float)j / (resolution - 1); v_.value = vmin + (vmax - vmin) * v; float result = (float)exp_.Evaluate(); Vector3 spherical = new Vector3((float)u_.value, (float)v_.value, result); Vector3 cartesian = SphericalToCartesian(spherical); Vector3 vel = new Vector3( (float)rand.NextDouble(), (float)rand.NextDouble(), (float)rand.NextDouble()); vel = vel.normalized * 0.1f; float sqrt2 = Mathf.Sqrt(2.0f); Color c = Color.cyan * Mathf.Sqrt(u * u + v * v) / sqrt2 + Color.yellow * (1.0f - Mathf.Sqrt(u * u + v * v) / sqrt2) + Color.red * Mathf.Sqrt(u * u + (1 - v) * (1 - v)) / sqrt2 + Color.green * (1.0f - Mathf.Sqrt(u * u + (1 - v) * (1 - v)) / sqrt2); Vector3 pos = new Vector3(cartesian.x, cartesian.z, cartesian.y); Particle p = new Particle() { position = pos, velocity = vel, color = c }; lock (insert_lck) { results.Add(p); } } } }
public Variable SetVariable(string name, string value) { Variable v; if (constants.TryGetValue(name,out v)) { if (v.stringValue == null) { throw new ESParameterTypeChangedException("Can not change type of existing parameter " + name); } v.stringValue = value; return v; } v = new Variable(name,value); constants.Add(name,v); return v; }
Vector3 ThreadedRK4(int TID, Vector3 v0, float dt) { AK.Variable varX_ = solvers[TID].GetGlobalVariable("x"); AK.Variable varY_ = solvers[TID].GetGlobalVariable("y"); AK.Variable varZ_ = solvers[TID].GetGlobalVariable("z"); varX_.value = v0.x; varY_.value = v0.z; varZ_.value = v0.y; Vector3 m1 = new Vector3((float)expXs[TID].Evaluate(), (float)expZs[TID].Evaluate(), (float)expYs[TID].Evaluate()).normalized; varX_.value = v0.x + m1.x * dt / 2.0f; varY_.value = v0.z + m1.z * dt / 2.0f; varZ_.value = v0.y + m1.y * dt / 2.0f; Vector3 m2 = new Vector3((float)expXs[TID].Evaluate(), (float)expZs[TID].Evaluate(), (float)expYs[TID].Evaluate()).normalized; varX_.value = v0.x + m2.x * dt / 2.0f; varY_.value = v0.z + m2.z * dt / 2.0f; varZ_.value = v0.y + m2.y * dt / 2.0f; Vector3 m3 = new Vector3((float)expXs[TID].Evaluate(), (float)expZs[TID].Evaluate(), (float)expYs[TID].Evaluate()).normalized; varX_.value = v0.x + m3.x * dt; varY_.value = v0.z + m3.z * dt; varZ_.value = v0.y + m3.y * dt; Vector3 m4 = new Vector3((float)expXs[TID].Evaluate(), (float)expZs[TID].Evaluate(), (float)expYs[TID].Evaluate()).normalized; Vector3 m = (m1 + m2 * 2.0f + m3 * 2.0f + m4) / 6.0f; return(v0 + m * dt); }
internal void ThreadedEvaluate(List <int[]> samples, ExpressionSet expressionSet, int TID) { Dictionary <string, AK.Variable> vars = new Dictionary <string, AK.Variable>(); int depth = expressionSet.ranges.Count; int width = (int)Mathf.Pow(particlesPerES, 1f / (float)depth); System.Random rand = new System.Random(); ThreadHelper threadHelper = SetupSolver(expressionSet); Dictionary <int, string> indexedParam = new Dictionary <int, string>(); int k = 0; foreach (string name in expressionSet.ranges.Keys) { AK.Variable var = threadHelper.solver.GetGlobalVariable(name); indexedParam.Add(k, name); vars[name] = var; k++; } int iterations = Math.Min(particlesPerES - samples.Count * TID, samples.Count); Particle[] particles = new Particle[iterations]; for (int i = 0; i < iterations; i++) { int[] arr = samples[i]; for (int j = 0; j < depth; j++) { int val = arr[j]; string name = indexedParam[j]; AK.Variable var = vars[name]; var.value = threadHelper.parameterMin[name] + (float)val / (width - 1) * (threadHelper.parameterMax[name] - threadHelper.parameterMin[name]); } float x = (float)threadHelper.expressionList[0].Evaluate(); float z = (float)threadHelper.expressionList[1].Evaluate(); float y = (float)threadHelper.expressionList[2].Evaluate(); lock (lck) { maxRange = (Mathf.Abs(x) > maxRange) ? Mathf.Abs(x) : maxRange; maxRange = (Mathf.Abs(y) > maxRange) ? Mathf.Abs(y) : maxRange; maxRange = (Mathf.Abs(z) > maxRange) ? Mathf.Abs(z) : maxRange; } particles[i] = new Particle(); particles[i].position = new Vector3(x, y, z); Vector3 vel = new Vector3(); vel.x = 0.5f - (float)rand.NextDouble(); vel.y = 0.5f - (float)rand.NextDouble(); vel.z = 0.5f - (float)rand.NextDouble(); vel = 0.1f * Vector3.Normalize(vel); particles[i].velocity = vel; } lock (lck) { threadResults.Add(particles); } }
public Symbol(Variable ptrToConstValue) { type = ptrToConstValue.stringValue != null ? SymbolType.StringVariable : SymbolType.RealValue; variable = ptrToConstValue; }
void SamplePoints() { Vector3 start = referencePoint.lastLocalPos; //lck = new object(); //thread_num = SystemInfo.processorCount; //thread_num = 1; //thread_num = (thread_num > 2) ? 2 : thread_num; tmin = (float)solver.EvaluateExpression(t_min); tmin = (tmin > 0) ? 0 : tmin; tmax = (float)solver.EvaluateExpression(t_max); tmax = (tmax < 0) ? 0 : tmax; currLocalPos = referencePoint.lastLocalPos; currExpX = vectorField.expressionX; currExpY = vectorField.expressionY; currExpZ = vectorField.expressionZ; int lastCount = positions.Count; positions.Clear(); solver = new AK.ExpressionSolver(); solver.SetGlobalVariable("x", referencePoint.lastLocalPos.x); solver.SetGlobalVariable("y", referencePoint.lastLocalPos.y); solver.SetGlobalVariable("z", referencePoint.lastLocalPos.z); expX = solver.SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.X].expression); expY = solver.SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.Y].expression); expZ = solver.SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.Z].expression); varX = solver.GetGlobalVariable("x"); varY = solver.GetGlobalVariable("y"); varZ = solver.GetGlobalVariable("z"); //solvers = new AK.ExpressionSolver[thread_num]; //expXs = new AK.Expression[thread_num]; //expYs = new AK.Expression[thread_num]; //expZs = new AK.Expression[thread_num]; //for(int i = 0; i < thread_num; i++) //{ // solvers[i] = new AK.ExpressionSolver(); // solvers[i].SetGlobalVariable("x", 0); // solvers[i].SetGlobalVariable("y", 0); // solvers[i].SetGlobalVariable("z", 0); // expXs[i] = solvers[i].SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.X].expression); // expYs[i] = solvers[i].SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.Y].expression); // expZs[i] = solvers[i].SymbolicateExpression(vectorField.es.expressions[ExpressionSet.ExpOptions.Z].expression); //} //Thread[] threads = new Thread[thread_num]; float positiveCount = tmax / time_step; positiveCount = (positiveCount > 50000) ? 50000 : positiveCount; float negativeCount = -tmin / time_step; negativeCount = (negativeCount > 50000) ? 50000 : negativeCount; //Vector3[] startPts = new Vector3[thread_num]; //startPts[0] = referencePoint.lastLocalPos; //for(int i = 1; i < thread_num; i++) //{ // startPts[i] = RK4(startPts[i - 1], time_step); //} //for(int i = 0; i < thread_num; i++) //{ // int index = i; // threads[i] = new Thread(() => ThreadedSampling(index, startPts[index], time_step * thread_num, positiveCount / thread_num, // negativeCount / thread_num)); // threads[i].Start(); //} ////for (int i = 0; i < 5; i++) ////{ //// yield return null; ////} //for (int i = 0; i < thread_num; i++) //{ // threads[i].Join(); //} Vector3 curr = start; for (int i = 0; i < positiveCount; i++) { curr = RK4(curr, time_step); positions.Add(i + 1, curr); } curr = start; for (int i = 0; i < negativeCount; i++) { curr = RK4(curr, -time_step); positions.Add(-i, curr); } if (positions.Count != lastCount) { InitializeParticleSystem(); } //RenderParticles(); currHighlight = 0; thread_finished = true; }
public void SetParamValue(string name, float ratio) { AK.Variable var = vars[name]; var.value = parameterMin[name] + ratio * (parameterMax[name] - parameterMin[name]); }
Symbol SymbolicateValue(string formula, int begin, int end, Expression exp) { if (formula[begin] == '+') { begin++; } // Check for string value if (formula[begin] == '\'' && formula[end - 1] == '\'') { var svalue = formula.Substring(begin+1,end-begin-2).Replace("\\'","'"); return new Symbol(svalue); } int depth=0; for (int k = begin; k < end; k++) { if (formula[k]=='(') depth++; else if (formula[k]==')') depth--; else if (depth == 0 && formula[k] == '^') { // Check for small integer powers: they will be done using multiplication instead! Symbol lhs = Symbolicate(formula,begin,k,exp); Symbol rhs = Symbolicate(formula,k+1,end,exp); var newSubExpression = new SymbolList(); if (end-k-1 == 1 && lhs.type == SymbolType.RealValue && formula.Substring(k+1,end-k-1)=="2") { // Second power found newSubExpression.Append(lhs); newSubExpression.Append(lhs); } else if (end-k-1 == 1 && lhs.type == SymbolType.RealValue && formula.Substring(k+1,end-k-1)=="3") { // Second power found newSubExpression.Append(lhs); newSubExpression.Append(lhs); newSubExpression.Append(lhs); } else { newSubExpression.Append(new Symbol(SymbolType.Pow)); newSubExpression.Append(lhs); newSubExpression.Append(rhs); } Symbol newSymbol = new Symbol(SymbolType.SubExpression); newSymbol.subExpression = newSubExpression; return newSymbol; } } if (formula[begin] == '(' && formula[end - 1] == ')') { var s = Symbolicate(formula, begin + 1, end - 1,exp); s.Simplify(); return s; } double valueAsRealNumber; if (double.TryParse(formula.Substring(begin,end-begin),out valueAsRealNumber)) { return new Symbol(valueAsRealNumber); } // Check if the value is transformed by a function if (formula[end-1]==')') { int i = begin; while (i < end-1) { if (formula[i]=='(') { break; } i++; } string funcName = formula.Substring(begin,i-begin); CustomFunction customFunc; if (customFuncs.TryGetValue(funcName,out customFunc)) { int requiredParameterCount = customFunc.paramCount; int foundParameterCount = SolverTools.CountParameters(formula,begin,end); if (requiredParameterCount == foundParameterCount) { if (requiredParameterCount == 1) { SymbolList newSubExpression = new SymbolList(); newSubExpression.Append(new Symbol(customFunc)); newSubExpression.Append(Symbolicate(formula,i+1,end-1,exp)); return new Symbol(newSubExpression); } else { List<SolverTools.IntPair> parameters = SolverTools.ParseParameters(formula,i,end); SymbolList newSubExpression = new SymbolList(); newSubExpression.Append(new Symbol(customFunc)); for (int k=0;k<requiredParameterCount;k++) { Symbol p = Symbolicate(formula,parameters[k].first,parameters[k].second,exp); newSubExpression.Append(p); } Symbol newSymbol = new Symbol(SymbolType.SubExpression); newSymbol.subExpression = newSubExpression; return newSymbol; } } else { throw new ESInvalidParametersException(customFunc.name + " expects " + requiredParameterCount + " parameters, " + foundParameterCount + " given."); } } else { throw new ESInvalidFunctionNameException(funcName); } } var valueName = formula.Substring(begin,end-begin); // Then a local constant specific to our expression Variable variable; if (exp.constants.TryGetValue(valueName,out variable)) { return new Symbol(variable); } // Non immutable globals if (globalConstants.TryGetValue(valueName,out variable)) { return new Symbol(variable); } // Immutable globals double constDouble; if (immutableGlobalConstants.TryGetValue(valueName, out constDouble)) { return new Symbol(constDouble); } // Found an unknown value name. Check policy to see what to do. Variable v = null; switch (undefinedVariablePolicy) { case UndefinedVariablePolicy.DefineExpressionLocalVariable: v = new Variable(valueName,0); exp.constants.Add(valueName,v); return new Symbol(v); case UndefinedVariablePolicy.DefineGlobalVariable: v = new Variable(valueName,0); globalConstants.Add(valueName,v); return new Symbol(v); default: throw new ESUnknownExpressionException(valueName); } }
public Variable SetGlobalVariable(string name, string value) { if (value == null) { throw new System.ArgumentException("Null is not acceptable string parameter value."); } Variable variable; if (globalConstants.TryGetValue(name, out variable)) { if (variable.stringValue == null) { throw new ESParameterTypeChangedException("Can not change type of existing parameter " + name); } variable.stringValue = value; return variable; } else { Variable v = new Variable(name,value); globalConstants.Add (name,v); return v; } }
public Variable SetGlobalVariable(string name, double value) { Variable variable; if (globalConstants.TryGetValue(name, out variable)) { if (variable.stringValue != null) { throw new ESParameterTypeChangedException("Can not change type of existing parameter " + name); } variable.value = value; return variable; } else { Variable v = new Variable(name,value); globalConstants.Add (name,v); return v; } }