diff --git a/Data/SVM.hs b/Data/SVM.hs
--- a/Data/SVM.hs
+++ b/Data/SVM.hs
@@ -1,107 +1,165 @@
-{-|
-This module provides a safe bindings to libsvm functions and structures with implicit memory handling.
--}
+-- |
+-- This module provides a safe bindings to libsvm functions and structures with implicit memory handling.
 module Data.SVM
-  ( Vector
-  , Problem
-  , KernelType (..)
-  , Algorithm (..)
-  , ExtraParam (..)
-  , Model
-  , train
-  , train'
-  , crossValidate
-  , crossValidate'
-  , loadModel
-  , saveModel
-  , predict
-  , withPrintFn
-  , CSvmPrintFn
-  ) where
+  ( Vector,
+    Problem,
+    KernelType (..),
+    Algorithm (..),
+    ExtraParam (..),
+    Model,
+    train,
+    train',
+    crossValidate,
+    crossValidate',
+    loadModel,
+    saveModel,
+    predict,
+    withPrintFn,
+    CSvmPrintFn,
+  )
+where
 
-import           Control.Exception
-import           Control.Monad         (when)
-import           Data.IntMap           (IntMap, toList)
-import qualified Data.IntMap           as M
-import           Data.SVM.Raw          (CSvmModel, CSvmNode (..), CSvmParameter,
-                                        CSvmPrintFn, CSvmProblem (..),
-                                        c_clone_model_support_vectors,
-                                        c_svm_check_parameter,
-                                        c_svm_cross_validation,
-                                        c_svm_destroy_model, c_svm_load_model,
-                                        c_svm_predict, c_svm_save_model,
-                                        c_svm_set_print_string_function,
-                                        c_svm_train, createSvmPrintFnPtr,
-                                        defaultCParam)
-import qualified Data.SVM.Raw          as R
-import           Foreign.C.String
-import           Foreign.ForeignPtr
-import           Foreign.Marshal.Alloc (alloca, free, malloc)
-import           Foreign.Marshal.Array
-import           Foreign.Ptr           (Ptr, freeHaskellFunPtr, nullPtr)
-import           Foreign.Storable      (peek, poke)
+import Control.Exception
+import Control.Monad (when)
+import Data.IntMap (IntMap, toList)
+import qualified Data.IntMap as M
+import Data.SVM.Raw
+  ( CSvmModel,
+    CSvmNode (..),
+    CSvmParameter,
+    CSvmPrintFn,
+    CSvmProblem (..),
+    c_clone_model_support_vectors,
+    c_svm_check_parameter,
+    c_svm_cross_validation,
+    c_svm_destroy_model,
+    c_svm_load_model,
+    c_svm_predict,
+    c_svm_save_model,
+    c_svm_set_print_string_function,
+    c_svm_train,
+    createSvmPrintFnPtr,
+    defaultCParam,
+  )
+import qualified Data.SVM.Raw as R
+import Foreign.C.String (newCString, peekCString)
+import Foreign.ForeignPtr
+  ( ForeignPtr,
+    newForeignPtr,
+    withForeignPtr,
+  )
+import Foreign.Marshal.Alloc (alloca, free, malloc)
+import Foreign.Marshal.Array
+  ( allocaArray,
+    newArray,
+    newArray0,
+    peekArray,
+    withArray0,
+  )
+import Foreign.Ptr (Ptr, freeHaskellFunPtr, nullPtr)
+import Foreign.Storable (peek, poke)
 
--- |Vector type provides a sparse implementation of vector. It uses IntMap as underlying implementation.
+-- | Vector type provides a sparse implementation of vector. It uses IntMap as underlying implementation.
 type Vector = IntMap Double
 
--- |SVM problem is a list of maps from training vectors to 1.0 or -1.0
+-- | SVM problem is a list of maps from training vectors to 1.0 or -1.0
 type Problem = [(Double, Vector)]
 
--- |'Model' is a wrapper over foreign pointer to 'CSvmModel'
+-- | 'Model' is a wrapper over foreign pointer to 'CSvmModel'
 newtype Model = Model (ForeignPtr CSvmModel)
 
