PowerPoint Add In Gropuing Problem VSTO Visual Studio 2022 - c#

I've creating 5 shapes and objects in the addin. I need to group these objects, but it won't allow me to. I', creating 3 ovals, 1 rectable and 1 textbox. I'm thinking I can't group them because they aren't the same shape.
How I create the shapes:
PowerPoint.Slide activeSlide = Globals.ThisAddIn.Application.ActiveWindow.View.Slide;
var color = Color.Gray;
var accColor = Color.LightGray;
PowerPoint.Shape ellipseShapeInner = activeSlide.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeOval, 10, 10, 2.5f * 28.3464567f, 2.5f * 28.3464567f);
ellipseShapeInner.Name = "innerCircle";
ellipseShapeInner.Fill.Visible = Office.MsoTriState.msoFalse;
ellipseShapeInner.Line.Weight = 3;
ellipseShapeInner.Line.ForeColor.RGB = ColorTranslator.ToOle(color);
PowerPoint.Shape ellipseShapeMiddle = activeSlide.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeOval, 10, 10, 3.5f * 28.3464567f, 3.5f * 28.3464567f);
ellipseShapeMiddle.Name = "middleCircle";
ellipseShapeMiddle.Fill.Visible = Office.MsoTriState.msoFalse;
ellipseShapeMiddle.Line.Weight = 2;
ellipseShapeMiddle.Line.ForeColor.RGB = ColorTranslator.ToOle(accColor);
PowerPoint.Shape ellipseShapeOuter = activeSlide.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeOval, 100, 100, 4.5f * 28.3464567f, 4.5f * 28.3464567f);
ellipseShapeOuter.Name = "OuterCircle";
ellipseShapeOuter.Fill.Visible = Office.MsoTriState.msoFalse;
ellipseShapeOuter.Line.Weight = 2;
ellipseShapeOuter.Line.ForeColor.RGB = ColorTranslator.ToOle(accColor);
ellipseShapeMiddle.Left = ellipseShapeOuter.Left + (ellipseShapeOuter.Width - ellipseShapeMiddle.Width) / 2;
ellipseShapeMiddle.Top = ellipseShapeOuter.Top + (ellipseShapeOuter.Height - ellipseShapeMiddle.Height) / 2;
ellipseShapeInner.Left = ellipseShapeMiddle.Left + (ellipseShapeMiddle.Width -ellipseShapeInner.Width) / 2;
ellipseShapeInner.Top = ellipseShapeMiddle.Top + (ellipseShapeMiddle.Height - ellipseShapeInner.Height) / 2;
PowerPoint.Shape lineShape = activeSlide.Shapes.AddShape(Office.MsoAutoShapeType.msoShapeRectangle, 10, 10, 7 * 28.3464567f, 0);
lineShape.Name = "LineShape";
lineShape.Line.Weight = 3;
lineShape.Line.ForeColor.RGB = ColorTranslator.ToOle(color);
lineShape.Left = ellipseShapeInner.Left + ellipseShapeInner.Width;
lineShape.Top = ellipseShapeInner.Top + (ellipseShapeInner.Height / 2);
PowerPoint.Shape textbox = activeSlide.Shapes.AddTextbox(Office.MsoTextOrientation.msoTextOrientationHorizontal, 10, 10, 7 * 28.3464567f, 0);
textbox.Name = "OuterTextbox";
textbox.TextFrame.TextRange.InsertAfter("Fokuspungt");
textbox.Top = lineShape.Top - textbox.Height;
textbox.Left = lineShape.Left + (textbox.Width / 4);
I've tried multiple ways of grouping objects I've found from stack overflow, youtube, discord you name it, but nothing seems to work.
I've tried a list:
ArrayList list = new ArrayList();
list.Add(ellipseShapeInner);
list.Add(ellipseShapeMiddle);
list.Add(ellipseShapeOuter);
list.Add(lineShape);
list.Add(textbox);
activeSlide.Shapes.Range(list).Group();
Error: System.ArgumentException: 'Shapes (unknown member): Illegal
value. Bad type: expected 1D array of Variants, Integers, Longs, or
Strings'
I've tried an array:
string[] myRangeArray = new string[2];
myRangeArray[0] = "innerCircle";
myRangeArray[1] = "middleCircle";
myRangeArray[2] = "outerCircle";
myRangeArray[3] = "LineShape";
myRangeArray[4] = "OuterTextbox";
activeSlide.Shapes.Range(myRangeArray).Group();
Error: System.IndexOutOfRangeException: 'Index was outside the matrix
limit'

