Пример #1
0
        /// <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;
            }
        }
Пример #2
0
        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;
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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);
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        /// <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);
        }
Пример #8
0
        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;
        }
Пример #9
0
        /// <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);
        }
Пример #10
0
        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;
        }
Пример #11
0
        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;
        }
Пример #12
0
        /// <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;
        }
Пример #13
0
 /// <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;
 }
Пример #14
0
 /// <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;
 }
Пример #15
0
 /// <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;
 }
Пример #16
0
        /// <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;
        }
Пример #17
0
        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);
        }
Пример #18
0
        /// <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;
        }
Пример #19
0
 /// <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;
 }
Пример #20
0
        /// <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;
        }
Пример #21
0
        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);
        }