--- |Kernel function for SVM algorithm.
-data KernelType = Linear -- ^Linear kernel function, i.e. dot product
-                | RBF     { gamma :: Double } -- ^Gaussian radial basis function with parameter 'gamma'
-                | Sigmoid { gamma :: Double, coef0 :: Double } -- ^Sigmoid kernel function
-                | Poly    { gamma :: Double, coef0 :: Double, degree :: Int} -- ^Inhomogeneous polynomial function
+-- | Kernel function for SVM algorithm.
+data KernelType
+  = -- | Linear kernel function, i.e. dot product
+    Linear
+  | -- | Gaussian radial basis function with parameter 'gamma'
+    RBF {gamma :: Double}
+  | -- | Sigmoid kernel function
+    Sigmoid {gamma :: Double, coef0 :: Double}
+  | -- | Inhomogeneous polynomial function
+    Poly {gamma :: Double, coef0 :: Double, degree :: Int}
 
--- |SVM Algorithm with parameters
-data Algorithm = CSvc  { c :: Double } -- ^c-SVC algorithm
-               | NuSvc { nu :: Double } -- ^nu-SVC algorithm
-               | NuSvr { nu :: Double, c :: Double } -- ^nu-SVR algorithm
-               | EpsilonSvr { epsilon :: Double, c :: Double } -- ^eps-SVR algorithm
-               | OneClassSvm { nu :: Double } -- ^One class SVM
+-- | SVM Algorithm with parameters
+data Algorithm
+  = -- | c-SVC algorithm
+    CSvc {c :: Double}
+  | -- | nu-SVC algorithm
+    NuSvc {nu :: Double}
+  | -- | nu-SVR algorithm
+    NuSvr {nu :: Double, c :: Double}
+  | -- | eps-SVR algorithm
+    EpsilonSvr {epsilon :: Double, c :: Double}
+  | -- | One class SVM
+    OneClassSvm {nu :: Double}
 
--- |Extra parameters of SVM implementation
-data ExtraParam = ExtraParam {cacheSize   :: Double,
-                              shrinking   :: Int,
-                              probability :: Int}
+-- | Extra parameters of SVM implementation
+data ExtraParam = ExtraParam
+  { cacheSize :: Double,
+    shrinking :: Int,
+    probability :: Int
+  }
 
--- |Default extra parameters of SVM implamentation
+-- | Default extra parameters of SVM implamentation
 defaultExtra :: ExtraParam
 defaultExtra = ExtraParam {cacheSize = 1000, shrinking = 1, probability = 0}
 
 mergeKernel :: KernelType -> CSvmParameter -> CSvmParameter
-mergeKernel Linear p        = p { R.kernel_type = R.linear }
-mergeKernel (RBF g) p       = p { R.kernel_type = R.rbf,
-                                  R.gamma = realToFrac g }
-mergeKernel (Sigmoid g cf) p = p { R.kernel_type = R.sigmoid,
-                                  R.gamma = realToFrac g,
-                                  R.coef0 = realToFrac cf }
-mergeKernel (Poly g cf d) p  = p { R.kernel_type = R.poly,
-                                  R.gamma = realToFrac g,
-                                  R.coef0 = realToFrac cf,
-                                  R.degree = fromIntegral d}
+mergeKernel Linear p = p {R.kernel_type = R.linear}
+mergeKernel (RBF g) p =
+  p
+    { R.kernel_type = R.rbf,
+      R.gamma = realToFrac g
+    }
+mergeKernel (Sigmoid g cf) p =
+  p
+    { R.kernel_type = R.sigmoid,
+      R.gamma = realToFrac g,
+      R.coef0 = realToFrac cf
+    }
+mergeKernel (Poly g cf d) p =
+  p
+    { R.kernel_type = R.poly,
+      R.gamma = realToFrac g,
+      R.coef0 = realToFrac cf,
+      R.degree = fromIntegral d
+    }
 
 mergeAlgo :: Algorithm -> CSvmParameter -> CSvmParameter