Related

Creating a grid like structure based on the area of an room

so in unity im creating randomly generating rooms. inside of these rooms i will "randomly" place objects, enemy,objects,items etc. based on nodes. nodes are transform objects that are separated from each other by 1 unit. the idea is that i can now pick a node and instantiate something at that node. The code works great when the room is 10x10(x,z since its a 3d game) i get a nice grid pattern it also works as expected when x is any multiple of 2. however when z changes from 10 it doesn't create the grid properly. there is also a problem if the room changes locations other then 0,0.
floor is a child object of the room.
void RoomSetup()
{
bool first = true;
int collCount = -1;
GameObject placeHolder = new GameObject("temp");
float colls;
float offX, offZ;
colls = floor.transform.localScale.x - 1;
print(colls);
for (int i = 0; i < ((floor.transform.localScale.x-1)
*(floor.transform.localScale.z-1)); i++)
{
//creating a for loop that stops when its greater then the area of the rectangle, subtract one from x,z so theres a one unit of padding from the walls.
offX = floor.transform.lossyPosition.x;
offZ = floor.transform.lossyPosition.z;
//getting the offset of the room in world space this is where i believe the issues arise
collCount++;
GameObject temp = new GameObject(i + " Node");
temp.transform.SetParent(floor.transform);
temp.AddComponent<BoxCollider>();
temp.GetComponent<BoxCollider>().isTrigger = true;
if(!first)
{
temp.transform.position = new Vector3((placeHolder.transform.position.x + 1), 6, placeHolder.transform.position.z);
placeHolder = temp;
if (collCount >= colls)
{
print("new line on " + temp.name + " coll " + collCount);
collCount = 0;
placeHolder.transform.position = new Vector3((-(floor.transform.localScale.x / 2) + 1)+offX, 6, (placeHolder.transform.position.z - 1)-offZ);
}
}
if (first)
{
// print(colls);
temp.transform.position = new Vector3((-(floor.transform.localScale.x / 2) + 1) + offX, 6, floor.transform.localScale.z - offZ);
placeHolder = temp;
first = false;
}
nodes.Add(temp);
}
}
Here are some pictures to help illustrate the issue
the first image is when the room is at 0,0 and it creates a nice grid pattern
when the room is offest it creates the grid still at 0,0
i figured it out, it happend to do with with the local and world scale/pos of the floor and the room
void RoomSetup()
{
bool first = true;
int collCount = -1;
GameObject placeHolder = new GameObject("temp");
float colls;
colls = floor.transform.localScale.x - 1;
offX = floor.transform.localScale.x;
offZ = floor.transform.localScale.z;
offX = (offX / 2) - offX + 1;
offZ = (offZ / 2) - 1;
offX = offX + floor.transform.position.x;
offZ = (offZ + floor.transform.position.z);
print(colls);
for (int i = 0; i < ((floor.transform.localScale.x-1) * (floor.transform.localScale.z-1)); i++)
{
collCount++;
//print(collCount);
GameObject temp = new GameObject(i + " Node");
temp.transform.SetParent(floor.transform);
temp.AddComponent<BoxCollider>();
temp.GetComponent<BoxCollider>().isTrigger = true;
if(!first)
{
temp.transform.position = new Vector3((placeHolder.transform.position.x + 1), 6, placeHolder.transform.position.z);
placeHolder = temp;
if (collCount >= colls)
{
print("new line on " + temp.name + " coll " + collCount);
collCount = 0;
temp.transform.position = new Vector3(floor.transform.localPosition.x + offX, 6, placeHolder.transform.position.z - 1);
placeHolder = temp;
}
}
if (first)
{
// print(colls);
temp.transform.position = new Vector3(floor.transform.localPosition.x+offX, 6, floor.transform.localPosition.z+offZ);
placeHolder = temp;
first = false;
}
nodes.Add(temp);
}
}
works as intended, creates a grid of nodes on the floor of anyroom square room

Drawing a lot of lines is very slow

