//CONSTRUCTOR public StepperWindow(StepperVM svm) : base() { //Bind property data through the StepperVM this.StepperVM = svm; this.DataContext = svm; InitializeComponent(); //Create a list of ObjectiveControl UI objects for each objective this.Objectives = new List <ObjectiveControl>(); foreach (List <double> objective in this.StepperVM.Objectives) { this.Objectives.Add(new ObjectiveControl()); } ConfigureDisplay(); }
public override Grasshopper.GUI.Canvas.GH_ObjectResponse RespondToMouseDoubleClick(Grasshopper.GUI.Canvas.GH_Canvas sender, Grasshopper.GUI.GH_CanvasMouseEvent e) { //Prevent opening of multiple windows at once if (!MyComponent.IsWindowOpen) { MyComponent.IsWindowOpen = true; StepperVM VM = new StepperVM(this.MyComponent); Thread viewerThread = new Thread(delegate() { System.Windows.Window viewer = new StepperWindow(VM); viewer.Show(); System.Windows.Threading.Dispatcher.Run(); }); viewerThread.SetApartmentState(ApartmentState.STA); // needs to be STA or throws exception viewerThread.Start(); } //reset relevant lists this.Gradient = new List <List <double> >(); this.DifOne = new List <List <double> >(); this.DifTwo = new List <List <double> >(); this.DesignMapStepperOne = new List <List <double> >(); this.DesignMapStepperTwo = new List <List <double> >(); this.DesignMapStepperCombined = new List <List <double> >(); this.ObjValsOne = new List <List <double> >(); this.ObjValsTwo = new List <List <double> >(); this.IsoPerf = new List <List <double> >(); //TO TEST OUTPUTS test.Add(new List <double>()); test[0].Add(248.0); numVars = MyComponent.numVars; numObjs = MyComponent.numObjs; //Set Finite Differences step size FDstep = 0.01; // create design map stepper, which is the list of new points to be tested for (int i = 0; i < numVars; i++) { DesignMapStepperOne.Add(new List <double>()); DesignMapStepperTwo.Add(new List <double>()); } for (int i = 0; i < numVars; i++) { for (int j = 0; j < numVars; j++) { DesignMapStepperOne[i].Add(MyComponent.VarsVals[j]); DesignMapStepperTwo[i].Add(MyComponent.VarsVals[j]); } } for (int i = 0; i < numVars; i++) { double left = MyComponent.VarsVals[i] - 0.5 * FDstep * (MyComponent.MaxVals[i] - MyComponent.MinVals[i]); double right = MyComponent.VarsVals[i] + 0.5 * FDstep * (MyComponent.MaxVals[i] - MyComponent.MinVals[i]); DesignMapStepperOne[i][i] = left; DesignMapStepperTwo[i][i] = right; } // combine lists DesignMapStepperCombined.AddRange(DesignMapStepperOne); DesignMapStepperCombined.AddRange(DesignMapStepperTwo); // Add dummy at end to resent sliders DesignMapStepperCombined.Add(MyComponent.VarsVals); // run through both design maps, gather objective values on left and right for each variable MyComponent.ObjValues = new List <List <double> >(); MyComponent.Iterating = true; this.Iterate(); MyComponent.Iterating = false; for (int j = 0; j < numObjs; j++) { ObjValsOne.AddRange(MyComponent.ObjValues); } double maxObj = double.MinValue; double minObj = double.MaxValue; // find the gradient for each objective by taking finite differences of every variable for (int j = 0; j < numObjs; j++) { Gradient.Add(new List <double>()); for (int i = 0; i < numVars; i++) { double left = ObjValsOne[i][j]; double right = ObjValsOne[numVars + i][j]; double difference = (right - left) / (FDstep); //* (MyComponent.MaxVals[i] - MyComponent.MinVals[i])); if (difference > maxObj) { maxObj = difference; } if (difference < minObj) { minObj = difference; } Gradient[j].Add((double)difference); //Gradient[j].Add((double) maxObj); } //Normalize by max/min difference double maxAbs = double.MinValue; double vecLength = 0; if (Math.Abs(maxObj) > maxAbs) { maxAbs = Math.Abs(maxObj); } if (Math.Abs(minObj) > maxAbs) { maxAbs = Math.Abs(minObj); } for (int i = 0; i < numVars; i++) { Gradient[j][i] = (Gradient[j][i] / maxAbs); vecLength = vecLength + Gradient[j][i] * Gradient[j][i]; } for (int i = 0; i < numVars; i++) { Gradient[j][i] = (Gradient[j][i] / Math.Sqrt(vecLength)); } } //// FIND THE ORTHOGONAL VECTORS ////double[][] gradientArray = Gradient.Select(a => a.ToArray()).ToArray(); List <List <string> > lst = new List <List <string> >(); double[,] gradientArray = new double[Gradient.Count, Gradient[0].Count]; for (int j = 0; j < Gradient.Count; j++) { for (int i = 0; i < Gradient[j].Count; i++) { gradientArray[j, i] = Gradient[j][i]; } } var matrixGrad = MathNet.Numerics.LinearAlgebra.Double.DenseMatrix.OfArray(gradientArray); //var matrixGrad = MathNet.Numerics.LinearAlgebra.Double.Matrix.Abs(14.0); //var matrixGradT = matrixGrad.Transpose(); var nullspace = matrixGrad.Kernel(); // Convert array to List of nullspace vectors if (numVars > numObjs) { for (int i = 0; i < numVars - numObjs; i++) { IsoPerf.Add(new List <double>()); double[] IsoPerfDir = nullspace[i].ToArray(); IsoPerf[i].AddRange(IsoPerfDir); } } // Randomly pick an isoperformance direction Random rnd = new Random(); int dir = new int(); int testrand = new int(); testrand = rnd.Next(numVars - numObjs); dir = testrand; // Ensure that direction is "interesting" //for (int i = testrand; i < numVars - numObjs - 1; i++) //{ // dir = i; // List<double> IsoVecAbs = IsoPerf[i].Select(x => Math.Abs(x)).ToList(); // IsoVecAbs.Sort(); // double a = IsoVecAbs[numVars - 1]; // double b = IsoVecAbs[numVars - 2]; // double c = a / b; // if (c < 3) { break; } // else { dir = dir + 1; } //} //for (int i = 0; i < numVars - numObjs; i++) //{ // for (int j = 0; j < IsoPerf[i].Count; j++) // { // IsoPerf.Add(new List<double>()); // double[] IsoPerfDir = nullspace[i].ToArray(); // } //} List <double> IsoPerfDirList = IsoPerf[dir]; // step in the right direction based on the gradient vector List <IGH_Param> sliderlist = new List <IGH_Param>(); foreach (IGH_Param src in MyComponent.Params.Input[0].Sources) { sliderlist.Add(src); } for (int i = 0; i < numVars; i++) { if (MyComponent.Direction > 0) { Grasshopper.Kernel.Special.GH_NumberSlider nslider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderlist[i]; double SteppedSlider = MyComponent.VarsVals[i] + Gradient[MyComponent.ObjNum][i] * MyComponent.StepSize * (MyComponent.MaxVals[i] - MyComponent.MinVals[i]); nslider.TrySetSliderValue((decimal)SteppedSlider); } if (MyComponent.Direction < 0) { Grasshopper.Kernel.Special.GH_NumberSlider nslider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderlist[i]; double SteppedSlider = MyComponent.VarsVals[i] - Gradient[MyComponent.ObjNum][i] * MyComponent.StepSize * (MyComponent.MaxVals[i] - MyComponent.MinVals[i]); nslider.TrySetSliderValue((decimal)SteppedSlider); } // TAKE STEP IN ORTHOGONAL DIRECTION if (MyComponent.Direction == 0) { Grasshopper.Kernel.Special.GH_NumberSlider nslider = (Grasshopper.Kernel.Special.GH_NumberSlider)sliderlist[i]; double SteppedSlider = MyComponent.VarsVals[i] + IsoPerfDirList[i] * MyComponent.StepSize * MyComponent.numVars; nslider.TrySetSliderValue((decimal)SteppedSlider); } } stepped = true; Grasshopper.Instances.ActiveCanvas.Document.NewSolution(true); return(base.RespondToMouseDoubleClick(sender, e)); }