-mergeAlgo (CSvc cf) p         = p { R.svm_type = R.cSvc,
-                                   R.c = realToFrac cf }
-mergeAlgo (NuSvc n) p       = p { R.svm_type = R.nuSvc,
-                                   R.nu = realToFrac n }
-mergeAlgo (NuSvr n cf) p     = p { R.svm_type = R.nuSvr,
-                                   R.nu = realToFrac n,
-                                   R.c = realToFrac cf }
-mergeAlgo (EpsilonSvr e cf) p = p { R.svm_type = R.epsilonSvr,
-                                   R.eps = realToFrac e,
-                                   R.c = realToFrac cf }
-mergeAlgo (OneClassSvm n) p = p { R.svm_type = R.oneClass,
-                                   R.nu = realToFrac n }
+mergeAlgo (CSvc cf) p =
+  p
+    { R.svm_type = R.cSvc,
+      R.c = realToFrac cf
+    }
+mergeAlgo (NuSvc n) p =
+  p
+    { R.svm_type = R.nuSvc,
+      R.nu = realToFrac n
+    }
+mergeAlgo (NuSvr n cf) p =
+  p
+    { R.svm_type = R.nuSvr,
+      R.nu = realToFrac n,
+      R.c = realToFrac cf
+    }
+mergeAlgo (EpsilonSvr e cf) p =
+  p
+    { R.svm_type = R.epsilonSvr,
+      R.eps = realToFrac e,
+      R.c = realToFrac cf
+    }
+mergeAlgo (OneClassSvm n) p =
+  p
+    { R.svm_type = R.oneClass,
+      R.nu = realToFrac n
+    }
 
 mergeExtra :: ExtraParam -> CSvmParameter -> CSvmParameter
-mergeExtra (ExtraParam cf s pr) p = p { R.cache_size = realToFrac cf,
-                                       R.shrinking = fromIntegral s,
-                                       R.probability = fromIntegral pr }
+mergeExtra (ExtraParam cf s pr) p =
+  p
+    { R.cache_size = realToFrac cf,
+      R.shrinking = fromIntegral s,
+      R.probability = fromIntegral pr
+    }
 
 -------------------------------------------------------------------------------
 
@@ -120,117 +178,123 @@
 withCSvmNodeArray v = withArray0 endMarker (convertToNodeArray v)
 
 newCSvmProblem :: Problem -> IO (Ptr CSvmProblem)
-newCSvmProblem lvs = do nodePtrList <- mapM (newCSvmNodeArray . snd) lvs
-                        nodePtrPtr  <- newArray nodePtrList
-                        labelPtr <- newArray (map (realToFrac . fst) lvs)
-                        let z = fromIntegral . length $ lvs
-                        ptr <- malloc
-                        poke ptr $ CSvmProblem z labelPtr nodePtrPtr
-                        return ptr
+newCSvmProblem lvs = do
+  nodePtrList <- mapM (newCSvmNodeArray . snd) lvs
+  nodePtrPtr <- newArray nodePtrList
+  labelPtr <- newArray (map (realToFrac . fst) lvs)
+  let z = fromIntegral . length $ lvs
+  ptr <- malloc
+  poke ptr $ CSvmProblem z labelPtr nodePtrPtr
+  return ptr
 
 freeCSVmProblem :: Ptr CSvmProblem -> IO ()
-freeCSVmProblem ptr = do prob <- peek ptr
-                         free $ y prob
-                         vecList <- peekArray (fromIntegral $ l prob) (x prob)
-                         mapM_ free vecList
-                         free $ x prob
-                         free ptr
+freeCSVmProblem ptr = do
+  prob <- peek ptr
+  free $ y prob
+  vecList <- peekArray (fromIntegral $ l prob) (x prob)
+  mapM_ free vecList
+  free $ x prob
+  free ptr
 
 withProblem :: Problem -> (Ptr CSvmProblem -> IO a) -> IO a
 withProblem prob = bracket (newCSvmProblem prob) freeCSVmProblem
 
 ---
 
