/// <summary> /// Create a model from the training data, has to be called before predicting /// </summary> /// <param name="paramater">The SvmParameter is converted to OneClass type</param> /// <returns>returns true if the model was created correctly</returns> public bool CreateModel(SVMParameter parameter) { parameter.Type = SVMType.ONE_CLASS; try { _model = _trainingData.Train(parameter); return true; } catch { return false; } }
public static void Free(IntPtr ptr) { if (ptr == IntPtr.Zero) { return; } svm_model x = (svm_model)Marshal.PtrToStructure(ptr, typeof(svm_model)); SVMModel.Free(x); Marshal.DestroyStructure(ptr, typeof(svm_model)); Marshal.FreeHGlobal(ptr); ptr = IntPtr.Zero; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="filename"></param> /// <returns></returns> public static bool SaveModel(SVMModel model, string filename) { if (String.IsNullOrWhiteSpace(filename) || model == null) { return(false); } IntPtr ptr_model = SVMModel.Allocate(model); IntPtr ptr_filename = Marshal.StringToHGlobalAnsi(filename); bool success = libsvm.svm_save_model(ptr_filename, ptr_model) == 0; Marshal.FreeHGlobal(ptr_filename); ptr_filename = IntPtr.Zero; return(success); }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="x"></param> /// <param name="estimations"></param> /// <returns></returns> public static double PredictProbability(SVMModel model, SVMNode[] x, out double[] estimations) { if (model == null) { throw new ArgumentNullException("model"); } if (x == null) { throw new ArgumentNullException("x"); } IntPtr ptr_model = SVMModel.Allocate(model); double result = PredictProbability(ptr_model, x, out estimations); SVMModel.Free(ptr_model); return(result); }
/// <summary> /// This function does classification or regression on a test vector x given a model. /// </summary> /// <param name="model">SVM model.</param> /// <param name="x">Test vector.</param> /// <returns>For a classification model, the predicted class for x is returned. /// For a regression model, the function value of x calculated using the model is returned. /// For an one-class model, +1 or -1 is returned.</returns> public static double Predict(SVMModel model, SVMNode[] x) { if (model == null) { throw new ArgumentNullException("model"); } if (x == null) { throw new ArgumentNullException("x"); } IntPtr ptr_model = SVMModel.Allocate(model); double result = Predict(ptr_model, x); SVMModel.Free(ptr_model); return(result); }
/// <summary> /// /// </summary> /// <param name="ptr_model"></param> /// <param name="x"></param> /// <param name="estimations"></param> /// <returns></returns> public static double PredictProbability(IntPtr ptr_model, SVMNode[] x, out double[] estimations) { if (ptr_model == IntPtr.Zero) { throw new ArgumentNullException("ptr_model"); } if (x == null) { throw new ArgumentNullException("x"); } bool isProbabilityModel = libsvm.svm_check_probability_model(ptr_model); if (!isProbabilityModel) { SVMModel.Free(ptr_model); estimations = null; return(-1); } int classCount = libsvm.svm_get_nr_class(ptr_model); IntPtr ptr_estimations = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * classCount); List <SVMNode> nodes = x.Select(a => a.Clone()).ToList(); nodes.Add(new SVMNode(-1, 0)); IntPtr ptr_nodes = SVMNode.Allocate(nodes.ToArray()); double result = libsvm.svm_predict_probability(ptr_model, ptr_nodes, ptr_estimations); estimations = new double[classCount]; Marshal.Copy(ptr_estimations, estimations, 0, estimations.Length); SVMNode.Free(ptr_nodes); Marshal.FreeHGlobal(ptr_estimations); ptr_estimations = IntPtr.Zero; return(result); }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="x"></param> /// <param name="values"></param> /// <returns></returns> public static double PredictValues(SVMModel model, SVMNode[] x, out double[] values) { int size = (int)(model.ClassCount * (model.ClassCount - 1) * 0.5); IntPtr ptr_values = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * size); IntPtr ptr_model = SVMModel.Allocate(model); List <SVMNode> nodes = x.Select(a => a.Clone()).ToList(); nodes.Add(new SVMNode(-1, 0)); IntPtr ptr_nodes = SVMNode.Allocate(nodes.ToArray()); double result = libsvm.svm_predict_values(ptr_model, ptr_nodes, ptr_values); values = new double[size]; Marshal.Copy(ptr_values, values, 0, values.Length); SVMModel.Free(ptr_model); SVMNode.Free(ptr_nodes); Marshal.FreeHGlobal(ptr_values); ptr_values = IntPtr.Zero; return(result); }
public SVMModel Clone() { SVMModel y = new SVMModel(); if (Parameter != null) y.Parameter = Parameter.Clone(); y.ClassCount = ClassCount; y.TotalSVCount = TotalSVCount; if (SV != null) y.SV = SV.Select(a => a.Select(b => b.Clone()).ToArray()).ToList(); if (SVCoefs != null) y.SVCoefs = SVCoefs.Select(a => a.Select(b => b).ToArray()).ToList(); if (Rho != null) y.Rho = Rho.Select(a => a).ToArray(); if (ProbabilityA != null) y.ProbabilityA = ProbabilityA.Select(a => a).ToArray(); if (ProbabilityB != null) y.ProbabilityB = ProbabilityB.Select(a => a).ToArray(); if (SVIndices != null) y.SVIndices = SVIndices.Select(a => a).ToArray(); if (Labels != null) y.Labels = Labels.Select(a => a).ToArray(); if (SVCounts != null) y.SVCounts = SVCounts.Select(a => a).ToArray(); y.Creation = Creation; return y; }
/// <summary> /// This function constructs and returns an SVM model according to the given training data and parameters. /// </summary> /// <param name="problem">Training data.</param> /// <param name="parameter">Parameter set.</param> /// <returns>SVM model according to the given training data and parameters.</returns> public static SVMModel Train(SVMProblem problem, SVMParameter parameter) { if (problem == null) { throw new ArgumentNullException("problem"); } if (parameter == null) { throw new ArgumentNullException("parameter"); } IntPtr ptr_problem = SVMProblem.Allocate(problem); IntPtr ptr_parameter = SVMParameter.Allocate(parameter); IntPtr ptr_model = libsvm.svm_train(ptr_problem, ptr_parameter); SVMModel model = SVMModel.Convert(ptr_model); SVMProblem.Free(ptr_problem); SVMParameter.Free(ptr_parameter); libsvm.svm_free_model_content(ptr_model); return(model); }
public static IntPtr Allocate(SVMModel x) { if (x == null || x.ClassCount < 1 || x.Parameter == null || x.Rho == null || x.Rho.Length < 1 || x.SVCoefs == null || x.SVCoefs.Count < 1 || x.TotalSVCount < 1) { return IntPtr.Zero; } if (x.Parameter.Type != SVMType.EPSILON_SVR && x.Parameter.Type != SVMType.NU_SVR && x.Parameter.Type != SVMType.ONE_CLASS && (x.Labels == null || x.Labels.Length < 1 || x.SVCounts == null || x.SVCounts.Length < 1)) { return IntPtr.Zero; } svm_model y = new svm_model(); y.nr_class = x.ClassCount; y.l = x.TotalSVCount; y.free_sv = (int)x.Creation; // Allocate model.parameter IntPtr ptr_param = SVMParameter.Allocate(x.Parameter); y.param = (svm_parameter)Marshal.PtrToStructure(ptr_param, typeof(svm_parameter)); SVMParameter.Free(ptr_param); // Allocate model.rho y.rho = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.Rho.Length); Marshal.Copy(x.Rho, 0, y.rho, x.Rho.Length); // Allocate model.probA y.probA = IntPtr.Zero; if (x.ProbabilityA != null) { y.probA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.ProbabilityA.Length); Marshal.Copy(x.ProbabilityA, 0, y.probA, x.ProbabilityA.Length); } // Allocate model.probB y.probB = IntPtr.Zero; if (x.ProbabilityB != null) { y.probB = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.ProbabilityB.Length); Marshal.Copy(x.ProbabilityB, 0, y.probB, x.ProbabilityB.Length); } if (x.Parameter.Type != SVMType.EPSILON_SVR && x.Parameter.Type != SVMType.NU_SVR && x.Parameter.Type != SVMType.ONE_CLASS) { // Allocate model.label y.label = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (int))*x.Labels.Length); Marshal.Copy(x.Labels, 0, y.label, x.Labels.Length); // Allocate model.nSV y.nSV = Marshal.AllocHGlobal(Marshal.SizeOf(typeof (int))*x.SVCounts.Length); Marshal.Copy(x.SVCounts, 0, y.nSV, x.SVCounts.Length); } else { y.label = IntPtr.Zero; y.nSV = IntPtr.Zero; } // Allocate model.sv_coef y.sv_coef = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * x.SVCoefs.Count); IntPtr i_ptr_svcoef = y.sv_coef; for (int i = 0; i < x.SVCoefs.Count; i++) { IntPtr temp = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.SVCoefs[i].Length); Marshal.Copy(x.SVCoefs[i], 0, temp, x.SVCoefs[i].Length); Marshal.StructureToPtr(temp, i_ptr_svcoef, true); i_ptr_svcoef = IntPtr.Add(i_ptr_svcoef, Marshal.SizeOf(typeof(IntPtr))); } // Allocate model.sv_indices y.sv_indices = IntPtr.Zero; if (x.SVIndices != null) { y.sv_indices = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * x.SVIndices.Length); Marshal.Copy(x.SVIndices, 0, y.sv_indices, x.SVIndices.Length); } // Allocate model.SV y.SV = IntPtr.Zero; if (x.SV != null) { y.SV = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * x.SV.Count); IntPtr i_ptr_sv = y.SV; for (int i = 0; i < x.SV.Count; i++) { // Prepare each node array // 1) All nodes containing zero value is removed // 2) A node which index is -1 is added to the end List<SVMNode> temp = x.SV[i].Where(a => a.Value != 0).ToList(); temp.Add(new SVMNode(-1, 0)); SVMNode[] nodes = temp.ToArray(); // Allocate node array IntPtr ptr_nodes = SVMNode.Allocate(nodes); Marshal.StructureToPtr(ptr_nodes, i_ptr_sv, true); i_ptr_sv = IntPtr.Add(i_ptr_sv, Marshal.SizeOf(typeof(IntPtr))); } } // Allocate the model int size = Marshal.SizeOf(y); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(y, ptr, true); return ptr; }
public static SVMModel Convert(svm_model x) { SVMModel y = new SVMModel(); y.Creation = (CreationType)x.free_sv; y.ClassCount = x.nr_class; y.TotalSVCount = x.l; if (y.Creation == CreationType.LOAD_MODEL) { y.Parameter = new SVMParameter(); y.Parameter.Type = (SVMType)x.param.svm_type; y.Parameter.Kernel = (SVMKernelType)x.param.kernel_type; switch (y.Parameter.Kernel) { case SVMKernelType.LINEAR: break; case SVMKernelType.POLY: y.Parameter.Gamma = x.param.gamma; y.Parameter.Coef0 = x.param.coef0; y.Parameter.Degree = x.param.degree; break; case SVMKernelType.RBF: y.Parameter.Gamma = x.param.gamma; break; case SVMKernelType.SIGMOID: y.Parameter.Gamma = x.param.gamma; y.Parameter.Coef0 = x.param.coef0; break; } } else { y.Parameter = SVMParameter.Convert(x.param); } int problemCount = (int)(y.ClassCount * (y.ClassCount - 1) * 0.5); y.Rho = new double[problemCount]; Marshal.Copy(x.rho, y.Rho, 0, y.Rho.Length); y.ProbabilityA = null; if (x.probA != IntPtr.Zero) { y.ProbabilityA = new double[problemCount]; Marshal.Copy(x.probA, y.ProbabilityA, 0, y.ProbabilityA.Length); } y.ProbabilityB = null; if (x.probB != IntPtr.Zero) { y.ProbabilityB = new double[problemCount]; Marshal.Copy(x.probB, y.ProbabilityB, 0, y.ProbabilityB.Length); } if (x.nSV != IntPtr.Zero) { y.SVCounts = new int[y.ClassCount]; Marshal.Copy(x.nSV, y.SVCounts, 0, y.SVCounts.Length); y.Labels = new int[y.ClassCount]; Marshal.Copy(x.label, y.Labels, 0, y.Labels.Length); } y.SVCoefs = new List<double[]>(y.ClassCount - 1); IntPtr i_ptr_svcoef = x.sv_coef; for (int i = 0; i < y.ClassCount - 1; i++) { y.SVCoefs.Add(new double[y.TotalSVCount]); IntPtr coef_ptr = (IntPtr)Marshal.PtrToStructure(i_ptr_svcoef, typeof(IntPtr)); Marshal.Copy(coef_ptr, y.SVCoefs[i], 0, y.SVCoefs[i].Length); i_ptr_svcoef = IntPtr.Add(i_ptr_svcoef, Marshal.SizeOf(typeof(IntPtr))); } y.SVIndices = null; if (x.sv_indices != IntPtr.Zero) { y.SVIndices = new int[y.TotalSVCount]; Marshal.Copy(x.sv_indices, y.SVIndices, 0, y.SVIndices.Length); } y.SV = new List<SVMNode[]>(); IntPtr i_ptr_sv = x.SV; for (int i = 0; i < x.l; i++) { IntPtr ptr_nodes = (IntPtr)Marshal.PtrToStructure(i_ptr_sv, typeof(IntPtr)); SVMNode[] nodes = SVMNode.Convert(ptr_nodes); y.SV.Add(nodes); i_ptr_sv = IntPtr.Add(i_ptr_sv, Marshal.SizeOf(typeof(IntPtr))); } return y; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="filename"></param> /// <returns></returns> public static bool SaveModel(SVMModel model, string filename) { if (String.IsNullOrWhiteSpace(filename) || model == null) { return false; } IntPtr ptr_model = SVMModel.Allocate(model); IntPtr ptr_filename = Marshal.StringToHGlobalAnsi(filename); bool success = libsvm.svm_save_model(ptr_filename, ptr_model) == 0; Marshal.FreeHGlobal(ptr_filename); ptr_filename = IntPtr.Zero; return success; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="x"></param> /// <param name="values"></param> /// <returns></returns> public static double PredictValues(SVMModel model, SVMNode[] x, out double[] values) { IntPtr ptr_model = SVMModel.Allocate(model); double result = PredictValues(ptr_model, x, out values); SVMModel.Free(ptr_model); return result; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="x"></param> /// <param name="estimations"></param> /// <returns></returns> public static double PredictProbability(SVMModel model, SVMNode[] x, out double[] estimations) { IntPtr ptr_model = SVMModel.Allocate(model); double result = PredictProbability(ptr_model, x, out estimations); SVMModel.Free(ptr_model); return result; }
/// <summary> /// This function does classification or regression on a test vector x given a model. /// </summary> /// <param name="model">SVM model.</param> /// <param name="x">Test vector.</param> /// <returns>For a classification model, the predicted class for x is returned. /// For a regression model, the function value of x calculated using the model is returned. /// For an one-class model, +1 or -1 is returned.</returns> public static double Predict(SVMModel model, SVMNode[] x) { IntPtr ptr_model = SVMModel.Allocate(model); double result = Predict(ptr_model, x); SVMModel.Free(ptr_model); return result; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <returns></returns> public static bool CheckProbabilityModel(SVMModel model) { if (model == null) { throw new ArgumentNullException("model"); } IntPtr ptr_model = SVMModel.Allocate(model); bool success = libsvm.svm_check_probability_model(ptr_model); SVMModel.Free(ptr_model); return success; }
public static SVMModel Convert(svm_model x) { SVMModel y = new SVMModel(); y.Creation = (CreationType)x.free_sv; y.ClassCount = x.nr_class; y.TotalSVCount = x.l; if (y.Creation == CreationType.LOAD_MODEL) { y.Parameter = new SVMParameter(); y.Parameter.Type = (SVMType)x.param.svm_type; y.Parameter.Kernel = (SVMKernelType)x.param.kernel_type; switch (y.Parameter.Kernel) { case SVMKernelType.LINEAR: break; case SVMKernelType.POLY: y.Parameter.Gamma = x.param.gamma; y.Parameter.Coef0 = x.param.coef0; y.Parameter.Degree = x.param.degree; break; case SVMKernelType.RBF: y.Parameter.Gamma = x.param.gamma; break; case SVMKernelType.SIGMOID: y.Parameter.Gamma = x.param.gamma; y.Parameter.Coef0 = x.param.coef0; break; } } else { y.Parameter = SVMParameter.Convert(x.param); } int problemCount = (int)(y.ClassCount * (y.ClassCount - 1) * 0.5); y.Rho = new double[problemCount]; Marshal.Copy(x.rho, y.Rho, 0, y.Rho.Length); y.ProbabilityA = null; if (x.probA != IntPtr.Zero) { y.ProbabilityA = new double[problemCount]; Marshal.Copy(x.probA, y.ProbabilityA, 0, y.ProbabilityA.Length); } y.ProbabilityB = null; if (x.probB != IntPtr.Zero) { y.ProbabilityB = new double[problemCount]; Marshal.Copy(x.probB, y.ProbabilityB, 0, y.ProbabilityB.Length); } y.SVCounts = new int[y.ClassCount]; Marshal.Copy(x.nSV, y.SVCounts, 0, y.SVCounts.Length); y.Labels = new int[y.ClassCount]; Marshal.Copy(x.label, y.Labels, 0, y.Labels.Length); y.SVCoefs = new List <double[]>(y.ClassCount - 1); IntPtr i_ptr_svcoef = x.sv_coef; for (int i = 0; i < y.ClassCount - 1; i++) { y.SVCoefs.Add(new double[y.TotalSVCount]); IntPtr coef_ptr = (IntPtr)Marshal.PtrToStructure(i_ptr_svcoef, typeof(IntPtr)); Marshal.Copy(coef_ptr, y.SVCoefs[i], 0, y.SVCoefs[i].Length); i_ptr_svcoef = IntPtr.Add(i_ptr_svcoef, Marshal.SizeOf(typeof(IntPtr))); } y.SVIndices = null; if (x.sv_indices != IntPtr.Zero) { y.SVIndices = new int[y.TotalSVCount]; Marshal.Copy(x.sv_indices, y.SVIndices, 0, y.SVIndices.Length); } y.SV = new List <SVMNode[]>(); IntPtr i_ptr_sv = x.SV; for (int i = 0; i < x.l; i++) { IntPtr ptr_nodes = (IntPtr)Marshal.PtrToStructure(i_ptr_sv, typeof(IntPtr)); SVMNode[] nodes = SVMNode.Convert(ptr_nodes); y.SV.Add(nodes); i_ptr_sv = IntPtr.Add(i_ptr_sv, Marshal.SizeOf(typeof(IntPtr))); } return(y); }
/// <summary> /// This function does classification or regression on a test vector x given a model. /// </summary> /// <param name="model">SVM model.</param> /// <param name="x">Test vector.</param> /// <returns>For a classification model, the predicted class for x is returned. /// For a regression model, the function value of x calculated using the model is returned. /// For an one-class model, +1 or -1 is returned.</returns> public static double Predict(SVMModel model, SVMNode[] x) { if (model == null) { throw new ArgumentNullException("model"); } if (x == null) { throw new ArgumentNullException("x"); } IntPtr ptr_model = SVMModel.Allocate(model); double result = Predict(ptr_model, x); SVMModel.Free(ptr_model); return result; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <returns></returns> public static bool CheckProbabilityModel(SVMModel model) { IntPtr ptr_model = SVMModel.Allocate(model); bool success = libsvm.svm_check_probability_model(ptr_model); SVMModel.Free(ptr_model); return success; }
/// <summary> /// /// </summary> /// <param name="model"></param> /// <param name="x"></param> /// <param name="estimations"></param> /// <returns></returns> public static double PredictProbability(SVMModel model, SVMNode[] x, out double[] estimations) { if (model == null) { throw new ArgumentNullException("model"); } if (x == null) { throw new ArgumentNullException("x"); } IntPtr ptr_model = SVMModel.Allocate(model); double result = PredictProbability(ptr_model, x, out estimations); SVMModel.Free(ptr_model); return result; }
public static IntPtr Allocate(SVMModel x) { if (x == null || x.ClassCount < 1 || x.Labels == null || x.Labels.Length < 1 || x.Parameter == null || x.Rho == null || x.Rho.Length < 1 || x.SVCoefs == null || x.SVCoefs.Count < 1 || x.TotalSVCount < 1 || x.SVCounts == null || x.SVCounts.Length < 1) { return(IntPtr.Zero); } svm_model y = new svm_model(); y.nr_class = x.ClassCount; y.l = x.TotalSVCount; y.free_sv = (int)x.Creation; // Allocate model.parameter IntPtr ptr_param = SVMParameter.Allocate(x.Parameter); y.param = (svm_parameter)Marshal.PtrToStructure(ptr_param, typeof(svm_parameter)); // Allocate model.rho y.rho = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.Rho.Length); Marshal.Copy(x.Rho, 0, y.rho, x.Rho.Length); // Allocate model.probA y.probA = IntPtr.Zero; if (x.ProbabilityA != null) { y.probA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.ProbabilityA.Length); Marshal.Copy(x.ProbabilityA, 0, y.probA, x.ProbabilityA.Length); } // Allocate model.probB y.probB = IntPtr.Zero; if (x.ProbabilityB != null) { y.probB = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.ProbabilityB.Length); Marshal.Copy(x.ProbabilityB, 0, y.probB, x.ProbabilityB.Length); } // Allocate model.label y.label = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * x.Labels.Length); Marshal.Copy(x.Labels, 0, y.label, x.Labels.Length); // Allocate model.nSV y.nSV = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * x.SVCounts.Length); Marshal.Copy(x.SVCounts, 0, y.nSV, x.SVCounts.Length); // Allocate model.sv_coef y.sv_coef = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * x.SVCoefs.Count); IntPtr i_ptr_svcoef = y.sv_coef; for (int i = 0; i < x.SVCoefs.Count; i++) { IntPtr temp = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(double)) * x.SVCoefs[i].Length); Marshal.Copy(x.SVCoefs[i], 0, temp, x.SVCoefs[i].Length); Marshal.StructureToPtr(temp, i_ptr_svcoef, true); i_ptr_svcoef = IntPtr.Add(i_ptr_svcoef, Marshal.SizeOf(typeof(IntPtr))); } // Allocate model.sv_indices y.sv_indices = IntPtr.Zero; if (x.SVIndices != null) { y.sv_indices = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)) * x.SVIndices.Length); Marshal.Copy(x.SVIndices, 0, y.sv_indices, x.SVIndices.Length); } // Allocate model.SV y.SV = IntPtr.Zero; if (x.SV != null) { y.SV = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(IntPtr)) * x.SV.Count); IntPtr i_ptr_sv = y.SV; for (int i = 0; i < x.SV.Count; i++) { // Prepare each node array // 1) All nodes containing zero value is removed // 2) A node which index is -1 is added to the end List <SVMNode> temp = x.SV[i].Where(a => a.Value != 0).ToList(); temp.Add(new SVMNode(-1, 0)); SVMNode[] nodes = temp.ToArray(); // Allocate node array IntPtr ptr_nodes = SVMNode.Allocate(nodes); Marshal.StructureToPtr(ptr_nodes, i_ptr_sv, true); i_ptr_sv = IntPtr.Add(i_ptr_sv, Marshal.SizeOf(typeof(IntPtr))); } } // Allocate the model int size = Marshal.SizeOf(y); IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(y, ptr, true); return(ptr); }