diff --git a/casadi-bindings.cabal b/casadi-bindings.cabal
--- a/casadi-bindings.cabal
+++ b/casadi-bindings.cabal
@@ -1,5 +1,5 @@
 name:                casadi-bindings
-version:             2.2.0.3
+version:             2.2.0.4
 synopsis:            mid-level bindings to CasADi
 category:            Numerical, Math
 description:
@@ -39,7 +39,8 @@
 
 library
   hs-source-dirs:      src
-  exposed-modules:     Casadi.Callback
+  exposed-modules:     Casadi.CMatrix
+                       Casadi.Callback
                        Casadi.DMatrix
                        Casadi.Function
                        Casadi.GenericC
diff --git a/src/Casadi/CMatrix.hs b/src/Casadi/CMatrix.hs
new file mode 100644
--- /dev/null
+++ b/src/Casadi/CMatrix.hs
@@ -0,0 +1,67 @@
+{-# OPTIONS_GHC -Wall #-}
+
+module Casadi.CMatrix
+       ( CMatrix(..)
+       , vertslice, horzslice
+       ) where
+
+import qualified Data.Vector as V
+
+import Casadi.Core.Classes.DMatrix ( DMatrix )
+
+import Casadi.Overloading ( Fmod, ArcTan2, SymOrd, Erf )
+import Casadi.Sparsity ( Sparsity )
+import Casadi.Slice ( Slice, slice )
+
+class (Eq a, Show a, Floating a, Fmod a, ArcTan2 a, SymOrd a, Erf a) => CMatrix a where
+  vertsplit :: a -> V.Vector Int -> V.Vector a
+  vertcat :: V.Vector a -> a
+  horzsplit :: a -> V.Vector Int -> V.Vector a
+  horzcat :: V.Vector a -> a
+  veccat :: V.Vector a -> a
+  size1 :: a -> Int
+  size2 :: a -> Int
+  numel :: a -> Int
+  -- | matrix matrix product
+  mm :: a -> a -> a
+  -- | sumAll(x*y), x and y same dimension
+  innerProd :: a -> a -> a
+  -- | transpose
+  trans :: a -> a
+  diag :: a -> a
+  eye :: Int -> a
+  ones :: (Int,Int) -> a
+  zeros :: (Int,Int) -> a
+  zerosSp :: Sparsity -> a
+  solve :: a -> a -> a
+  indexed :: a -> Slice -> Slice -> a
+  sparsity :: a -> Sparsity
+  getNZ :: a -> Slice -> a
+  setNZ :: a -> a -> Slice -> IO ()
+  triu :: a -> a
+  tril :: a -> a
+  triu2symm :: a -> a
+  tril2symm :: a -> a
+  copy :: a -> IO a
+  dense :: a -> a
+  fromDMatrix :: DMatrix -> a
+  fromDVector :: V.Vector Double -> a
+
+
+vertslice :: CMatrix a => a -> V.Vector Int -> V.Vector a
+vertslice x vs = V.fromList (f (V.toList vs))
+  where
+    cols = size2 x
+    hslice = slice 0 cols 1
+
+    f (v0:v1:others) = indexed x (slice v0 v1 1) hslice : f (v1:others)
+    f _ = []
+
+horzslice :: CMatrix a => a -> V.Vector Int -> V.Vector a
+horzslice x vs = V.fromList (f (V.toList vs))
+  where
+    rows = size1 x
+    vslice = slice 0 rows 1
+
+    f (v0:v1:others) = indexed x vslice (slice v0 v1 1) : f (v1:others)
+    f _ = []
diff --git a/src/Casadi/DMatrix.hs b/src/Casadi/DMatrix.hs
--- a/src/Casadi/DMatrix.hs
+++ b/src/Casadi/DMatrix.hs
@@ -1,160 +1,98 @@
 {-# OPTIONS_GHC -Wall -fno-cse -fno-warn-orphans #-}
 
 module Casadi.DMatrix
-       ( DMatrix, dcrs, dmm, dinnerProd, dvector, ddata, ddiag
-       , ddense, dsparsify, dtrans
-       , dtriu, dtril
-       , dtriu2symm, dtril2symm
-       , dsize, dsize1, dsize2, dnumel
-       , dvertcat, dhorzcat, dveccat, dvertsplit, dhorzsplit
-       , deye, dones, dzeros, dzerosSp
-       , dindexed
-       , dgetNZ, dsetNZ
-       , dcopy
+       ( DMatrix
+       , dsparsify
+       , ddata
        ) where
 
 import qualified Data.Vector as V
 import System.IO.Unsafe ( unsafePerformIO )
 import Linear.Conjugate ( Conjugate(..) )
 
-import Casadi.Core.Classes.Sparsity
 import Casadi.Core.Classes.DMatrix
-import Casadi.Core.Classes.Slice ( Slice )
+import qualified Casadi.Core.Tools as C
 
 import Casadi.Overloading ( Fmod(..), ArcTan2(..), SymOrd(..), Erf(..) )
+import Casadi.CMatrix ( CMatrix(..) )
 
 instance Conjugate DMatrix where
   conjugate = id
 
-instance Show DMatrix where
-  show x = unsafePerformIO (dmatrix_getDescription x)
-  {-# NOINLINE show #-}
-
-instance Eq DMatrix where
-  x == y = unsafePerformIO (dmatrix_zz_isEqual__0 x y)
-  {-# NOINLINE (==) #-}
-
--- | matrix matrix product
-dmm :: DMatrix -> DMatrix -> DMatrix
-dmm x y = unsafePerformIO (dmatrix_zz_mtimes__1 x y)
-{-# NOINLINE dmm #-}
-
--- | sumAll(x*y), x and y same dimension
-dinnerProd :: DMatrix -> DMatrix -> DMatrix
-dinnerProd x y = unsafePerformIO (dmatrix_zz_inner_prod x y)
-{-# NOINLINE dinnerProd #-}
-
--- | transpose
-dtrans :: DMatrix -> DMatrix
-dtrans x = unsafePerformIO (dmatrix_T x)
-{-# NOINLINE dtrans #-}
-
-ddense :: DMatrix -> DMatrix
-ddense x = unsafePerformIO (dmatrix_zz_dense x)
-{-# NOINLINE ddense #-}
-
 dsparsify :: DMatrix -> DMatrix
 dsparsify x = unsafePerformIO (dmatrix_zz_sparsify__0 x)
 {-# NOINLINE dsparsify #-}
 
-dcrs :: DMatrix -> Sparsity
-dcrs x = unsafePerformIO (dmatrix_sparsityRef__0 x)
-{-# NOINLINE dcrs #-}
-
-ddiag :: DMatrix -> DMatrix
-ddiag x = unsafePerformIO (dmatrix_zz_diag x)
-{-# NOINLINE ddiag #-}
-
--- | from vector
-dvector :: V.Vector Double -> DMatrix
-dvector x = unsafePerformIO (dmatrix__4 x)
-{-# NOINLINE dvector #-}
-
 ddata :: DMatrix -> V.Vector Double
 ddata x = unsafePerformIO (dmatrix_data__0 x)
 {-# NOINLINE ddata #-}
 
-dsize :: DMatrix -> Int
-dsize x = unsafePerformIO (dmatrix_size__1 x)
-{-# NOINLINE dsize #-}
-
-dsize1 :: DMatrix -> Int
-dsize1 x = unsafePerformIO (dmatrix_size1 x)
-{-# NOINLINE dsize1 #-}
-
-dsize2 :: DMatrix -> Int
-dsize2 x = unsafePerformIO (dmatrix_size2 x)
-{-# NOINLINE dsize2 #-}
-
-dnumel :: DMatrix -> Int
-dnumel x = unsafePerformIO (dmatrix_numel__1 x)
-{-# NOINLINE dnumel #-}
-
-dvertcat :: V.Vector DMatrix -> DMatrix
-dvertcat x = unsafePerformIO (dmatrix_zz_vertcat x)
-{-# NOINLINE dvertcat #-}
-
-dveccat :: V.Vector DMatrix -> DMatrix
-dveccat x = unsafePerformIO (dmatrix_zz_veccat x)
-{-# NOINLINE dveccat #-}
-
-dvertsplit :: DMatrix -> V.Vector Int -> V.Vector DMatrix
-dvertsplit x ks = unsafePerformIO (dmatrix_zz_vertsplit x ks)
-{-# NOINLINE dvertsplit #-}
-
-dhorzsplit :: DMatrix -> V.Vector Int -> V.Vector DMatrix
-dhorzsplit x ks = unsafePerformIO (dmatrix_zz_horzsplit x ks)
-{-# NOINLINE dhorzsplit #-}
-
-dhorzcat :: V.Vector DMatrix -> DMatrix
-dhorzcat x = unsafePerformIO (dmatrix_zz_horzcat x)
-{-# NOINLINE dhorzcat #-}
-
-dtriu :: DMatrix -> DMatrix
-dtriu x = unsafePerformIO (dmatrix_zz_triu__0 x)
-{-# NOINLINE dtriu #-}
-
-dtril :: DMatrix -> DMatrix
-dtril x = unsafePerformIO (dmatrix_zz_tril__0 x)
-{-# NOINLINE dtril #-}
-
-dtriu2symm :: DMatrix -> DMatrix
-dtriu2symm x = unsafePerformIO (dmatrix_zz_triu2symm x)
-{-# NOINLINE dtriu2symm #-}
-
-dtril2symm :: DMatrix -> DMatrix
-dtril2symm x = unsafePerformIO (dmatrix_zz_tril2symm x)
-{-# NOINLINE dtril2symm #-}
-
-deye :: Int -> DMatrix
-deye n = unsafePerformIO (dmatrix_eye n)
-{-# NOINLINE deye #-}
-
-dones :: (Int,Int) -> DMatrix
-dones (r,c) = unsafePerformIO (dmatrix_ones__3 r c)
-{-# NOINLINE dones #-}
-
-dzeros :: (Int,Int) -> DMatrix
-dzeros (r,c) = unsafePerformIO (dmatrix_zeros__3 r c)
-{-# NOINLINE dzeros #-}
-
-dzerosSp :: Sparsity -> DMatrix
-dzerosSp sp = unsafePerformIO (dmatrix_zeros__0 sp)
-{-# NOINLINE dzerosSp #-}
-
-dindexed :: DMatrix -> Slice -> Slice -> DMatrix
-dindexed m sx sy = unsafePerformIO (dmatrix_getSub__3 m False sx sy)
-{-# NOINLINE dindexed #-}
-
-dgetNZ :: DMatrix -> Slice -> DMatrix
-dgetNZ m s = unsafePerformIO (dmatrix_getNZ__1 m False s)
-{-# NOINLINE dgetNZ #-}
+instance Show DMatrix where
+  show x = unsafePerformIO (dmatrix_getDescription x)
+  {-# NOINLINE show #-}
 
-dsetNZ :: DMatrix -> DMatrix -> Slice -> IO ()
-dsetNZ m y s = dmatrix_setNZ__1 m y False s
+instance Eq DMatrix where
+  x == y = unsafePerformIO (dmatrix_zz_isEqual__0 x y)
+  {-# NOINLINE (==) #-}
 
-dcopy :: DMatrix -> IO DMatrix
-dcopy m = dmatrix__10 m
+instance CMatrix DMatrix where
+  veccat x = unsafePerformIO (dmatrix_zz_veccat x)
+  {-# NOINLINE veccat #-}
+  ----  vertsplit = vertslice
+  vertsplit x ks = unsafePerformIO (dmatrix_zz_vertsplit x ks)
+  {-# NOINLINE vertsplit #-}
+  vertcat x = unsafePerformIO (dmatrix_zz_vertcat x)
+  {-# NOINLINE vertcat #-}
+  --  horzsplit = horzslice
+  horzsplit x ks = unsafePerformIO (dmatrix_zz_horzsplit x ks)
+  {-# NOINLINE horzsplit #-}
+  horzcat x = unsafePerformIO (dmatrix_zz_horzcat x)
+  {-# NOINLINE horzcat #-}
+  size1 x = unsafePerformIO (dmatrix_size1 x)
+  {-# NOINLINE size1 #-}
+  size2 x = unsafePerformIO (dmatrix_size2 x)
+  {-# NOINLINE size2 #-}
+  numel x = unsafePerformIO (dmatrix_numel__1 x)
+  {-# NOINLINE numel #-}
+  mm x y = unsafePerformIO (dmatrix_zz_mtimes__1 x y)
+  {-# NOINLINE mm #-}
+  innerProd x y = unsafePerformIO (dmatrix_zz_inner_prod x y)
+  {-# NOINLINE innerProd #-}
+  trans x = unsafePerformIO (dmatrix_T x)
+  {-# NOINLINE trans #-}
+  diag x = unsafePerformIO (dmatrix_zz_diag x)
+  {-# NOINLINE diag #-}
+  eye n = unsafePerformIO (dmatrix_eye n)
+  {-# NOINLINE eye #-}
+  ones (r,c) = unsafePerformIO (dmatrix_ones__3 r c)
+  {-# NOINLINE ones #-}
+  zeros (r,c) = unsafePerformIO (dmatrix_zeros__3 r c)
+  {-# NOINLINE zeros #-}
+  zerosSp sp = unsafePerformIO (dmatrix_zeros__0 sp)
+  {-# NOINLINE zerosSp #-}
+  solve x y = unsafePerformIO (C.solve__3 x y)
+  {-# NOINLINE solve #-}
+  indexed m sx sy = unsafePerformIO (dmatrix_getSub__3 m False sx sy)
+  {-# NOINLINE indexed #-}
+  sparsity x = unsafePerformIO (dmatrix_sparsityRef__0 x)
+  {-# NOINLINE sparsity #-}
+  getNZ m s = unsafePerformIO (dmatrix_getNZ__1 m False s)
+  {-# NOINLINE getNZ #-}
+  setNZ m y s = dmatrix_setNZ__1 m y False s
+  triu x = unsafePerformIO (dmatrix_zz_triu__0 x)
+  {-# NOINLINE triu #-}
+  tril x = unsafePerformIO (dmatrix_zz_tril__0 x)
+  {-# NOINLINE tril #-}
+  triu2symm  x = unsafePerformIO (dmatrix_zz_triu2symm x)
+  {-# NOINLINE triu2symm #-}
+  tril2symm x = unsafePerformIO (dmatrix_zz_tril2symm x)
+  {-# NOINLINE tril2symm #-}
+  copy m = dmatrix__10 m
+  dense x = unsafePerformIO (dmatrix_zz_dense x)
+  {-# NOINLINE dense #-}
+  fromDMatrix = id
+  fromDVector x = unsafePerformIO (dmatrix__4 x)
+  {-# NOINLINE fromDVector #-}
 
 instance Num DMatrix where
   (+) x y = unsafePerformIO (dmatrix_zz_plus x y)
@@ -225,7 +163,6 @@
   {-# NOINLINE geq #-}
   x  `eq` y = unsafePerformIO (dmatrix_zz_eq x y)
   {-# NOINLINE eq #-}
-
 
 instance Erf DMatrix where
   erf x = unsafePerformIO (dmatrix_zz_erf x)
diff --git a/src/Casadi/MX.hs b/src/Casadi/MX.hs
--- a/src/Casadi/MX.hs
+++ b/src/Casadi/MX.hs
@@ -1,34 +1,21 @@
 {-# OPTIONS_GHC -Wall -fno-cse -fno-warn-orphans #-}
 
 module Casadi.MX
-       ( MX, sym, symV, symM, mm, innerProd, trans, diag
-       , gradient, jacobian -- , hessian
-       , solve
+       ( MX
+       , sym, symV, symM, gradient, jacobian -- , hessian
        , expand
-       , triu, tril
-       , triu2symm, tril2symm
-       , dense --, sparse
-       , d2m
-       , size, size1, size2, numel
-       , crs, vertcat, horzcat, veccat, vertsplit, horzsplit
-       , eye, ones, zeros, zerosSp
-       , indexed
-       , getNZ, setNZ
-       , copy
        ) where
 
 import Data.Vector ( Vector )
-import qualified Data.Vector as V
 import System.IO.Unsafe ( unsafePerformIO )
 import Linear.Conjugate ( Conjugate(..) )
 
 import Casadi.Core.Classes.MX
-import Casadi.Core.Classes.DMatrix ( DMatrix )
-import Casadi.Core.Classes.Sparsity ( Sparsity )
-import Casadi.Core.Classes.Slice ( Slice )
 import qualified Casadi.Core.Tools as C
 
 import Casadi.Overloading ( Fmod(..), ArcTan2(..), SymOrd(..), Erf(..) )
+import Casadi.CMatrix ( CMatrix(..) )
+import Casadi.DMatrix ()
 import Casadi.SharedObject ( castSharedObject )
 
 instance Conjugate MX where
@@ -65,132 +52,74 @@
 expand x = unsafePerformIO (C.matrix_expand__0 x)
 {-# NOINLINE expand #-}
 
-solve :: MX -> MX -> MX
-solve a b = unsafePerformIO (C.solve__0 a b)
-{-# NOINLINE solve #-}
-
 ---- | @hessian exp x@ is the jacobian of exp w.r.t. x
 --hessian :: MX -> MX -> MX
 --hessian x y = unsafePerformIO (C.hessian x y)
 --{-# NOINLINE hessian #-}
 
-d2m :: DMatrix -> MX
-d2m x = unsafePerformIO (mx__0 x)
-{-# NOINLINE d2m #-}
-
--- | matrix matrix product
-mm :: MX -> MX -> MX
-mm x y = unsafePerformIO (mx_zz_mtimes__1 x y)
-{-# NOINLINE mm #-}
-
--- | sumAll(x*y), x and y same dimension
-innerProd :: MX -> MX -> MX
-innerProd x y = unsafePerformIO (mx_zz_inner_prod x y)
-{-# NOINLINE innerProd #-}
-
--- | transpose
-trans :: MX -> MX
-trans x = unsafePerformIO (mx_T x)
-{-# NOINLINE trans #-}
-
-dense :: MX -> MX
-dense x = unsafePerformIO (mx_zz_dense x)
-{-# NOINLINE dense #-}
-
 --sparsify :: MX -> MX
 --sparsify x = unsafePerformIO (mx_zz_sparsify__0 x)
 --{-# NOINLINE sparsify #-}
 
-triu :: MX -> MX
-triu x = unsafePerformIO (mx_zz_triu__0 x)
-{-# NOINLINE triu #-}
-
-tril :: MX -> MX
-tril x = unsafePerformIO (mx_zz_tril__0 x)
-{-# NOINLINE tril #-}
-
-triu2symm :: MX -> MX
-triu2symm x = unsafePerformIO (mx_zz_triu2symm x)
-{-# NOINLINE triu2symm #-}
-
-tril2symm :: MX -> MX
-tril2symm x = unsafePerformIO (mx_zz_tril2symm x)
-{-# NOINLINE tril2symm #-}
-
-diag :: MX -> MX
-diag x = unsafePerformIO (mx_zz_diag x)
-{-# NOINLINE diag #-}
-
-crs :: MX -> Sparsity
-crs x = unsafePerformIO (mx_sparsityRef__0 x)
-{-# NOINLINE crs #-}
-
--- | from MXElement vector
-size :: MX -> Int
-size x = unsafePerformIO (mx_size__1 x)
-{-# NOINLINE size #-}
-
-size1 :: MX -> Int
-size1 x = unsafePerformIO (mx_size1 x)
-{-# NOINLINE size1 #-}
-
-size2 :: MX -> Int
-size2 x = unsafePerformIO (mx_size2 x)
-{-# NOINLINE size2 #-}
-
-numel :: MX -> Int
-numel x = unsafePerformIO (mx_numel__1 x)
-{-# NOINLINE numel #-}
-
-vertcat :: V.Vector MX -> MX
-vertcat x = unsafePerformIO (mx_zz_vertcat x)
-{-# NOINLINE vertcat #-}
-
-veccat :: V.Vector MX -> MX
-veccat x = unsafePerformIO (mx_zz_veccat x)
-{-# NOINLINE veccat #-}
-
-vertsplit :: MX -> V.Vector Int -> V.Vector MX
-vertsplit x ks = unsafePerformIO (mx_zz_vertsplit x ks)
-{-# NOINLINE vertsplit #-}
-
-horzsplit :: MX -> V.Vector Int -> V.Vector MX
-horzsplit x ks = unsafePerformIO (mx_zz_horzsplit x ks)
-{-# NOINLINE horzsplit #-}
-
-horzcat :: V.Vector MX -> MX
-horzcat x = unsafePerformIO (mx_zz_horzcat x)
-{-# NOINLINE horzcat #-}
-
-eye :: Int -> MX
-eye n = unsafePerformIO (mx_eye n)
-{-# NOINLINE eye #-}
-
-ones :: (Int,Int) -> MX
-ones (r,c) = unsafePerformIO (mx_ones__3 r c)
-{-# NOINLINE ones #-}
-
-zeros :: (Int,Int) -> MX
-zeros (r,c) = unsafePerformIO (mx_zeros__3 r c)
-{-# NOINLINE zeros #-}
-
-zerosSp :: Sparsity -> MX
-zerosSp sp = unsafePerformIO (mx_zeros__0 sp)
-{-# NOINLINE zerosSp #-}
-
-indexed :: MX -> Slice -> Slice -> MX
-indexed m sx sy = unsafePerformIO (mx_getSub__3 m False sx sy)
-{-# NOINLINE indexed #-}
-
-getNZ :: MX -> Slice -> MX
-getNZ m s = unsafePerformIO (mx_getNZ__1 m False s)
-{-# NOINLINE getNZ #-}
-
-setNZ :: MX -> MX -> Slice -> IO ()
-setNZ m y s = mx_setNZ__1 m y False s
-
-copy :: MX -> IO MX
-copy m = mx__2 m
+instance CMatrix MX where
+  veccat x = unsafePerformIO (mx_zz_veccat x)
+  {-# NOINLINE veccat #-}
+  --  vertsplit = vertslice
+  vertsplit x ks = unsafePerformIO (mx_zz_vertsplit x ks)
+  {-# NOINLINE vertsplit #-}
+  vertcat x = unsafePerformIO (mx_zz_vertcat x)
+  {-# NOINLINE vertcat #-}
+  --  horzsplit = horzslice
+  horzsplit x ks = unsafePerformIO (mx_zz_horzsplit x ks)
+  {-# NOINLINE horzsplit #-}
+  horzcat x = unsafePerformIO (mx_zz_horzcat x)
+  {-# NOINLINE horzcat #-}
+  size1 x = unsafePerformIO (mx_size1 x)
+  {-# NOINLINE size1 #-}
+  size2 x = unsafePerformIO (mx_size2 x)
+  {-# NOINLINE size2 #-}
+  numel x = unsafePerformIO (mx_numel__1 x)
+  {-# NOINLINE numel #-}
+  mm x y = unsafePerformIO (mx_zz_mtimes__1 x y)
+  {-# NOINLINE mm #-}
+  innerProd x y = unsafePerformIO (mx_zz_inner_prod x y)
+  {-# NOINLINE innerProd #-}
+  trans x = unsafePerformIO (mx_T x)
+  {-# NOINLINE trans #-}
+  diag x = unsafePerformIO (mx_zz_diag x)
+  {-# NOINLINE diag #-}
+  eye n = unsafePerformIO (mx_eye n)
+  {-# NOINLINE eye #-}
+  ones (r,c) = unsafePerformIO (mx_ones__3 r c)
+  {-# NOINLINE ones #-}
+  zeros (r,c) = unsafePerformIO (mx_zeros__3 r c)
+  {-# NOINLINE zeros #-}
+  zerosSp sp = unsafePerformIO (mx_zeros__0 sp)
+  {-# NOINLINE zerosSp #-}
+  solve a b = unsafePerformIO (C.solve__0 a b)
+  {-# NOINLINE solve #-}
+  indexed m sx sy = unsafePerformIO (mx_getSub__3 m False sx sy)
+  {-# NOINLINE indexed #-}
+  sparsity x = unsafePerformIO (mx_sparsityRef__0 x)
+  {-# NOINLINE sparsity #-}
+  getNZ m s = unsafePerformIO (mx_getNZ__1 m False s)
+  {-# NOINLINE getNZ #-}
+  setNZ m y s = mx_setNZ__1 m y False s
+  triu x = unsafePerformIO (mx_zz_triu__0 x)
+  {-# NOINLINE triu #-}
+  tril x = unsafePerformIO (mx_zz_tril__0 x)
+  {-# NOINLINE tril #-}
+  triu2symm x = unsafePerformIO (mx_zz_triu2symm x)
+  {-# NOINLINE triu2symm #-}
+  tril2symm x = unsafePerformIO (mx_zz_tril2symm x)
+  {-# NOINLINE tril2symm #-}
+  copy m = mx__2 m
+  dense x = unsafePerformIO (mx_zz_dense x)
+  {-# NOINLINE dense #-}
+  fromDMatrix x = unsafePerformIO (mx__0 x)
+  {-# NOINLINE fromDMatrix #-}
+  fromDVector x = fromDMatrix (fromDVector x)
+  {-# NOINLINE fromDVector #-}
 
 instance Num MX where
   (+) x y = unsafePerformIO (mx_zz_plus x y)
diff --git a/src/Casadi/SX.hs b/src/Casadi/SX.hs
--- a/src/Casadi/SX.hs
+++ b/src/Casadi/SX.hs
@@ -1,32 +1,20 @@
 {-# OPTIONS_GHC -Wall -fno-cse -fno-warn-orphans #-}
 
 module Casadi.SX
-       ( SX, ssym, ssymV, ssymM, smm, sinnerProd, strans
-       , sgradient, sjacobian, shessian, sdiag
-       , ssolve
-       , striu, stril
-       , striu2symm, stril2symm
-       , sdense, ssparsify
-       , d2s
-       , ssize, ssize1, ssize2, snumel
-       , scrs, svertcat, shorzcat, sveccat, svertsplit, shorzsplit
-       , seye, sones, szeros, szerosSp
-       , sindexed
-       , sgetNZ, ssetNZ
-       , scopy
+       ( SX
+       , ssym, ssymV, ssymM, sgradient, sjacobian, shessian
+       , ssparsify
        ) where
 
-import qualified Data.Vector as V
 import System.IO.Unsafe ( unsafePerformIO )
 import Linear.Conjugate ( Conjugate(..) )
 
 import Casadi.Core.Classes.SX
-import Casadi.Core.Classes.DMatrix ( DMatrix )
-import Casadi.Core.Classes.Sparsity ( Sparsity )
-import Casadi.Core.Classes.Slice ( Slice )
 import qualified Casadi.Core.Tools as C
 
 import Casadi.Overloading ( Fmod(..), ArcTan2(..), SymOrd(..), Erf(..) )
+import Casadi.CMatrix ( CMatrix(..) )
+import Casadi.DMatrix ()
 
 instance Show SX where
   show x = unsafePerformIO (sx_getDescription x)
@@ -63,126 +51,70 @@
 shessian x y = unsafePerformIO (C.hessian__1 x y)
 {-# NOINLINE shessian #-}
 
--- | matrix matrix product
-smm :: SX -> SX -> SX
-smm x y = unsafePerformIO (sx_zz_mtimes__1 x y)
-{-# NOINLINE smm #-}
-
--- | sumAll(x*y), x and y same dimension
-sinnerProd :: SX -> SX -> SX
-sinnerProd x y = unsafePerformIO (sx_zz_inner_prod x y)
-{-# NOINLINE sinnerProd #-}
-
-d2s :: DMatrix -> SX
-d2s x = unsafePerformIO (sx__2 x)
-{-# NOINLINE d2s #-}
-
-sdiag :: SX -> SX
-sdiag x = unsafePerformIO (sx_zz_diag x)
-{-# NOINLINE sdiag #-}
-
--- | transpose
-strans :: SX -> SX
-strans x = unsafePerformIO (sx_T x)
-{-# NOINLINE strans #-}
-
-sdense :: SX -> SX
-sdense x = unsafePerformIO (sx_zz_dense x)
-{-# NOINLINE sdense #-}
-
 ssparsify :: SX -> SX
 ssparsify x = unsafePerformIO (sx_zz_sparsify__0 x)
 {-# NOINLINE ssparsify #-}
 
-striu :: SX -> SX
-striu x = unsafePerformIO (sx_zz_triu__0 x)
-{-# NOINLINE striu #-}
-
-stril :: SX -> SX
-stril x = unsafePerformIO (sx_zz_tril__0 x)
-{-# NOINLINE stril #-}
-
-striu2symm :: SX -> SX
-striu2symm x = unsafePerformIO (sx_zz_triu2symm x)
-{-# NOINLINE striu2symm #-}
-
-stril2symm :: SX -> SX
-stril2symm x = unsafePerformIO (sx_zz_tril2symm x)
-{-# NOINLINE stril2symm #-}
-
-scrs :: SX -> Sparsity
-scrs x = unsafePerformIO (sx_sparsityRef__0 x)
-{-# NOINLINE scrs #-}
-
-ssize :: SX -> Int
-ssize x = unsafePerformIO (sx_size__1 x)
-{-# NOINLINE ssize #-}
-
-ssize1 :: SX -> Int
-ssize1 x = unsafePerformIO (sx_size1 x)
-{-# NOINLINE ssize1 #-}
-
-ssize2 :: SX -> Int
-ssize2 x = unsafePerformIO (sx_size2 x)
-{-# NOINLINE ssize2 #-}
-
-snumel :: SX -> Int
-snumel x = unsafePerformIO (sx_numel__1 x)
-{-# NOINLINE snumel #-}
-
-svertcat :: V.Vector SX -> SX
-svertcat x = unsafePerformIO (sx_zz_vertcat x)
-{-# NOINLINE svertcat #-}
-
-shorzcat :: V.Vector SX -> SX
-shorzcat x = unsafePerformIO (sx_zz_horzcat x)
-{-# NOINLINE shorzcat #-}
-
-sveccat :: V.Vector SX -> SX
-sveccat x = unsafePerformIO (sx_zz_veccat x)
-{-# NOINLINE sveccat #-}
-
-svertsplit :: SX -> V.Vector Int -> V.Vector SX
-svertsplit x ks = unsafePerformIO (sx_zz_vertsplit x ks)
-{-# NOINLINE svertsplit #-}
-
-shorzsplit :: SX -> V.Vector Int -> V.Vector SX
-shorzsplit x ks = unsafePerformIO (sx_zz_horzsplit x ks)
-{-# NOINLINE shorzsplit #-}
-
-ssolve :: SX -> SX -> SX
-ssolve a b = unsafePerformIO (C.solve__2 a b)
-{-# NOINLINE ssolve #-}
-
-seye :: Int -> SX
-seye n = unsafePerformIO (sx_eye n)
-{-# NOINLINE seye #-}
-
-sones :: (Int,Int) -> SX
-sones (r,c) = unsafePerformIO (sx_ones__3 r c)
-{-# NOINLINE sones #-}
-
-szeros :: (Int,Int) -> SX
-szeros (r,c) = unsafePerformIO (sx_zeros__3 r c)
-{-# NOINLINE szeros #-}
-
-szerosSp :: Sparsity -> SX
-szerosSp sp = unsafePerformIO (sx_zeros__0 sp)
-{-# NOINLINE szerosSp #-}
-
-sindexed :: SX -> Slice -> Slice -> SX
-sindexed m sx sy = unsafePerformIO (sx_getSub__3 m False sx sy)
-{-# NOINLINE sindexed #-}
-
-sgetNZ :: SX -> Slice -> SX
-sgetNZ m s = unsafePerformIO (sx_getNZ__1 m False s)
-{-# NOINLINE sgetNZ #-}
-
-ssetNZ :: SX -> SX -> Slice -> IO ()
-ssetNZ m y s = sx_setNZ__1 m y False s
+instance CMatrix SX where
+  veccat x = unsafePerformIO (sx_zz_veccat x)
+  {-# NOINLINE veccat #-}
+  --  vertsplit = vertslice
+  vertsplit x ks = unsafePerformIO (sx_zz_vertsplit x ks)
+  {-# NOINLINE vertsplit #-}
+  vertcat x = unsafePerformIO (sx_zz_vertcat x)
+  {-# NOINLINE vertcat #-}
+  --  horzsplit = horzslice
+  horzsplit x ks = unsafePerformIO (sx_zz_horzsplit x ks)
+  {-# NOINLINE horzsplit #-}
+  horzcat x = unsafePerformIO (sx_zz_horzcat x)
+  {-# NOINLINE horzcat #-}
+  size1 x = unsafePerformIO (sx_size1 x)
+  {-# NOINLINE size1 #-}
+  size2 x = unsafePerformIO (sx_size2 x)
+  {-# NOINLINE size2 #-}
+  numel x = unsafePerformIO (sx_numel__1 x)
+  {-# NOINLINE numel #-}
+  mm x y = unsafePerformIO (sx_zz_mtimes__1 x y)
+  {-# NOINLINE mm #-}
+  innerProd x y = unsafePerformIO (sx_zz_inner_prod x y)
+  {-# NOINLINE innerProd #-}
+  trans x = unsafePerformIO (sx_T x)
+  {-# NOINLINE trans #-}
+  diag x = unsafePerformIO (sx_zz_diag x)
+  {-# NOINLINE diag #-}
+  eye n = unsafePerformIO (sx_eye n)
+  {-# NOINLINE eye #-}
+  ones (r,c) = unsafePerformIO (sx_ones__3 r c)
+  {-# NOINLINE ones #-}
+  zeros (r,c) = unsafePerformIO (sx_zeros__3 r c)
+  {-# NOINLINE zeros #-}
+  zerosSp sp = unsafePerformIO (sx_zeros__0 sp)
+  {-# NOINLINE zerosSp #-}
+  solve a b = unsafePerformIO (C.solve__2 a b)
+  {-# NOINLINE solve #-}
+  indexed m sx sy = unsafePerformIO (sx_getSub__3 m False sx sy)
+  {-# NOINLINE indexed #-}
+  sparsity x = unsafePerformIO (sx_sparsityRef__0 x)
+  {-# NOINLINE sparsity #-}
+  getNZ m s = unsafePerformIO (sx_getNZ__1 m False s)
+  {-# NOINLINE getNZ #-}
+  setNZ m y s = sx_setNZ__1 m y False s
+  triu x = unsafePerformIO (sx_zz_triu__0 x)
+  {-# NOINLINE triu #-}
+  tril x = unsafePerformIO (sx_zz_tril__0 x)
+  {-# NOINLINE tril #-}
+  triu2symm x = unsafePerformIO (sx_zz_triu2symm x)
+  {-# NOINLINE triu2symm #-}
+  tril2symm x = unsafePerformIO (sx_zz_tril2symm x)
+  {-# NOINLINE tril2symm #-}
+  copy m = sx__12 m
+  dense x = unsafePerformIO (sx_zz_dense x)
+  {-# NOINLINE dense #-}
+  fromDMatrix x = unsafePerformIO (sx__2 x)
+  {-# NOINLINE fromDMatrix #-}
+  fromDVector x = fromDMatrix (fromDVector x)
+  {-# NOINLINE fromDVector #-}
 
-scopy :: SX -> IO SX
-scopy m = sx__12 m
 
 instance Num SX where
   (+) x y = unsafePerformIO (sx_zz_plus x y)