-withParam :: ExtraParam
-             -> Algorithm
-             -> KernelType
-             -> (Ptr CSvmParameter -> IO a)
-             -> IO a
+withParam ::
+  ExtraParam ->
+  Algorithm ->
+  KernelType ->
+  (Ptr CSvmParameter -> IO a) ->
+  IO a
 withParam extra algo kern f =
-    let merge = mergeAlgo algo . mergeKernel kern . mergeExtra extra
-        param = merge defaultCParam
-    in alloca $ \paramPtr -> poke paramPtr param >> f paramPtr
+  let merge = mergeAlgo algo . mergeKernel kern . mergeExtra extra
+      param = merge defaultCParam
+   in alloca $ \paramPtr -> poke paramPtr param >> f paramPtr
 
 checkParam :: Ptr CSvmProblem -> Ptr CSvmParameter -> IO ()
 checkParam probPtr paramPtr = do
-    let errStr = c_svm_check_parameter probPtr paramPtr
-    when (errStr /= nullPtr) $ peekCString errStr >>= error . ("svm: "++)
+  let errStr = c_svm_check_parameter probPtr paramPtr
+  when (errStr /= nullPtr) $ peekCString errStr >>= error . ("svm: " ++)
 
 --
 
--- |Like 'train' but with extra parameters
+-- | Like 'train' but with extra parameters
 train' :: ExtraParam -> Algorithm -> KernelType -> Problem -> IO Model
 train' extra algo kern prob =
-    withProblem prob $ \probPtr ->
+  withProblem prob $ \probPtr ->
     withParam extra algo kern $ \paramPtr -> do
-        checkParam probPtr paramPtr
-        modelPtr <- c_svm_train probPtr paramPtr
-        _ <- c_clone_model_support_vectors modelPtr
-        modelForeignPtr <- newForeignPtr c_svm_destroy_model modelPtr
-        return $ Model modelForeignPtr
-
+      checkParam probPtr paramPtr
+      modelPtr <- c_svm_train probPtr paramPtr
+      _ <- c_clone_model_support_vectors modelPtr
+      modelForeignPtr <- newForeignPtr c_svm_destroy_model modelPtr
+      return $ Model modelForeignPtr
 
 -- | The 'train' function allows training a 'Model' starting from a 'Problem'
 -- by specifying an 'Algorithm' and a 'KernelType'
 train :: Algorithm -> KernelType -> Problem -> IO Model
 train = train' defaultExtra
 
--- |Like 'crossvalidate' but with extra parameters
-crossValidate' :: ExtraParam
-                  -> Algorithm
-                  -> KernelType
-                  -> Problem
-                  -> Int
-                  -> IO [Double]
+-- | Like 'crossvalidate' but with extra parameters
+crossValidate' ::
+  ExtraParam ->
+  Algorithm ->
+  KernelType ->
+  Problem ->
+  Int ->
+  IO [Double]
 crossValidate' extra algo kern prob nFold =
-    withProblem prob $ \probPtr ->
+  withProblem prob $ \probPtr ->
     withParam extra algo kern $ \paramPtr -> do
-        probLen <- (fromIntegral . R.l) `fmap` peek probPtr
-        allocaArray probLen $ \targetPtr -> do -- (length prob is inefficient)
-            checkParam probPtr paramPtr
-            let c_nFold = fromIntegral nFold
-            c_svm_cross_validation probPtr paramPtr c_nFold targetPtr
-            map realToFrac `fmap` peekArray probLen targetPtr
+      probLen <- (fromIntegral . R.l) `fmap` peek probPtr
+      allocaArray probLen $ \targetPtr -> do
+        -- (length prob is inefficient)
+        checkParam probPtr paramPtr
+        let c_nFold = fromIntegral nFold
+        c_svm_cross_validation probPtr paramPtr c_nFold targetPtr
+        map realToFrac `fmap` peekArray probLen targetPtr
 
--- |Stratified cross validation
+-- | Stratified cross validation
 crossValidate :: Algorithm -> KernelType -> Problem -> Int -> IO [Double]
 crossValidate = crossValidate' defaultExtra
 
 -----------------------------------------------------------------------
 
--- |Save model to the file
+-- | Save model to the file
 saveModel :: Model -> FilePath -> IO ()
 saveModel (Model modelForeignPtr) path =