I want to draw a lot of lines on 3 forms but when I call this method, it takes a lot of time. With 200+ lines it takes 1 sec approximately. What am I doing wrong?
public void drawObjects()
{
pAux = selectedPen;
for (int i = 0; i < objects.Count; i++)
{
for(int ed = 0; ed < objects[i].getEdges().Count; ed++)
{
frontGraphics.DrawRectangle(recPen, (objects[i].getEdges()[ed].getPoint1().X + 332), -(objects[i].getEdges()[ed].getPoint1().Y - 170), 2, 2);
rightGraphics.DrawRectangle(recPen, objects[i].getEdges()[ed].getPoint1().Z + 332, -(objects[i].getEdges()[ed].getPoint1().Y - 170), 2, 2);
topGraphics.DrawRectangle(recPen, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Z - 170), 2, 2);
if (objects[i].getEdges().Count > 0)
{
if (objects[i].selected == true)
pAux = selectedPen;
else
pAux = linePen;
frontGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Y -170),
objects[i].getEdges()[ed].getPoint2().X + 332, -(objects[i].getEdges()[ed].getPoint2().Y -170));
rightGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().Z + 332, -(objects[i].getEdges()[ed].getPoint1().Y - 170),
objects[i].getEdges()[ed].getPoint2().Z + 332, -(objects[i].getEdges()[ed].getPoint2().Y - 170));
topGraphics.DrawLine(pAux, objects[i].getEdges()[ed].getPoint1().X + 332, -(objects[i].getEdges()[ed].getPoint1().Z - 170),
objects[i].getEdges()[ed].getPoint2().X + 332, -(objects[i].getEdges()[ed].getPoint2().Z - 170));
}
}
}
}
It is not clear what front-end you're using (WPF, WinForms), but you might be using a lot of resources with your current code. The getEdges() and/or getPoint() methods could be costly methods, and you're calling those methods a lot.
If there's a result of method that you're going to reuse: store it in a variable. Here's what your code will look like:
public void drawObjects()
{
pAux = selectedPen;
for (int i = 0; i < objects.Count; i++)
{
var currentObject = objects[i];
var edges = currentObject.getEdges();
for(int ed = 0; ed < edges.Count; ed++)
{
var currentEd = edges[ed];
var edPoint1 = currentEd.getPoint1();
var edPoint2 = currentEd.getPoint2();
frontGraphics.DrawRectangle(recPen, (edPoint1.X + 332), -(edPoint1.Y - 170), 2, 2);
rightGraphics.DrawRectangle(recPen, edPoint1.Z + 332, -(edPoint1.Y - 170), 2, 2);
topGraphics.DrawRectangle(recPen, edPoint1.X + 332, -(edPoint1.Z - 170), 2, 2);
pAux = currentObject.selected ? selectedPen : linePen;
frontGraphics.DrawLine(pAux, edPoint1().X + 332, -(edPoint1().Y -170), edPoint2.X + 332, -(edPoint2.Y -170));
rightGraphics.DrawLine(pAux, edPoint1.Z + 332, -(edPoint1.Y - 170), edPoint2.Z + 332, -(edPoint2.Y - 170));
topGraphics.DrawLine(pAux, edPoint1.X + 332, -(edPoint1.Z - 170), edPoint2.X + 332, -(edPoint2.Z - 170));
}
}
}
Edit: as #Hans Kesting mentioned, this line in the inner loop is superfluous:
if (objects[i].getEdges().Count > 0)
It will always evaluate to true since you got in the inner loop.
PS: Note that this might not solve all your performance issues, but I'm sure this will help.
I solve this using PICTURE BOX, i draw in a bitmap and set bitmap as the image of Picture box.

Feedforward backPropagation networks to approximate linear functions using c#

