/// <summary> /// Plot the given scatterplot on screen. /// </summary> /// <param name="plot">The scatterplot to plot</param> private static void Plot(Scatterplot plot) { var box = ScatterplotBox.Show(plot); var callback = new Action(() => { box.SetLinesVisible(true); box.SetSymbolSize(0); box.SetScaleTight(true); }); System.Threading.Thread.Sleep(100); box.Invoke(callback); }
/// <summary> /// Plot the training errors. /// </summary> /// <param name="trainingErrors">The traininer errors to plot</param> /// <param name="title">The chart title</param> /// <param name="xAxisLabel">The chart x-ais label</param> /// <param name="yAxisLabel">The chart y-axis label</param> private static void Plot( List <double> trainingErrors, string title, string xAxisLabel, string yAxisLabel) { var epochs = trainingErrors.Count(); var x = Enumerable.Range(0, epochs).Select(v => (double)v).ToArray(); var y = trainingErrors.ToArray(); var plot = new Scatterplot(title, xAxisLabel, yAxisLabel); plot.Compute(x, y); ScatterplotBox.Show(plot); }
private void cmdRocCurve_Click(object sender, EventArgs e) { if (_scatterplot != null) { ScatterplotBox.Show(_scatterplot) .SetSymbolSize(0) .SetLinesVisible(true) .SetScaleTight(true) .WaitForClose(); } else { MessageBox.Show("Run benchmart first!"); } }
private static void and() { // Create a simple binary AND // classification problem: double[][] problem = { // a b a + b new double[] { 0, 0, 0 }, new double[] { 0, 1, 0 }, new double[] { 1, 0, 0 }, new double[] { 1, 1, 1 }, }; // Get the two first columns as the problem // inputs and the last column as the output // input columns double[][] inputs = problem.GetColumns(0, 1); // output column int[] outputs = problem.GetColumn(2).ToInt32(); // Plot the problem on screen ScatterplotBox.Show("AND", inputs, outputs).Hold(); // Create a L2-regularized L2-loss support vector classification algorithm var teacher = new LinearDualCoordinateDescent() { Loss = Loss.L2, Complexity = 1000, Tolerance = 1e-5 }; // Use the algorithm to learn the machine var svm = teacher.Learn(inputs, outputs); // Compute the machine's answers for the learned inputs bool[] answers = svm.Decide(inputs); // Convert to Int32 so we can plot: int[] zeroOneAnswers = answers.ToZeroOne(); // Plot the results ScatterplotBox.Show("SVM's answer", inputs, zeroOneAnswers) .Hold(); }
public static void Excute() { double[][] inputs = { /* 1.*/ new double[] { 0, 0 }, /* 2.*/ new double[] { 1, 0 }, /* 3.*/ new double[] { 0, 1 }, /* 4.*/ new double[] { 1, 1 }, }; double[][] inputs2 = { /* 1.*/ new double[] { 0, 0 }, /* 2.*/ new double[] { 1, 0 }, /* 3.*/ new double[] { 1, 1 }, /* 4.*/ new double[] { 1, 1 }, }; int[] outputs = { /* 1. 0 xor 0 = 0: */ 0, /* 2. 1 xor 0 = 1: */ 1, /* 3. 0 xor 1 = 1: */ 1, /* 4. 1 xor 1 = 0: */ 0, }; // Create the learning algorithm with the chosen kernel var smo = new SequentialMinimalOptimization <Gaussian>() { Complexity = 100 // Create a hard-margin SVM }; // Use the algorithm to learn the svm var svm = smo.Learn(inputs, outputs); // Compute the machine's answers for the given inputs bool[] prediction = svm.Decide(inputs2); // Compute the classification error between the expected // values and the values actually predicted by the machine: double error = new AccuracyLoss(outputs).Loss(prediction); Console.WriteLine("Error: " + error); // Show results on screen ScatterplotBox.Show("Training data", inputs, outputs); ScatterplotBox.Show("SVM results", inputs, prediction.ToZeroOne()); Console.ReadKey(); }
/// <summary> /// Plot a histogram. /// </summary> /// <param name="histogram">The histogram to plot</param> /// <param name="title">The plot title</param> /// <param name="xAxisLabel">The x-axis label</param> /// <param name="yAxisLabel">The y-axis label</param> private static void Plot(Histogram histogram, string title, string xAxisLabel, string yAxisLabel) { var x = new List <double>(); var y = new List <double>(); for (int i = 0; i < histogram.Values.Length; i++) { var xcor = histogram.Bins[i].Range.Min; x.AddRange(from n in Enumerable.Range(0, histogram.Values[i]) select xcor); y.AddRange(from n in Enumerable.Range(0, histogram.Values[i]) select n * 1.0); } var plot = new Scatterplot(title, xAxisLabel, yAxisLabel); plot.Compute(x.ToArray(), y.ToArray()); ScatterplotBox.Show(plot); }
/// <summary> /// Plot a graph on screen. /// </summary> /// <param name="xSeries">The x-series to plot</param> /// <param name="ySeries">The y-series to plot</param> /// <param name="title">The plot title</param> /// <param name="xAxisLabel">The x-axis label</param> /// <param name="yAxisLabel">The y-axis label</param> public static void Plot( Series <int, double> xSeries, Series <int, double> ySeries, string title, string xAxisLabel, string yAxisLabel) { // generate plot arrays var x = xSeries.Values.ToArray(); var y = ySeries.Values.ToArray(); // plot the graph var plot = new Scatterplot(title, xAxisLabel, yAxisLabel); plot.Compute(x, y); ScatterplotBox.Show(plot); }
public static void Main(string[] args) { var scoreFileName = CommonUtils.GetTrainingFile("東京電機大学校歌.ust"); var startState = CreateHmm(scoreFileName); //OutputGraphs(startState.Model); var plots = new List <(int x, int y)>(); var tracker = new SingingPositionTracker(startState); var prevNoteIndex = -1; var observationIndex = 0; var audioFileName = CommonUtils.GetTrainingFile("校歌 2018-01-17 15-10-46.wav"); foreach (var observation in ToObservations(LoadAudioFile(audioFileName, false))) { tracker.InputObservation(observation); var note = tracker.CurrentNote; var currentNoteIndex = note?.Index ?? -1; if (currentNoteIndex != prevNoteIndex) { Console.ForegroundColor = ConsoleColor.Red; if (note != null) { Console.WriteLine("位置 {0} -> {1} ({2}, {3})", prevNoteIndex, currentNoteIndex, CommonUtils.ToNoteName(note.NoteNumber % 12), note.Lyric); } else { Console.WriteLine("位置 {0} -> {1}", prevNoteIndex, currentNoteIndex); } Console.ResetColor(); plots.Add((observationIndex, currentNoteIndex)); prevNoteIndex = currentNoteIndex; } observationIndex++; } ScatterplotBox.Show("NoteIndex", plots.Select(t => (double)t.x).ToArray(), plots.Select(t => (double)t.y).ToArray()).Hold(); //ScatterplotBox.Show("Position", plots.Select(t => (double)t.x).ToArray(), plots.Select(t => (double)matcher.Score[t.y].Position).ToArray()); }
private static void network(double[][] inputs, int[] outputs) { // Since we would like to learn binary outputs in the form // [-1,+1], we can use a bipolar sigmoid activation function IActivationFunction function = new BipolarSigmoidFunction(); // In our problem, we have 2 inputs (x, y pairs), and we will // be creating a network with 5 hidden neurons and 1 output: // var network = new ActivationNetwork(function, inputsCount: 2, neuronsCount: new[] { 5, 1 }); // Create a Levenberg-Marquardt algorithm var teacher = new LevenbergMarquardtLearning(network) { UseRegularization = true }; // Because the network is expecting multiple outputs, // we have to convert our single variable into arrays // var y = outputs.ToDouble().ToJagged(); // Iterate until stop criteria is met double error = double.PositiveInfinity; double previous; do { previous = error; // Compute one learning iteration error = teacher.RunEpoch(inputs, y); } while (Math.Abs(previous - error) < 1e-10 * previous); // Classify the samples using the model int[] answers = inputs.Apply(network.Compute).GetColumn(0).Apply(System.Math.Sign); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Network results", inputs, answers) .Hold(); }
private void btnRun_Click(object sender, EventArgs e) { ds = new DataSet(); if (fileName.Contains(".xls") || fileName.Contains(".xlsx")) { ds = excelTrackle.LoadDataFromExcel(fileName, "Sheet1"); } else if (fileName.Contains(".txt") || fileName.Contains(".dat")) { ds.Tables.Add(excelTrackle.LoadDataFromText(fileName)); } //for (int ti = 0; ti < ds.Tables.Count; ti++) // for (int i = 0; i < ds.Tables[ti].Rows.Count; i++) // { // for (int j = 0; j < ds.Tables[ti].Columns.Count; j++) // Console.Write(ds.Tables[ti].Rows[i][j].ToString() + "\t"); // Console.Write("\n"); // } double[][] data = new double[ds.Tables[0].Rows.Count - 1][]; for (int i = 0; i < data.Length; i++) { data[i] = new double[2] { Convert.ToDouble(ds.Tables[0].Rows[i + 1][2]), Convert.ToDouble(ds.Tables[0].Rows[i + 1][3]) }; } KMeans kmean = new KMeans(2); int[] result = kmean.Compute(data); ds.Tables.Add(); ds.Tables[1].Columns.Add("depth", Type.GetType("System.Double")); ds.Tables[1].Columns.Add("lith1", Type.GetType("System.Int32")); DataRow dr = ds.Tables[1].NewRow(); for (int i = 0; i < result.Length; i++) { dr = ds.Tables[1].NewRow(); dr["depth"] = ds.Tables[0].Rows[i + 1][0]; dr["lith1"] = result[i]; ds.Tables[1].Rows.Add(dr); } Console.WriteLine("log interpretion is OK"); ScatterplotBox.Show("lith", data, result); btnSave.Enabled = true; }
private static void kmeans(double[][] inputs) { // Create a 3-Means algorithm var kmeans = new KMeans(k: 3) { Distance = new SquareEuclidean(), MaxIterations = 1000 }; // Use it to learn a data model var model = kmeans.Learn(inputs); // Use the model to group new instances int[] prediction = model.Decide(inputs); // Plot the results ScatterplotBox.Show("KMeans's answer", inputs, prediction).Hold(); }
public void PlotValidationCurve(IEnumerable <double> errors, int epochCount) { double[] x = Enumerable .Range(1, epochCount) .Select(v => (double)v) .ToArray(); double[] y = errors.ToArray(); Scatterplot plot = new Scatterplot( "График изменения квадратичной ошибки тестирования", TrainingPlotResources.YAxisTitle, "Ошибки тестирования"); plot.Compute(x, y); ScatterplotBox.Show(plot); }
public void PlotTrainingCurve(IEnumerable <double> errors, int epochCount) { double[] x = Enumerable .Range(1, epochCount) .Select(v => (double)v) .ToArray(); double[] y = errors.ToArray(); Scatterplot plot = new Scatterplot( TrainingPlotResources.Title, TrainingPlotResources.YAxisTitle, TrainingPlotResources.XAxisTitle); plot.Compute(x, y); ScatterplotBox.Show(plot); }
private static void binarySplit(double[][] inputs) { // Create a binary-split algorithm var binarySplit = new BinarySplit(k: 3) { Distance = new SquareEuclidean(), MaxIterations = 1000 }; // Use it to learn a data model var model = binarySplit.Learn(inputs); // Use the model to group new instances int[] prediction = model.Decide(inputs); // Plot the results ScatterplotBox.Show("Binary Split's answer", inputs, prediction).Hold(); }
private void PrintRandomDigit(Frame <int, string> training) { Console.WriteLine(@"Вывод случайного тренировочного образца..."); Random rnd = new Random(); int row = rnd.Next(1, training.RowCount); string randomDigit = training.Rows[row]["Column1"].ToString(); double[] x = Enumerable.Range(0, 784).Select(v => (double)(v % 28)).ToArray(); double[] y = Enumerable.Range(0, 784).Select(v => (double)(-v / 28)).ToArray(); int[] z = Enumerable.Range(2, 784) .Select(i => new { i, v = training.Rows[row][$"Column{i}"] as double? }) .Select(t => t.v > 0.5 ? 1 : 0).ToArray(); Scatterplot plot = new Scatterplot($"Цифра {randomDigit}", "x", "y"); plot.Compute(x, y, z); ScatterplotBox.Show(plot); }
public void ScatterplotBox_ShowTest1() { double[,] points = { { 1, 1 }, { 1, 4 }, { 4, 1 }, { 4, 4 }, }; ScatterplotBox.Show(points).Hold(); int[] classes = { 0, 1, 0, 1, }; ScatterplotBox.Show(points, classes).Hold(); }
private static void meanShift(double[][] inputs) { // Create a mean-shfit algorithm var kmeans = new MeanShift() { Bandwidth = 0.1, Kernel = new EpanechnikovKernel(), Distance = new Euclidean(), MaxIterations = 1000 }; // Use it to learn a data model var model = kmeans.Learn(inputs); // Use the model to group new instances int[] prediction = model.Decide(inputs); // Plot the results ScatterplotBox.Show("Mean-Shift's answer", inputs, prediction).Hold(); }
private static void gmm(double[][] inputs) { var gmm = new GaussianMixtureModel(components: 3) { Tolerance = 1e-6 }; var model = gmm.Learn(inputs); int[] prediction = model.Decide(inputs); double[][] prob = model.Probabilities(inputs); // Compute the clustering distortion double distortion = model.Distortion(inputs, prediction); // Plot the results ScatterplotBox.Show("Free GMM's answer", inputs, prediction) .Hold(); }
private static void decisionTree(double[][] inputs, int[] outputs) { // In our problem, we have 2 classes (samples can be either // positive or negative), and 2 continuous-valued inputs. C45Learning teacher = new C45Learning(new[] { DecisionVariable.Continuous("X"), DecisionVariable.Continuous("Y") }); // Use the learning algorithm to induce the tree DecisionTree tree = teacher.Learn(inputs, outputs); // Classify the samples using the model int[] answers = tree.Decide(inputs); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Decision Tree results", inputs, answers) .Hold(); }
private static void ValidateModelResults(string modelName, double[] regInSamplePreds, double[] regOutSamplePreds, double[][] trainX, double[] trainY, double[][] testX, double[] testY) { // RMSE for in-sample double regInSampleRMSE = Math.Sqrt(new SquareLoss(trainX).Loss(regInSamplePreds)); // RMSE for out-sample double regOutSampleRMSE = Math.Sqrt(new SquareLoss(testX).Loss(regOutSamplePreds)); Console.WriteLine("RMSE: {0:0.0000} (Train) vs. {1:0.0000} (Test)", regInSampleRMSE, regOutSampleRMSE); // R^2 for in-sample double regInSampleR2 = new RSquaredLoss(trainX[0].Length, trainX).Loss(regInSamplePreds); // R^2 for out-sample double regOutSampleR2 = new RSquaredLoss(testX[0].Length, testX).Loss(regOutSamplePreds); Console.WriteLine("R^2: {0:0.0000} (Train) vs. {1:0.0000} (Test)", regInSampleR2, regOutSampleR2); // Scatter Plot of expected and actual ScatterplotBox.Show( String.Format("Actual vs. Prediction ({0})", modelName), testY, regOutSamplePreds ); }
private static void gmmSharedCovariances(double[][] inputs) { var gmm = new GaussianMixtureModel(components: 3) { Tolerance = 1e-6, Options = new NormalOptions() { Shared = true } }; var model = gmm.Learn(inputs); int[] prediction = model.Decide(inputs); // Compute the clustering distortion double distortion = model.Distortion(inputs, prediction); // Plot the results ScatterplotBox.Show("Shared GMM's answer", inputs, prediction) .Hold(); }
private void BtnSvmKernal_Click(object sender, EventArgs e) { // Create a new Sequential Minimal Optimization (SMO) learning // algorithm and estimate the complexity parameter C from data var teacher = new SequentialMinimalOptimization <Gaussian>() { UseComplexityHeuristic = true, UseKernelEstimation = true // estimate the kernel from the data }; // Teach the vector machine var svm = teacher.Learn(_inputs, _outputs); // Classify the samples using the model bool[] answers = svm.Decide(_inputs); // Convert to Int32 so we can plot: int[] zeroOneAnswers = answers.ToZeroOne(); // Plot the results ScatterplotBox.Show("Expected results", _inputs, _outputs); ScatterplotBox.Show("GaussianSVM results", _inputs, zeroOneAnswers); }
/// <summary> /// Plot a graph on screen. /// </summary> /// <param name="feature">The features to plot</param> /// <param name="labels">The labels to plot</param> /// <param name="predictions">The predictions to plot</param> /// <param name="title">The plot title</param> /// <param name="xAxisLabel">The x-axis label</param> /// <param name="yAxisLabel">The y-axis label</param> public static void Plot( double[] feature, double[] labels, double[] predictions, string title, string xAxisLabel, string yAxisLabel) { // generate plot arrays var x = feature.Concat(feature).ToArray(); var y = predictions.Concat(labels).ToArray(); // set up color arrays var colors1 = Enumerable.Repeat(1, labels.Length).ToArray(); var colors2 = Enumerable.Repeat(2, labels.Length).ToArray(); var c = colors1.Concat(colors2).ToArray(); // plot the graph var plot = new Scatterplot(title, xAxisLabel, yAxisLabel); plot.Compute(x, y, c); ScatterplotBox.Show(plot); }
private static void logisticRegression(double[][] inputs, int[] outputs) { // Create iterative re-weighted least squares for logistic regressions var teacher = new IterativeReweightedLeastSquares <LogisticRegression>() { MaxIterations = 100, Regularization = 1e-6 }; // Use the teacher algorithm to learn the regression: LogisticRegression lr = teacher.Learn(inputs, outputs); // Classify the samples using the model bool[] answers = lr.Decide(inputs); // Convert to Int32 so we can plot: int[] zeroOneAnswers = answers.ToZeroOne(); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Logistic Regression results", inputs, zeroOneAnswers) .Hold(); }
static void Main(string[] args) { CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US"); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US"); List <Wine> wines; using (var stream = new StreamReader(".\\winequality-red.csv")) using (var helper = new CsvHelper.CsvReader(stream)) { helper.Configuration.RegisterClassMap <WineMap>(); wines = helper.GetRecords <Wine>().ToList(); } var testingSet = wines.Take(400).ToList(); var trainingSet = wines.Skip(400).ToList(); double[] result = LinearRegression(testingSet, trainingSet); decimal good = result.Zip(testingSet, (x, y) => Math.Abs(x - y.Quality) <= 0.2).Where(x => x).Count(); decimal all = 400; Debug.WriteLine($"Correctness: {good / all}"); ScatterplotBox.Show("Expected results", result.Select(x => (double)x).ToArray(), testingSet.Select(x => (double)x.Quality).ToArray()).Hold(); }
static void Main(string[] args) { double[][] inputs = { /* 1. */ new double[] { 0, 0 }, /* 2. */ new double[] { 1, 0 }, /* 3. */ new double[] { 0, 1 }, /* 4. */ new double[] { 1, 1 } }; int[] outputs = { /* 1. 0 xor 0 = 0: */ 1, /* 2. 1 xor 0 = 1: */ 0, /* 3. 0 xor 1 = 1: */ 0, /* 4. 1 xor 1 = 0: */ 0, }; var smo = new SequentialMinimalOptimization <Gaussian>() { Complexity = 100 }; var svm = smo.Learn(inputs, outputs); bool[] prediction = svm.Decide(inputs); double error = new AccuracyLoss(outputs).Loss(prediction); Console.WriteLine("Error: " + error); ScatterplotBox.Show("Training data", inputs, outputs); ScatterplotBox.Show("SVM results", inputs, prediction.ToZeroOne()); Console.ReadKey(); }
private static void naiveBayes(double[][] inputs, int[] outputs) { // In our problem, we have 2 classes (samples can be either // positive or negative), and 2 inputs (x and y coordinates). // Create a Naive Bayes learning algorithm var teacher = new NaiveBayesLearning <NormalDistribution>(); // Use the learning algorithm to learn var nb = teacher.Learn(inputs, outputs); // At this point, the learning algorithm should have // figured important details about the problem itself: int numberOfClasses = nb.NumberOfClasses; // should be 2 (positive or negative) int nunmberOfInputs = nb.NumberOfInputs; // should be 2 (x and y coordinates) // Classify the samples using the model int[] answers = nb.Decide(inputs); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Naive Bayes results", inputs, answers) .Hold(); }
private static void naiveBayes(double[][] inputs, int[] outputs) { // In our problem, we have 2 classes (samples can be either // positive or negative), and 2 inputs (x and y coordinates). var nb = new NaiveBayes <NormalDistribution>(classes: 2, inputs: 2, initial: new NormalDistribution()); // The Naive Bayes expects the class labels to // range from 0 to k, so we convert -1 to be 0: // outputs = outputs.Apply(x => x < 0 ? 0 : x); // Estimate the Naive Bayes double error = nb.Estimate(inputs, outputs); // Classify the samples using the model int[] answers = inputs.Apply(nb.Compute); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Naive Bayes results", inputs, answers) .Hold(); }
private static void logistic(double[][] inputs, int[] outputs) { // In our problem, we have 2 inputs (x, y pairs) var logistic = new LogisticRegression(inputs: 2); // Create a iterative re-weighted least squares algorithm var teacher = new IterativeReweightedLeastSquares(logistic); // Logistic Regression expects the output labels // to range from 0 to k, so we convert -1 to be 0: // outputs = outputs.Apply(x => x < 0 ? 0 : x); // Iterate until stop criteria is met double error = double.PositiveInfinity; double previous; do { previous = error; // Compute one learning iteration error = teacher.Run(inputs, outputs); } while (Math.Abs(previous - error) < 1e-10 * previous); // Classify the samples using the model int[] answers = inputs.Apply(logistic.Compute).Apply(Math.Round).ToInt32(); // Plot the results ScatterplotBox.Show("Expected results", inputs, outputs); ScatterplotBox.Show("Logistic Regression results", inputs, answers) .Hold(); }
public static void BuildDecisionTreeOnYearAndUser() { DataHandler.ImportReviewData(5); DataHandler.Reviews.Shuffle(); DataTable data = new DataTable("Review Simple Input Data"); data.Columns.Add("Year"); data.Columns.Add("User"); data.Columns.Add("Review"); for (int i = 0; i < 1500; i++) { var currentReview = DataHandler.Reviews[i]; object[] values = new object[3]; values[0] = currentReview.reviewTime.Year; values[1] = currentReview.reviewerID; values[2] = currentReview.overall; data.Rows.Add(values); } // Create a new codification codebook to // convert strings into integer symbols var codebook = new Codification(data, "Year", "User", "Review"); DataTable symbols = codebook.Apply(data, "Year", "User", "Review"); int[][] inputs = symbols.ToJagged <int>("Year", "User"); int[] outputs = symbols.ToArray <int>("Review"); // Gather information about decision variables DecisionVariable[] attributes = { new DecisionVariable("Year", 7), // 3 years new DecisionVariable("User", 18), // 18 possible users }; // Create a new instance of the ID3 algorithm var id3learning = new ID3Learning(attributes); // Learn the training instances! DecisionTree tree = id3learning.Learn(inputs, outputs); // Compute the training error when predicting training instances double error = new ZeroOneLoss(outputs).Loss(tree.Decide(inputs)); // The tree can now be queried for new examples through // its decide method. For example, we can create a query DataTable newData = new DataTable("Review Simple Input Data"); newData.Columns.Add("Year"); newData.Columns.Add("User"); newData.Columns.Add("Review"); for (int i = 1500; i < 2000; i++) { var currentReview = DataHandler.Reviews[i]; object[] values = new object[3]; values[0] = currentReview.reviewTime.Year; values[1] = currentReview.reviewerID; values[2] = currentReview.overall; newData.Rows.Add(values); } DataTable newSymbols = codebook.Apply(data, "Year", "User", "Review"); int[][] newInputs = newSymbols.ToJagged <int>("Year", "User"); int[] newOutputs = newSymbols.ToArray <int>("Review"); int[] answers = tree.Decide(newInputs); ScatterplotBox.Show("Expected results", newOutputs.Select(i => (double)i).ToArray()); ScatterplotBox.Show("Decision Tree results", newOutputs.Select(i => (double)i).ToArray()) .Hold(); }