-    withForeignPtr modelForeignPtr $ \modelPtr -> do
-        pathString <- newCString path
-        ret <- c_svm_save_model pathString modelPtr
-        when (ret /= 0) $ error $ "svm: error saving the model:" ++ show ret
+  withForeignPtr modelForeignPtr $ \modelPtr -> do
+    pathString <- newCString path
+    ret <- c_svm_save_model pathString modelPtr
+    when (ret /= 0) $ error $ "svm: error saving the model:" ++ show ret
 
--- |Load model from the file
+-- | Load model from the file
 loadModel :: FilePath -> IO Model
 loadModel path = do
-    modelPtr <- c_svm_load_model =<< newCString path
-    Model `fmap` newForeignPtr c_svm_destroy_model modelPtr
+  modelPtr <- c_svm_load_model =<< newCString path
+  Model `fmap` newForeignPtr c_svm_destroy_model modelPtr
 
--- |Predict a value for 'Vector' by using 'Model'
+-- | Predict a value for 'Vector' by using 'Model'
 predict :: Model -> Vector -> IO Double
 predict (Model modelForeignPtr) vector = action
-    where action :: IO Double
-          action = withForeignPtr modelForeignPtr $ \modelPtr ->
-                   withCSvmNodeArray vector (fmap realToFrac . c_svm_predict modelPtr)
+  where
+    action :: IO Double
+    action = withForeignPtr modelForeignPtr $ \modelPtr ->
+      withCSvmNodeArray vector (fmap realToFrac . c_svm_predict modelPtr)
 
--- |Wrapper to change the libsvm output reporting function.
+-- | Wrapper to change the libsvm output reporting function.
 --
--- libsvm by default writes some statistics to stdout. If you don't
--- want any output from libsvm, you can do e.g.:
+--  libsvm by default writes some statistics to stdout. If you don't
+--  want any output from libsvm, you can do e.g.:
 --
--- >>> withPrintFn (\_ -> return ()) $ train (NuSvc 0.25) (RBF 1) feats
+--  >>> withPrintFn (\_ -> return ()) $ train (NuSvc 0.25) (RBF 1) feats
 withPrintFn :: CSvmPrintFn -> IO a -> IO a
-withPrintFn printfn body = bracket
-  (do
-    c_printfn <- createSvmPrintFnPtr printfn
-    c_svm_set_print_string_function c_printfn
-    return c_printfn
-  )
-  freeHaskellFunPtr
-  (const body)
+withPrintFn printfn body =
+  bracket
+    ( do
+        c_printfn <- createSvmPrintFnPtr printfn
+        c_svm_set_print_string_function c_printfn
+        return c_printfn
+    )
+    freeHaskellFunPtr
+    (const body)
diff --git a/HSvm.cabal b/HSvm.cabal
--- a/HSvm.cabal
+++ b/HSvm.cabal
@@ -1,6 +1,6 @@
 Cabal-Version:      2.2
 Name:               HSvm
-Version:            0.1.2.3.25
+Version:            0.1.2.3.32
 Copyright:          (c) 2009 Paolo Losi, 2017 Pavel Ryzhov
 Maintainer:         Pavel Ryzhov <paul@paulrz.cz>
 License:            BSD-3-Clause
diff --git a/cbits/svm.cpp b/cbits/svm.cpp
--- a/cbits/svm.cpp
+++ b/cbits/svm.cpp
@@ -8,6 +8,10 @@
 #include <limits.h>
 #include <locale.h>
 #include "svm.h"
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
 int libsvm_version = LIBSVM_VERSION;
 typedef float Qfloat;
 typedef signed char schar;
@@ -1290,6 +1294,9 @@
 		int start, j;
 		if((start = cache->get_data(i,&data,len)) < len)
 		{
+#ifdef _OPENMP
+#pragma omp parallel for private(j) schedule(guided)
+#endif
 			for(j=start;j<len;j++)
 				data[j] = (Qfloat)(y[i]*y[j]*(this->*kernel_function)(i,j));
 		}