I'm studying the feedforward backPropagation networks and using the "Accord.Neuro" libraries in c# (I used the ResilientBackpropagationLearning class that manages the "momentum" itself).
At this time my problem is to understand how to approximate the functions, especially those that are linear combinations of the input variables (hence the simplest ones).
Learning is supervised and one example is this: 3 variables -> y (x1, x2, x3) = 2 * x1 + x2 + 5 * x3.
I started studying functions on a single variable, then with 2, then with 3 variables and I managed to get results that I find satisfactory.
I managed to dimension the net and get good results.
---Case 3 Inputs:
3 INPUT
1 Hidden layer where there are 15 knots
1 OUTPUT
Training set, randomly generated on the input variable ranges, of 100 examples.
Training of 1000 Epochs(but also less).
I can get a network error of less than 0.001 and an average percentage error on the validation set of 1-2%.
---Try it now with 4 inputs
4 INPUT
1 Hidden layer where there are 25 knots
1 OUTPUT
Training set, randomly generated on the input variable ranges, of 500 examples
Training of 5000 Epochs
I can get a network error of less than 2.5 and an average percentage error on the validation set of 25-30%.
I've tried with so many configurations getting poor results. Even by increasing the number of examples up to 5000, epochs up to 100,000 and hidden nodes up to 50 I get an average percentage error on the validation set that improves but only up to 20-25%.
Why did I get so poor?
This is the base code of my program:
http://accord-framework.net/docs/html/T_Accord_Neuro_Learning_ResilientBackpropagationLearning.htm
This is my simple program:
using Accord.Neuro;
using Accord.Neuro.Learning;
using System;
namespace ConsoleApp4_1
{
class Program
{
struct struttura
{
public double INPUT1, INPUT2, INPUT3, INPUT4, OUTPUT1;
}
static void Main(string[] args)
{
bool needToStop = false;
Random rr = new Random((int)DateTime.Now.Millisecond);
int NE = 40, epoche = 50000, p;
double ERRORE = 0.00001d;
struttura[] EE = new struttura[NE];
double error = 1;
double[][] input = new double[NE][];
double[][] output = new double[NE][];
for (int u = 0; u < NE; u++) input[u] = new double[4];
for (int u = 0; u < NE; u++) output[u] = new double[1];
for (p = 0; p < NE; p++)
{
EE[p].INPUT1 = rr.Next(1, 200);
EE[p].INPUT2 = rr.Next(1, 100);
EE[p].INPUT3 = rr.Next(1, 50);
EE[p].INPUT4 = rr.Next(1, 150);
EE[p].OUTPUT1 = 0.1d * EE[p].INPUT2 + (2.0d / 3) * EE[p].INPUT1 + (7.0d / 10) * EE[p].INPUT3 + (2.0d / 3) * EE[p].INPUT4; // 278.3333333
}
for (p = 0; p < NE; p++)
{
for (int u = 0; u < NE; u++) input[u][0] = EE[u].INPUT1 / 200;
for (int u = 0; u < NE; u++) input[u][1] = EE[u].INPUT2 / 100;
for (int u = 0; u < NE; u++) input[u][2] = EE[u].INPUT3 / 50;
for (int u = 0; u < NE; u++) input[u][3] = EE[u].INPUT3 / 150;
for (int u = 0; u < NE; u++) output[u][0] = EE[u].OUTPUT1 / 278.3333333;
}
// create neural network
ActivationNetwork network = new ActivationNetwork(new SigmoidFunction(), 4, 8, 1);
// create teacher
var teacher = new ResilientBackpropagationLearning(network);
int i = 0;
// loop
while (!needToStop)
{
i++;
// run epoch of learning procedure
error = teacher.RunEpoch(input, output);
// check error value to see if we need to stop
if ((error < ERRORE) | (i == epoche)) needToStop = true;
Console.WriteLine(i + " " + error);
}
Console.WriteLine("Esempi per epoca: "+NE+" epoca: " + i + " error: " + error + "\n\n"); // bastano 408 epoche con NE = 40
double[] test1 = new double[] { 30.0d / 200, 80.0d / 100, 23.0d / 50, 100.0d/150};
double[] ris1 = network.Compute(test1);
double[] ris1Atteso1 = new double[] { 110.7666667d };
Console.WriteLine("a: " + (ris1[0] * 278.3333333d).ToString("") + " " + ris1Atteso1[0]);
double[] test2 = new double[] { 150.0d / 200, 40.0d / 100, 3.0d / 50, 40.0d/150};
double[] ris2 = network.Compute(test2);
double[] ris1Atteso2 = new double[] { 132.7666667d };
Console.WriteLine("\na: " + (ris2[0] * 278.3333333d).ToString("") + " " + ris1Atteso2[0]);
double[] test3 = new double[] { 15.0d / 200, 30.0d / 100, 45.0d / 50, 146.0d/150};
double[] ris3 = network.Compute(test3);
double[] ris1Atteso3 = new double[] { 141,8333333d };
Console.WriteLine("\na: " + (ris3[0] * 278.3333333d).ToString("") + " " + ris1Atteso3[0]);
double[] test4 = new double[] { 3.0d / 200, 60.0d / 100, 12.0d / 50, 70.0d/150};
double[] ris4 = network.Compute(test4);
double[] ris1Atteso4 = new double[] {63.0666667d};
Console.WriteLine("\na: " + (ris4[0] * 278.3333333d).ToString("") + " " + ris1Atteso4[0]);
double[] test5 = new double[] { 50.0d / 200, 2.0d / 100, 44.0d / 50, 15.0d/150};
double[] ris5 = network.Compute(test5);
double[] ris1Atteso5 = new double[] { 74,333333d };
Console.WriteLine("\na: " + (ris5[0] * 278.3333333d).ToString("") + " " + ris1Atteso5[0]);
double[] test6 = new double[] { 180.0d / 200, 95.0d / 100, 25.0d / 50, 70.0d/150 };
double[] ris6 = network.Compute(test6);
double[] ris1Atteso6 = new double[] { 193.6666667 };
Console.WriteLine("\na: " + (ris6[0] * 278.3333333d).ToString("") + " " + ris1Atteso6[0]);
double[] test7 = new double[] { 22.0d / 200, 12.0d / 100, 2.0d / 50, 10.0d/150 };
double[] ris7 = network.Compute(test7);
double[] ris1Atteso7 = new double[] { 23.9333333d };
Console.WriteLine("\na: " + (ris7[0] * 278.3333333d).ToString("") + " " + ris1Atteso7[0]);
double[] test8 = new double[] { 35.0d / 200, 5.0d / 100, 40.0d / 50, 120.0d/150 };
double[] ris8 = network.Compute(test8);
double[] ris1Atteso8 = new double[] { 131.8333333d };
Console.WriteLine("\na: " + (ris8[0] * 278.3333333d).ToString("") + " " + ris1Atteso8[0]);
double[] test9 = new double[] { 115.0d / 200, 70.0d / 100, 50.0d / 50, 88.0d/150};
double[] ris9 = network.Compute(test9);
double[] ris1Atteso9 = new double[] { 177.3333333d };
Console.WriteLine("\na: " + (ris9[0] * 278.3333333d).ToString("") + " " + ris1Atteso9[0]);
double[] test10 = new double[] { 18.0d / 200, 88.0d / 100, 1.0d / 50, 72.0d/150 };
double[] ris10 = network.Compute(test10);
double[] ris1Atteso10 = new double[] { 69.5d };
Console.WriteLine("\na: " + (ris10[0] * 278.3333333d).ToString("") + " " + ris1Atteso10[0]);
double sum = Math.Abs(ris1[0] * 278.3333333d - ris1Atteso1[0])+ Math.Abs(ris2[0] * 278.3333333d - ris1Atteso2[0]) + Math.Abs(ris3[0] * 278.3333333d - ris1Atteso3[0]) + Math.Abs(ris4[0] * 278.3333333d - ris1Atteso4[0]) + Math.Abs(ris5[0] * 278.3333333d - ris1Atteso5[0])
+ Math.Abs(ris6[0] * 278.3333333d - ris1Atteso6[0]) + Math.Abs(ris7[0] * 278.3333333d - ris1Atteso7[0]) + Math.Abs(ris8[0] * 278.3333333d - ris1Atteso8[0]) + Math.Abs(ris9[0] * 278.3333333d - ris1Atteso9[0]) + Math.Abs(ris10[0] * 278.3333333d - ris1Atteso10[0]);
double erroreMedio = sum / 10;
double sumMedie = Math.Abs((ris1[0] * 278.3333d - ris1Atteso1[0]) / (ris1Atteso1[0]))
+ Math.Abs((ris2[0] * 278.3333d - ris1Atteso2[0]) / (ris1Atteso2[0]))
+ Math.Abs((ris3[0] * 278.3333d - ris1Atteso3[0]) / (ris1Atteso3[0]))
+ Math.Abs((ris4[0] * 278.3333d - ris1Atteso4[0]) / (ris1Atteso4[0]))
+ Math.Abs((ris5[0] * 278.3333d - ris1Atteso5[0]) / (ris1Atteso5[0]))
+ Math.Abs((ris6[0] * 278.3333d - ris1Atteso6[0]) / (ris1Atteso6[0]))
+ Math.Abs((ris7[0] * 278.3333d - ris1Atteso7[0]) / (ris1Atteso7[0]))
+ Math.Abs((ris8[0] * 278.3333d - ris1Atteso8[0]) / (ris1Atteso8[0]))
+ Math.Abs((ris9[0] * 278.3333d - ris1Atteso9[0]) / (ris1Atteso9[0]))
+ Math.Abs((ris10[0] * 278.3333d - ris1Atteso10[0]) / (ris1Atteso10[0]));
Console.WriteLine("\nErrore medio su 10 : "+ erroreMedio);
Console.WriteLine("\nErrore % medio : " + (sumMedie/10)*100);
Console.ReadLine();
}
}
}
Although i'm unfamiliar with Accord.
You seam to hit a classical problem that can happen to wrong dimensioned networks.
The neural network gets (extreme) good on training sets but not on practical sets.
I think you should try it with less hidden neurons.
As your network learned to much the training set resulting in that it cannt handle different data. As it would be better to score 85%-train and 79%-validation. As compared to 99%-train and 65%-validation. Notice that those % numbers the total % of both network is the same (85+79)=(99+65), but the first network would be better in solving unknown thing; and thats the general goal.
The term for what you have now is called over fitting.
Most often caused by that the network starts to act more like memory, it memorizes treshold, while it should be more about decision making in the unknown validation sets. Well i hope this helps.
Also be aware that with less hidden neurons, its also possible to not achieve near 100% on train set, but eventually its not about solving that one, keep that in mind.
Also not sure what you try to solve with it, but make sure your data set has the right neural network, for simple testing fun try to Irish-flower data set. My networks can score 199.16% or so on that in combined (trained+validation). You might try to beat that and if so give me an update :)

