I should have 5 columns which stack the second and third values.
Instead, I get two columns:
The first stacking the second value of each column.
The second column stacking the last 4 values.
I'm not sure exactly what I'm doing wrong. I have been battling with Syncfusion for the past week trying to get, what I would have thought to be, fairly basic slides built for a client. However, this has been a nightmare so far.
// Creates the two charts that go on the presentation
IPresentationChart chart = slide.Charts.AddChart(150, 100, 300, 125);
// Set data values
chart.ChartData.SetValue(1, 1, date1);
chart.ChartData.SetValue(2, 1, date2);
chart.ChartData.SetValue(3, 1, date3);
chart.ChartData.SetValue(4, 1, date4);
chart.ChartData.SetValue(5, 1, date5);
chart.ChartData.SetValue(1, 2, mains1);
chart.ChartData.SetValue(2, 2, mains2);
chart.ChartData.SetValue(3, 2, mains3);
chart.ChartData.SetValue(4, 2, mains4);
chart.ChartData.SetValue(5, 2, mains5);
chart.ChartData.SetValue(1, 3, variance1);
chart.ChartData.SetValue(2, 3, variance2);
chart.ChartData.SetValue(3, 3, variance3);
chart.ChartData.SetValue(4, 3, variance4);
chart.ChartData.SetValue(5, 3, variance5);
// Chart 1
// Set data range, Title and Category settings
chart.PrimaryCategoryAxis.CategoryType = OfficeCategoryType.Category;
chart.ChartTitle = "";
chart.ChartArea.Fill.Transparency = 0.5;
IOfficeChartSerie serie= chart.Series.Add(date1);
serie.Values = chart.ChartData[1, 2, 1, 3];
serie.SerieType = OfficeChartType.Column_Stacked;
IOfficeChartSerie serie2 = chart.Series.Add(date2);
serie2.Values = chart.ChartData[2, 2, 2, 3];
serie2.SerieType = OfficeChartType.Column_Stacked;
IOfficeChartSerie serie3 = chart.Series.Add(date3);
serie3.Values = chart.ChartData[3, 2, 3, 3];
serie3.SerieType = OfficeChartType.Column_Stacked;
IOfficeChartSerie serie4 = chart.Series.Add(date4);
serie4.Values = chart.ChartData[4, 2, 4, 3];
serie4.SerieType = OfficeChartType.Column_Stacked;
IOfficeChartSerie serie5 = chart.Series.Add(date5);
serie5.Values = chart.ChartData[5, 2, 5, 3];
serie5.SerieType = OfficeChartType.Column_Stacked;
chart.PlotArea.Layout.ManualLayout.Height = 0.9;
chart.PlotArea.Layout.ManualLayout.Width = 1;
chart.PlotArea.Layout.ManualLayout.Left = 0;
chart.PlotArea.Layout.ManualLayout.Top = 0;
chart.PrimaryCategoryAxis.CategoryLabels = chart.ChartData[1, 1, 5, 1];
chart.Legend.IncludeInLayout = false;
chart.HasLegend = false;
The number of columns in the column-stacked chart depends on the number of categories available in the data range. In your code snippet, there are only two category values. So, two columns are displayed in the column - stacked chart.
Example: serie.Values = chart.ChartData[1, 2, 1, 3];
Here the category values are [ 1, 2 ] and [ 1 , 3 ].
We have also manually created a chart in Microsoft PowerPoint for your scenario (in your code snippet) and attached the created PowerPoint presentation in below link.
http://www.syncfusion.com/downloads/support/directtrac/general/pp/Chart1370190114.pptx
We have also modified your code snippet to display the 5 columns. Please find the code snippet as below.
IPresentationChart chart = slide.Charts.AddChart(150, 100, 300, 125);
chart.ChartType = OfficeChartType.Column_Stacked;
chart.ChartData.SetValue(1, 1, "4355");
chart.ChartData.SetValue(2, 1, "4356");
chart.ChartData.SetValue(3, 1, "4357");
chart.ChartData.SetValue(4, 1, "4358");
chart.ChartData.SetValue(5, 1, "4359");
chart.ChartData.SetValue(1, 2, "6");
chart.ChartData.SetValue(2, 2, "7");
chart.ChartData.SetValue(3, 2, "8");
chart.ChartData.SetValue(4, 2, "9");
chart.ChartData.SetValue(5, 2, "10");
chart.ChartData.SetValue(1, 3, "11");
chart.ChartData.SetValue(2, 3, "12");
chart.ChartData.SetValue(3, 3, "13");
chart.ChartData.SetValue(4, 3, "14");
chart.ChartData.SetValue(5, 3, "15");
//Set data range, Title and category settings
chart.PrimaryCategoryAxis.CategoryType = OfficeCategoryType.Category;
chart.ChartTitle = "";
chart.ChartArea.Fill.Transparency = 0.5;
IOfficeChartSerie serie = chart.Series.Add("date1");
//Selecting data from first row second column to fifth row second column
//ChartData[startRow,startColumn,endRow,endColumn]
serie.Values = chart.ChartData[1, 2, 5, 2]; //Modified the data range to have 5 columns
serie.SerieType = OfficeChartType.Column_Stacked;
IOfficeChartSerie serie2 = chart.Series.Add("date2");
//Selection data from first row third column to fifth row third column
serie2.Values = chart.ChartData[1, 3, 5, 3]; //Modified the data range to have 5 columns
serie2.SerieType = OfficeChartType.Column_Stacked;
chart.PlotArea.Layout.ManualLayout.Height = 0.9;
chart.PlotArea.Layout.ManualLayout.Width = 1;
chart.PlotArea.Layout.ManualLayout.Left = 0;
chart.PlotArea.Layout.ManualLayout.Top = 0;
chart.PrimaryCategoryAxis.CategoryLabels = chart.ChartData[1, 1, 5, 1];
chart.Legend.IncludeInLayout = true;
chart.HasLegend = false;
Output document for the above modified code snippet:
http://www.syncfusion.com/downloads/support/directtrac/general/pp/Output-549061229.pptx
Please let us know if you need further assistance on this,
Note : I work for Syncfusion Software Private Limited
Related
I'm trying to solve a non square linear system with Math.net.
But I get an error Matrix dimensions must agree: 3x7.
Here is some example code:
using MathNet.Numerics.LinearAlgebra;
var mBuilder = Matrix<double>.Build;
var vBuilder = Vector<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
var b = vBuilder.DenseOfArray(new double[] { -3, -5, -2 });
Vector<double> x;
x = A.Solve(b);
Cleary the system has a solution (e.g. X = {0, 0, 0, 0, 3, 5, 2}).
How can I solve such a system with Math.Net?
You can not use the Matrix.Solve function with a non-square matrix because there is no inverse and no unique solutions for a rectangular matrix. Google "inverse of rectangular matrix" for explanations galore. You can use pseudoinverse however, as shown below.
var mBuilder = Matrix<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
Matrix<double> b = Matrix<double>.Build.Dense(3, 1);
b[0, 0] = -3.0;
b[1, 0] = -5.0;
b[2, 0] = -2.0;
var p = A.PseudoInverse();
var x = p * b;
// verify
var o = A * x;
I would like to try adding a dropout layer in my model but I get this error on Train method:
Volume should have a Shape [1] to be converter to a System.Double
What did I do wrong? I would also like to know how to "disable" the dropout layer when I'm not in training (testing).
SgdTrainer trainer;
int numFeatures = 3;
Net<double> net = new Net<double>();
Volume<double> inputVolume, outputVolume;
trainer = new SgdTrainer(net) { LearningRate = 0.0001, BatchSize = 128 };
// 4 test cases with 3 features each
double[] inputData = new double[12] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8 };
// binary classification: 0,1 = is class; 1,0 = not class
double[] outputData = new double[8] { 0, 1, 1, 0, 0, 1, 1, 0 };
net.AddLayer(new InputLayer(1, 1, numFeatures));
net.AddLayer(new FullyConnLayer(10));
net.AddLayer(new ReluLayer());
net.AddLayer(new DropoutLayer(0.5)); // (ಠ_ಠ)
net.AddLayer(new FullyConnLayer(2));
net.AddLayer(new SoftmaxLayer(2));
inputVolume = BuilderInstance.Volume.From(inputData, new Shape(1, 1, numFeatures, inputData.Length / numFeatures));
outputVolume = BuilderInstance.Volume.From(outputData, new Shape(1, 1, 2, outputData.Length / 2));
trainer.Train(inputVolume, outputVolume); // get error if there is dropout above
Volume should have a Shape [1] to be converter to a System.Double
This error was due to a bug recently introduced in ConvNetSharp. It was fixed in PR #133
I would also like to know how to "disable" the dropout layer when I'm not in training
Dropout layer knows when you are training or evaluating the model. It will drop and scale inputs when necessary.
Let's say I have a multidimensional array:
var arr = new double[2, 5, 5]
{
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 }
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 1, 1, 1, 1 }
},
};
I want to copy 3 by 3 part of that array starting from index [1,1,1] till index [1,3,3] (all 2 values).
What is the most efficient way of doing so ? So far, I do it with a loop:
var arr2 = new int[3, 3];
int x_start = 1;
int y_start = 1;
for (int i = 0; i < arr2.GetLength(0); i++)
{
for (int j = 0; j < arr2.GetLength(1); j++)
{
arr2[i, j] = arr[1, x_start + i, y_start + j];
}
}
But I wonder if there is a more efficient way of doing it ?
poke already made the same point in their comment, but this is essentially the best way of doing this.
That’s the most efficient way to do it. You are using fast loops and only loop over those indexes you are interested in. - poke
You could possibly cache the two GetLength() calls in an integer, but I doubt that'd make any meaningful difference in performance.
My test is to solve this following problem:
A zero-indexed array A consisting of N integers is given.
Write a solution to find out the sub array of A, which contains consequent items that has the maximum sum of all its items.
Example:
A = [2, -1, 3, -3, 4, -9, 10, -3, 4, -4, -7, 2, 8]. The answer is [10, -3, 4]
A = [3, 2, -5, 7, 4, -8, 3, -5, 2, 4, -2, 4]. The answer is [7, 4]
A = [-2, 5, 3, 6, -1,-5]. The answer is [-2, 5, 3, 6].
Please help me to give me the way to resolve it.
Basicly, what you need to do is to traverse the array and check for the maximum value of the sum of elements. Once you have found the max sum, you have the last element of your resulting subarray.
Once you have found the max element, you need to traverse back and do the same in order to find the sub array with maximum sum of elements.
int iNewTopHigh = 0;
int iNewTopLow = 0;
int iIndNewTopHigh = 0;
int iIndNewTopLow = 0;
int iSumHigh = 0;
int iSumLow = 0;
int[] iArr = {2, -1, 3, -3, 4, -9, 10, -3, 4, -4, -7, 2, 8};
//{3, 2, -5, 7, 4, -8, 3, -5, 2, 4, -2, 4};
//{-2, 5, 3, 6, -1,-5};
//Get the top
for(int i = 0; i < iArr.Length; i++){
iSumHigh += iArr[i];
if(iSumHigh > iNewTopHigh){
iIndNewTopHigh = i;
iNewTopHigh = iSumHigh;
}
}
//Get the bottom
for(int i = iIndNewTopHigh; i != 0; i--){
iSumLow += iArr[i];
if(iSumLow > iNewTopLow){
iIndNewTopLow = i;
iNewTopLow = iSumLow;
}
}
//Print results
for(int i = iIndNewTopLow ; i <= iIndNewTopHigh; i++){
Console.Write(iArr[i] + ", ");
}
Requirements:
Integer operations only (no floats)
Elements are interlocked at intervals as evenly as possible
Note:
"Intervals as evenly as possible" can be defined as having each length of intervals as close to one value as possible.
Micro-optimizations are welcome and desired.
Example inputs and outputs:
//Inputs
[ 1, 2, 3, 4, 5, 6, 7 ]
[ 10, 20, 30, 40 ]
//Correct output
[ 1, 10, 2, 20, 3, 30, 4, 5, 40, 6, 7]
//Wrong output ([5, 6, 7] is not an optimal interval)
[ 1, 10, 2, 20, 3, 30, 4, 40, 5, 6, 7]
-
//Inputs
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[ 2, 2, 2 ]
//Correct output
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 1, 1]
//Wrong output (last [1] is not an optimal interval)
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 1, 3, 1]
Here's my own implementation with as much optimization as I can think of for a managed language. In C++, it may be faster to use a triple XOR swap for the array pointers, but I'm not sure. It may be necessary to look at the JITed assembly to further optimize this particular code.
In the meantime, let's see if other people have better algorithms.
int[] InterlockMerge(int[] a1, int[] a2) {
var longSet = a1;
var shortSet = a2;
//Swap if a2 is longer
if (a1.Length < a2.Length){
longSet = a2;
shortSet = a1;
}
var ll = longSet.Length;
var ls = shortSet.Length;
var totalLength = ll + ls;
int[] res = new int[totalLength]; //The resulting set
int l = ll / (ls + 1); //Initial testing ratio (an int)
int li = 0; //index for longSet
int si = 0; //index for shortSet
for (int i = 0; i < totalLength; i++) {
if (l > 0) {
res[i] = longSet[li++];
l--;
continue;
}
res[i] = shortSet[si++];
l = (ll - li) / (ls - si + 1); //Recalculate the testing ratio
}
return res;
}