@@ -1405,6 +1412,9 @@
 		int j, real_i = index[i];
 		if(cache->get_data(real_i,&data,l) < l)
 		{
+#ifdef _OPENMP
+#pragma omp parallel for private(j) schedule(guided)
+#endif
 			for(j=0;j<l;j++)
 				data[j] = (Qfloat)(this->*kernel_function)(real_i,j);
 		}
@@ -1833,7 +1843,7 @@
 		return 1.0/(1+exp(fApB)) ;
 }
 
-// Method 2 from the multiclass_prob paper by Wu, Lin, and Weng
+// Method 2 from the multiclass_prob paper by Wu, Lin, and Weng to predict probabilities
 static void multiclass_probability(int k, double **r, double *p)
 {
 	int t,j;
@@ -1897,7 +1907,7 @@
 	free(Qp);
 }
 
-// Cross-validation decision values for probability estimates
+// Using cross-validation decision values to get parameters for SVC probability estimates
 static void svm_binary_svc_probability(
 	const svm_problem *prob, const svm_parameter *param,
 	double Cp, double Cn, double& probA, double& probB)
@@ -1984,6 +1994,83 @@
 	free(perm);
 }
 
+// Binning method from the oneclass_prob paper by Que and Lin to predict the probability as a normal instance (i.e., not an outlier)
+static double predict_one_class_probability(const svm_model *model, double dec_value)
+{
+	double prob_estimate = 0.0;
+	int nr_marks = 10;
+
+	if(dec_value < model->prob_density_marks[0])
+		prob_estimate = 0.001;
+	else if(dec_value > model->prob_density_marks[nr_marks-1])
+		prob_estimate = 0.999;
+	else
+	{
+		for(int i=1;i<nr_marks;i++)
+			if(dec_value < model->prob_density_marks[i])
+			{
+				prob_estimate = (double)i/nr_marks;
+				break;
+			}
+	}
+	return prob_estimate;
+}
+
+static int compare_double(const void *a, const void *b)
+{
+	if(*(double *)a > *(double *)b)
+		return 1;
+	else if(*(double *)a < *(double *)b)
+		return -1;
+	return 0;
+}
+
+// Get parameters for one-class SVM probability estimates
+static int svm_one_class_probability(const svm_problem *prob, const svm_model *model, double *prob_density_marks)
+{
+	double *dec_values = Malloc(double,prob->l);
+	double *pred_results = Malloc(double,prob->l);
+	int ret = 0;
+	int nr_marks = 10;
+
+	for(int i=0;i<prob->l;i++)
+		pred_results[i] = svm_predict_values(model,prob->x[i],&dec_values[i]);
+	qsort(dec_values,prob->l,sizeof(double),compare_double);
+
+	int neg_counter=0;
+	for(int i=0;i<prob->l;i++)
+		if(dec_values[i]>=0)
+		{
+			neg_counter = i;
+			break;
+		}
+
+	int pos_counter = prob->l-neg_counter;
+	if(neg_counter<nr_marks/2 || pos_counter<nr_marks/2)
+	{
+		fprintf(stderr,"WARNING: number of positive or negative decision values <%d; too few to do a probability estimation.\n",nr_marks/2);
+		ret = -1;
+	}
+	else
+	{
+		// Binning by density
+		double *tmp_marks = Malloc(double,nr_marks+1);
+		int mid = nr_marks/2;
+		for(int i=0;i<mid;i++)
+			tmp_marks[i] = dec_values[i*neg_counter/mid];
+		tmp_marks[mid] = 0;
+		for(int i=mid+1;i<nr_marks+1;i++)
+			tmp_marks[i] = dec_values[neg_counter-1+(i-mid)*pos_counter/mid];
+
+		for(int i=0;i<nr_marks;i++)
+			prob_density_marks[i] = (tmp_marks[i]+tmp_marks[i+1])/2;
+		free(tmp_marks);
+	}
+	free(dec_values);
+	free(pred_results);
+	return ret;
+}
+
 // Return parameter of a Laplace distribution
 static double svm_svr_probability(
 	const svm_problem *prob, const svm_parameter *param)