Correct way to use indexer in Parallel.For

I have a method which generates a (Waveform) bitmap based on a specific (Waveform)-function (in the examples below I am simply using Math.Sin to simplify things). Up until now this method was "serial" (no threads) however some of the functions used are relatively time consuming so I tried using Parallel.For and Parallel.ForEach, but I guess the index variable I use must get "corrupted" (or at least have another value than what I expect) the graphics being generated will either contain "spikes" or strange lines between points that are not neighbours.
Here first is my serial version (which works):
Point[] points = new Point[rect.Width];
byte[] ptTypes = new byte[rect.Width];
for (int i = 0; i < rect.Width; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int) (halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
using (GraphicsPath wavePath = new GraphicsPath(points, ptTypes))
{
gph.DrawPath(wavePen, wavePath);
}
As you can see the code simply uses 2 arrays (one for Points and one for PointTypes) so the order these values are inserted into the array should not matter, as long as the values are inserted into the correct elements of the arrays.
Next example is using Parallel.For (to simplify the examples I have omitted the creation of the arrays and the actual draw method):
Parallel.For(0, rect.Width,
i =>
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
});
Lastly I tried using a Partitioner with a Parallel.ForEach loop, but that did not fix the problem either:
var rangePartitioner = Partitioner.Create(0, rect.Width);
Parallel.ForEach(rangePartitioner, (range, loopState) =>
{
for (int i = range.Item1; i < range.Item2; i++)
{
double phase = MathUtil.WrapRad((MathUtil.PI2 / (rect.Width / 1d)) * i);
double value = Math.Sin(phase);//waveform.ValueAtPhase(phase);
newPoint = new Point(rect.Left + i,
rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
points[i] = newPoint;
if (i == 0)
ptTypes[i] = (byte)PathPointType.Start;
else
ptTypes[i] = (byte)PathPointType.Line;
}
});
Pelle
newPoint = new Point(rect.Left + i, rect.Top + (int)(halfHeight + (value * -1d * halfHeight * scaleY)));
newPoint is not scoped to your for() loop - it's likely threads are updating it before you get to the next line points[i] = newPoint;
Change it to var newPoint = ...
Otherwise, your Parallel.For looks fine.
Also, does this have different behavior?
Math.Sin(phase);//waveform.ValueAtPhase(phase);
Providing ValueAtPhase does not modify anything, you should be able to use it within the loop.

nonlinear optimization using the Solver Foundation Services

I have a non-linear optimization problem with constraints. It can be solved in Microsoft Excel with the Solver add-in, but I am having trouble replicating that in C#.
I installed the Microsoft Solver Foundation dll
This is the example where I adapted my code from :
http://msdn.microsoft.com/en-us/library/gg261758(v=vs.93).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-3
Basically, in my code, I have 2 parameters called RHO and NU. I need to get their optimal values which minimizes the sum of squares. I have ONLY 1 value for RHO and 1 value for NU, so I know that putting RHO[s] and NU[s] in my code is wrong, but when I replace them with RHO and NU, I get errors.
Another issue is that, in the example, the code looks for one optimal variable called "fuel" of type "Goal". In my case, I have 2 variables which need to be optimized.
Obviously, the program breaks at the last line, it says: "there is no solution to propagate".
Anyone has an idea how my code could be corrected ?? any help is appreciated !
This is my code:
class Segment
{
public double Strike { get; set; }
public double VolImp { get; set; }
public double _Rho_ { get; set; }
public double _Nu_ { get; set; }
public double _Alpha_ { get; set; }
}
Segment[] segmentData = new Segment[] {
new Segment { Strike = 5, VolImp = 53.2608},
new Segment { Strike = 10, VolImp = 48.3773},
new Segment { Strike = 20, VolImp = 43.8949},
new Segment { Strike = 30, VolImp = 40.9367},
new Segment { Strike = 40, VolImp = 38.891},
new Segment { Strike = 50, VolImp = 37.417},
new Segment { Strike = 60, VolImp = 36.2838},
new Segment { Strike = 70, VolImp = 35.3713},
new Segment { Strike = 80, VolImp = 34.6192},
new Segment { Strike = 90, VolImp = 33.9774},
new Segment { Strike = 100, VolImp = 33.4359},
new Segment { Strike = 110, VolImp = 32.9747},
new Segment { Strike = 120, VolImp = 32.5635},
new Segment { Strike = 130, VolImp = 32.2025},
new Segment { Strike = 140, VolImp = 31.8917},
new Segment { Strike = 150, VolImp = 31.6209},
new Segment { Strike = 160, VolImp = 31.3702},
new Segment { Strike = 170, VolImp = 31.1596},
new Segment { Strike = 180, VolImp = 30.9591},
};
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
// Parameters
Set segments = new Set(Domain.Integer, "segments");
Parameter RHO = new Parameter(Domain.Real, "RHO", segments);
RHO.SetBinding(segmentData, "_Rho_", "Strike");
Parameter NU = new Parameter(Domain.RealNonnegative, "NU", segments);
NU.SetBinding(segmentData, "_Nu_", "Strike");
Parameter ALPHA = new Parameter(Domain.RealNonnegative, "ALPHA", segments);
ALPHA.SetBinding(segmentData, "_Alpha_", "Strike");
Parameter MyStrike = new Parameter(Domain.RealNonnegative, "MyStrike", segments);
MyStrike.SetBinding(segmentData, "Strike", "Strike");
Parameter MyImpVol = new Parameter(Domain.RealNonnegative, "MyImpVol", segments);
MyImpVol.SetBinding(segmentData, "VolImp", "Strike");
model.AddParameters(RHO, NU, ALPHA, MyStrike, MyImpVol);
//Constraints
model.AddConstraint("rho_bound", Model.ForEach(segments, s => (-1 <= RHO[s] <= 1))) ;
model.AddConstraint("nu_bound", Model.ForEach(segments, s => (0 <= NU[s]) )) ;
model.AddConstraint("alpha_bound", Model.ForEach(segments, s => (0 < ALPHA[s]))) ;
double Forward = 100 ;
//Goal
Goal Mygoal = model.AddGoal("Mygoal", GoalKind.Minimize, Model.Sum(Model.ForEach(segments, s => Model.Power((MyImpVol[s] - (ALPHA[s] * (NU[s] / ALPHA[s] * Model.Log(Forward / MyStrike[s])) * (Model.Log((Model.Sqrt(1 - 2 * RHO[s] * (NU[s] / ALPHA[s] * Model.Log(Forward / MyStrike[s])) + Model.Power((NU[s] / ALPHA[s] * Model.Log(Forward / MyStrike[s])), 2)) + (NU[s] / ALPHA[s] * Model.Log(Forward / MyStrike[s])) - RHO[s]) / (1 - RHO[s]))) * (1 + (0.25 * RHO[s] * NU[s] * ALPHA[s] + (2 - 3 * RHO[s] * RHO[s]) / 24 * NU[s] * NU[s]) * 6.46407))), 2)))) ;
//solve
context.Solve();
context.PropagateDecisions();

Categories