diff --git a/scikits/learn/src/libsvm_helper.c b/scikits/learn/src/libsvm_helper.c
index f8edee2a1f5d8d880bc197b5ca72d03ebcabb1f2..f131eaed9a7fa76f6e9be92fed6e49c614590912 100644
--- a/scikits/learn/src/libsvm_helper.c
+++ b/scikits/learn/src/libsvm_helper.c
@@ -338,7 +338,8 @@ int copy_prob_predict(char *predict, struct svm_model *model, npy_intp *predict_
     if (predict_nodes == NULL)
         return -1;
     for(i=0; i<n; ++i) {
-        svm_predict_probability(model, predict_nodes[i], &t[i*m]);
+        svm_predict_probability(model, predict_nodes[i], 
+                                dec_values + i*m*sizeof(double));
         free(predict_nodes[i]);
     }
     return 0;
diff --git a/scikits/learn/svm.py b/scikits/learn/svm.py
index 76db50020a83ce97f84ec74927f0c0f8589ef201..1e117fc7a18dfb15c3288608897a1bd5c02db94a 100644
--- a/scikits/learn/svm.py
+++ b/scikits/learn/svm.py
@@ -5,7 +5,7 @@ _kernel_types = ['linear', 'poly', 'rbf', 'sigmoid', 'precomputed']
 _svm_types = ['c_svc', 'nu_svc', 'one_class', 'epsilon_svr', 'nu_svr']
 
 
-class BaseSVM(object):
+class BaseLibsvm(object):
     """
     Base class for classifiers that use support vector machine.
 
@@ -62,8 +62,8 @@ class BaseSVM(object):
         if X.shape[0] != y.shape[0]: raise ValueError("Incompatible shapes")
 
         if (self.gamma == 0): self.gamma = 1.0/X.shape[0]
-        self.coef_, self.rho_, self.support_, self.nclass_, self.nSV_, self.label_, \
-             self.probA_, self.probB_ = libsvm.train_wrap(X, y,
+        self.coef_, self.rho_, self.support_, self.nclass_, self.nSV_, \
+                 self.label_, self.probA_, self.probB_ = libsvm.train_wrap(X, y,
                  self.svm, self.kernel, self.degree, self.gamma,
                  self.coef0, self.eps, self.C, self.nr_weight,
                  self.weight_label, self.weight, self.nu, self.cache_size, self.p,
@@ -100,7 +100,7 @@ class BaseSVM(object):
 # Public API
 # No processing should go into these classes
 
-class SVC(BaseSVM):
+class SVC(BaseLibsvm):
     """
     Support Vector Classification
 
@@ -174,46 +174,16 @@ class SVC(BaseSVM):
     SVR
     """
 
-    _penalties = {'l2': 0, 'l1' : 6}
-
-    
-    def __init__(self, impl='c_svc', kernel='rbf', degree=3, penalty='l2',
+    def __init__(self, impl='c_svc', kernel='rbf', degree=3,
                  gamma=0.0, coef0=0.0, cache_size=100.0, eps=1e-3,
                  C=1.0, nr_weight=0, nu=0.5, p=0.1, shrinking=True,
                  probability=False):
-        BaseSVM.__init__(self, impl, kernel, degree, gamma, coef0,
+        BaseLibsvm.__init__(self, impl, kernel, degree, gamma, coef0,
                          cache_size, eps, C, nr_weight, nu, p,
                          shrinking, probability)
-        self.penalty = self._penalties[penalty]
-        if self.kernel == 0:
-            # this must be called after BaseSVM.__init__
-            # because liblinear expects this to be ints
-            self.weight_label = np.empty(0, dtype=np.int32)
-
-    def fit(self, X, Y):
-        if self.kernel > 0:
-            return BaseSVM.fit(self, X, Y)
-        X = np.asanyarray(X, dtype=np.float64, order='C')
-        Y = np.asanyarray(Y, dtype=np.int32, order='C')
-        self.coef_, self.label_, self.bias_ = liblinear.train_wrap(X,
-                                          Y, self.penalty, self.eps, 1.0,
-                                          self.C, 0,
-                                          self.weight_label,
-                                          self.weight)
-
-        return self
 
-    def predict(self, T):
-        if self.kernel > 0:
-            return BaseSVM.predict(self, T)
-        T = np.asanyarray(T, dtype=np.float64, order='C')
-        return liblinear.predict_wrap(T, self.coef_, self.penalty,
-                                      self.eps, self.C,
-                                      self.weight_label,
-                                      self.weight, self.label_,
-                                      1.0)
 
-class SVR(BaseSVM):
+class SVR(BaseLibsvm):
     """
     Support Vector Regression.
 
@@ -244,11 +214,11 @@ class SVR(BaseSVM):
                  gamma=0.0, coef0=0.0, cache_size=100.0, eps=1e-3,
                  C=1.0, nr_weight=0, nu=0.5, p=0.1, shrinking=True,
                  probability=False):
-        BaseSVM.__init__(self, impl, kernel, degree, gamma, coef0,
+        BaseLibsvm.__init__(self, impl, kernel, degree, gamma, coef0,
                          cache_size, eps, C, nr_weight, nu, p,
                          shrinking, probability)
 
-class OneClassSVM(BaseSVM):
+class OneClassSVM(BaseLibsvm):
     """
     Outlayer detection
 
@@ -265,6 +235,51 @@ class OneClassSVM(BaseSVM):
                  C=1.0, nr_weight=0, nu=0.5, p=0.1, shrinking=True,
                  probability=False):
         impl = 'one_class'
-        BaseSVM.__init__(self, impl, kernel, degree, gamma, coef0,
+        BaseLibsvm.__init__(self, impl, kernel, degree, gamma, coef0,
                          cache_size, eps, C, nr_weight, nu, p,
                          shrinking, probability)
+
+
+class LinearSVC(object):
+    """
+    Linear Support Vector Classification.
+
+
+    Parameters
+    ----------
+    
+    Also accepts parameter penalty, that can have values 'l1' or 'l2'
+
+    Similar to SVC with parameter kernel='linear', but uses internally
+    liblinear rather than libsvm, so it has more flexibility in the
+    choice of penalties and loss functions and should be faster for
+    huge datasets.
+    """
+    _penalties = {'': 0}
+
+    def __init__(self, loss='l2', penalty='l2', dual=False, eps=1e-4, C=1.0):
+        self.penalty = self._penalties[penalty]
+        self.eps = eps
+        self.C = C
+
+    _penalties = {'l2': 0, 'l1' : 6}
+    _weight_label = np.empty(0, dtype=np.int)
+    _weight = np.empty(0, dtype=np.float64)
+
+    def fit(self, X, Y):
+        X = np.asanyarray(X, dtype=np.float64, order='C')
+        Y = np.asanyarray(Y, dtype=np.int, order='C')
+        self.coef_, self.label_, self.bias_ = liblinear.train_wrap(X,
+                                          Y, self.penalty, self.eps, 1.0,
+                                          self.C, 0,
+                                          self._weight_label,
+                                          self._weight)
+
+    def predict(self, T):
+        T = np.asanyarray(T, dtype=np.float64, order='C')
+        return liblinear.predict_wrap(T, self.coef_, self.penalty,
+                                      self.eps, self.C,
+                                      self._weight_label,
+                                      self._weight, self.label_,
+                                      self.bias_)
+