@@ -2107,24 +2194,14 @@
 	   param->svm_type == EPSILON_SVR ||
 	   param->svm_type == NU_SVR)
 	{
-		printf("SVM type %d\n", param->svm_type);
-		printf("Kernel type %d\n", param->kernel_type);
-		printf("Gamma %f\n", param->gamma);
 		// regression or one-class-svm
 		model->nr_class = 2;
 		model->label = NULL;
 		model->nSV = NULL;
 		model->probA = NULL; model->probB = NULL;
+		model->prob_density_marks = NULL;
 		model->sv_coef = Malloc(double *,1);
 
-		if(param->probability &&
-		   (param->svm_type == EPSILON_SVR ||
-		    param->svm_type == NU_SVR))
-		{
-			model->probA = Malloc(double,1);
-			model->probA[0] = svm_svr_probability(prob,param);
-		}
-
 		decision_function f = svm_train_one(prob,param,0,0);
 		model->rho = Malloc(double,1);
 		model->rho[0] = f.rho;
@@ -2147,6 +2224,24 @@
 				++j;
 			}
 
+		if(param->probability &&
+		   (param->svm_type == EPSILON_SVR ||
+		    param->svm_type == NU_SVR))
+		{
+			model->probA = Malloc(double,1);
+			model->probA[0] = svm_svr_probability(prob,param);
+		}
+		else if(param->probability && param->svm_type == ONE_CLASS)
+		{
+			int nr_marks = 10;
+			double *prob_density_marks = Malloc(double,nr_marks);
+
+			if(svm_one_class_probability(prob,model,prob_density_marks) == 0)
+				model->prob_density_marks = prob_density_marks;
+			else
+				free(prob_density_marks);
+		}
+
 		free(f.alpha);
 	}
 	else
@@ -2264,6 +2359,7 @@
 			model->probA=NULL;
 			model->probB=NULL;
 		}
+		model->prob_density_marks=NULL;	// for one-class SVM probabilistic outputs only
 
 		int total_sv = 0;
 		int *nz_count = Malloc(int,nr_class);
@@ -2356,8 +2452,8 @@
 	int nr_class;
 	if (nr_fold > l)
 	{
+		fprintf(stderr,"WARNING: # folds (%d) > # data (%d). Will use # folds = # data instead (i.e., leave-one-out cross validation)\n", nr_fold, l);
 		nr_fold = l;
-		fprintf(stderr,"WARNING: # folds > # data. Will use # folds = # data instead (i.e., leave-one-out cross validation)\n");
 	}
 	fold_start = Malloc(int,nr_fold+1);
 	// stratified cv may not give leave-one-out rate
@@ -2518,6 +2614,9 @@
 	{
 		double *sv_coef = model->sv_coef[0];
 		double sum = 0;
+#ifdef _OPENMP
+#pragma omp parallel for private(i) reduction(+:sum) schedule(guided)
+#endif
 		for(i=0;i<model->l;i++)
 			sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param);
 		sum -= model->rho[0];
@@ -2534,6 +2633,9 @@
 		int l = model->l;
 
 		double *kvalue = Malloc(double,l);
+#ifdef _OPENMP
+#pragma omp parallel for private(i) schedule(guided)
+#endif
 		for(i=0;i<l;i++)
 			kvalue[i] = Kernel::k_function(x,model->SV[i],model->param);
 
@@ -2641,6 +2743,14 @@
 		free(pairwise_prob);
 		return model->label[prob_max_idx];
 	}
+	else if(model->param.svm_type == ONE_CLASS && model->prob_density_marks!=NULL)
+	{
+		double dec_value;
+		double pred_result = svm_predict_values(model,x,&dec_value);
+		prob_estimates[0] = predict_one_class_probability(model,dec_value);
+		prob_estimates[1] = 1-prob_estimates[0];
+		return pred_result;
+	}
 	else
 		return svm_predict(model, x);
 }
@@ -2714,6 +2824,14 @@
 			fprintf(fp," %.17g",model->probB[i]);
 		fprintf(fp, "\n");
 	}
+	if(model->prob_density_marks)
+	{
+		fprintf(fp, "prob_density_marks");
+		int nr_marks=10;
+		for(int i=0;i<nr_marks;i++)
+			fprintf(fp," %.17g",model->prob_density_marks[i]);
+		fprintf(fp, "\n");
+	}
 
 	if(model->nSV)
 	{
@@ -2868,6 +2986,13 @@
 			for(int i=0;i<n;i++)
 				FSCANF(fp,"%lf",&model->probB[i]);
 		}
+		else if(strcmp(cmd,"prob_density_marks")==0)
+		{
+			int n = 10;	// nr_marks
+			model->prob_density_marks = Malloc(double,n);
+			for(int i=0;i<n;i++)
+				FSCANF(fp,"%lf",&model->prob_density_marks[i]);
+		}
 		else if(strcmp(cmd,"nr_sv")==0)
 		{
 			int n = model->nr_class;
@@ -2912,6 +3037,7 @@
 	model->rho = NULL;
 	model->probA = NULL;
 	model->probB = NULL;
+	model->prob_density_marks = NULL;
 	model->sv_indices = NULL;
 	model->label = NULL;
 	model->nSV = NULL;
@@ -3023,14 +3149,17 @@
 	model_ptr->rho = NULL;
 
 	free(model_ptr->label);
-	model_ptr->label= NULL;
+	model_ptr->label = NULL;
 
 	free(model_ptr->probA);
 	model_ptr->probA = NULL;
 
 	free(model_ptr->probB);
-	model_ptr->probB= NULL;
+	model_ptr->probB = NULL;
 
+	free(model_ptr->prob_density_marks);
+	model_ptr->prob_density_marks = NULL;
+
 	free(model_ptr->sv_indices);
 	model_ptr->sv_indices = NULL;
 
@@ -3124,11 +3253,7 @@
 	   param->probability != 1)
 		return "probability != 0 and probability != 1";
 
-	if(param->probability == 1 &&
-	   svm_type == ONE_CLASS)
-		return "one-class SVM probability output not supported yet";
 
-
 	// check whether nu-svc is feasible
 
 	if(svm_type == NU_SVC)
@@ -3187,8 +3312,10 @@
 
 int svm_check_probability_model(const svm_model *model)
 {
-	return ((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) &&
-		model->probA!=NULL && model->probB!=NULL) ||
+	return
+		((model->param.svm_type == C_SVC || model->param.svm_type == NU_SVC) &&
+		 model->probA!=NULL && model->probB!=NULL) ||
+		(model->param.svm_type == ONE_CLASS && model->prob_density_marks!=NULL) ||
 		((model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) &&
 		 model->probA!=NULL);
 }
diff --git a/cbits/svm.h b/cbits/svm.h
--- a/cbits/svm.h
+++ b/cbits/svm.h
@@ -1,7 +1,7 @@
 #ifndef _LIBSVM_H
 #define _LIBSVM_H
 
-#define LIBSVM_VERSION 325
+#define LIBSVM_VERSION 332
 
 #ifdef __cplusplus
 extern "C" {
@@ -59,6 +59,7 @@
 	double *rho;		/* constants in decision functions (rho[k*(k-1)/2]) */
 	double *probA;		/* pariwise probability information */
 	double *probB;
+	double *prob_density_marks;	/* probability information for ONE_CLASS */
 	int *sv_indices;        /* sv_indices[0,...,nSV-1] are values in [1,...,num_traning_data] to indicate SVs in the training set */
 
 	/* for classification only */
@@ -88,7 +89,6 @@
 double svm_predict(const struct svm_model *model, const struct svm_node *x);
 double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates);
 
-void svm_destroy_model(struct svm_model *model_ptr);
 void svm_free_model_content(struct svm_model *model_ptr);
 void svm_free_and_destroy_model(struct svm_model **model_ptr_ptr);
 void svm_destroy_param(struct svm_parameter *param);
@@ -99,6 +99,7 @@
 void svm_set_print_string_function(void (*print_func)(const char *));
 
 // added by HSvm
+void svm_destroy_model(struct svm_model *model_ptr);
 int clone_model_support_vectors(struct svm_model *model);
 
 
