/* Generated by Cython 0.10.1 on Sun Jan 25 19:43:28 2009 */

#define PY_SSIZE_T_CLEAN
#include "Python.h"
#include "structmember.h"
#ifndef PY_LONG_LONG
  #define PY_LONG_LONG LONG_LONG
#endif
#ifndef DL_EXPORT
  #define DL_EXPORT(t) t
#endif
#if PY_VERSION_HEX < 0x02040000
  #define METH_COEXIST 0
#endif
#if PY_VERSION_HEX < 0x02050000
  typedef int Py_ssize_t;
  #define PY_SSIZE_T_MAX INT_MAX
  #define PY_SSIZE_T_MIN INT_MIN
  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)
  #define PyNumber_Index(o)    PyNumber_Int(o)
  #define PyIndex_Check(o)     PyNumber_Check(o)
#endif
#if PY_VERSION_HEX < 0x02060000
  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
  #define PyVarObject_HEAD_INIT(type, size) \
          PyObject_HEAD_INIT(type) size,
  #define PyType_Modified(t)

  typedef struct {
       void *buf;
       PyObject *obj;
       Py_ssize_t len;
       Py_ssize_t itemsize;
       int readonly;
       int ndim;
       char *format;
       Py_ssize_t *shape;
       Py_ssize_t *strides;
       Py_ssize_t *suboffsets;
       void *internal;
  } Py_buffer;

  #define PyBUF_SIMPLE 0
  #define PyBUF_WRITABLE 0x0001
  #define PyBUF_LOCK 0x0002
  #define PyBUF_FORMAT 0x0004
  #define PyBUF_ND 0x0008
  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)

#endif
#if PY_MAJOR_VERSION < 3
  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
#if PY_MAJOR_VERSION >= 3
  #define Py_TPFLAGS_CHECKTYPES 0
  #define Py_TPFLAGS_HAVE_INDEX 0
#endif
#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
#if PY_MAJOR_VERSION >= 3
  #define PyBaseString_Type            PyUnicode_Type
  #define PyString_Type                PyBytes_Type
  #define PyInt_Type                   PyLong_Type
  #define PyInt_Check(op)              PyLong_Check(op)
  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
  #define PyInt_FromString             PyLong_FromString
  #define PyInt_FromUnicode            PyLong_FromUnicode
  #define PyInt_FromLong               PyLong_FromLong
  #define PyInt_FromSize_t             PyLong_FromSize_t
  #define PyInt_FromSsize_t            PyLong_FromSsize_t
  #define PyInt_AsLong                 PyLong_AsLong
  #define PyInt_AS_LONG                PyLong_AS_LONG
  #define PyInt_AsSsize_t              PyLong_AsSsize_t
  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
#else
  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)
  #define PyBytes_Type                 PyString_Type
#endif
#if PY_MAJOR_VERSION >= 3
  #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)
#endif
#if !defined(WIN32) && !defined(MS_WINDOWS)
  #ifndef __stdcall
    #define __stdcall
  #endif
  #ifndef __cdecl
    #define __cdecl
  #endif
#else
  #define _USE_MATH_DEFINES
#endif
#ifdef __cplusplus
#define __PYX_EXTERN_C extern "C"
#else
#define __PYX_EXTERN_C extern
#endif
#include <math.h>
#define __PYX_HAVE_API__svd
#include "stdlib.h"
#include "numpy/arrayobject.h"


#ifdef __GNUC__
#define INLINE __inline__
#elif _WIN32
#define INLINE __inline
#else
#define INLINE 
#endif

typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/



static int __pyx_skip_dispatch = 0;


/* Type Conversion Predeclarations */

#if PY_MAJOR_VERSION < 3
#define __Pyx_PyBytes_FromString PyString_FromString
#define __Pyx_PyBytes_AsString   PyString_AsString
#else
#define __Pyx_PyBytes_FromString PyBytes_FromString
#define __Pyx_PyBytes_AsString   PyBytes_AsString
#endif

#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x);
static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x);
static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x);
static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b);

#define __pyx_PyInt_AsLong(x) (PyInt_CheckExact(x) ? PyInt_AS_LONG(x) : PyInt_AsLong(x))
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))

static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x);
static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x);
static INLINE char __pyx_PyInt_char(PyObject* x);
static INLINE short __pyx_PyInt_short(PyObject* x);
static INLINE int __pyx_PyInt_int(PyObject* x);
static INLINE long __pyx_PyInt_long(PyObject* x);
static INLINE signed char __pyx_PyInt_signed_char(PyObject* x);
static INLINE signed short __pyx_PyInt_signed_short(PyObject* x);
static INLINE signed int __pyx_PyInt_signed_int(PyObject* x);
static INLINE signed long __pyx_PyInt_signed_long(PyObject* x);
static INLINE long double __pyx_PyInt_long_double(PyObject* x);
#ifdef __GNUC__
/* Test for GCC > 2.95 */
#if __GNUC__ > 2 ||               (__GNUC__ == 2 && (__GNUC_MINOR__ > 95)) 
#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#else /* __GNUC__ > 2 ... */
#define likely(x)   (x)
#define unlikely(x) (x)
#endif /* __GNUC__ > 2 ... */
#else /* __GNUC__ */
#define likely(x)   (x)
#define unlikely(x) (x)
#endif /* __GNUC__ */
    
static PyObject *__pyx_m;
static PyObject *__pyx_b;
static PyObject *__pyx_empty_tuple;
static int __pyx_lineno;
static int __pyx_clineno = 0;
static const char * __pyx_cfilenm= __FILE__;
static const char *__pyx_filename;
static const char **__pyx_f;

static void __Pyx_RaiseDoubleKeywordsError(
    const char* func_name, PyObject* kw_name); /*proto*/

static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
    Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/

static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[],     PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args,     const char* function_name); /*proto*/
static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info);
static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/
static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/
static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/
static const char* __Pyx_DescribeTokenInFormatString(const char* ts); /*proto*/
static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_f32_t(const char* ts); /*proto*/

static int __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/

static void __Pyx_RaiseBufferFallbackError(void); /*proto*/

static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i32_t(const char* ts); /*proto*/

static int __Pyx_GetBuffer_nn___pyx_t_3svd_i32_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/
static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i16_t(const char* ts); /*proto*/

static int __Pyx_GetBuffer_nn___pyx_t_3svd_i16_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/
static void __Pyx_RaiseBufferIndexError(int axis); /*proto*/
#define __Pyx_BufPtrStrided1d(type, buf, i0, s0) (type)((char*)buf + i0 * s0)
#define __Pyx_BufPtrStrided2d(type, buf, i0, s0, i1, s1) (type)((char*)buf + i0 * s0 + i1 * s1)
static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i8_t(const char* ts); /*proto*/

static int __Pyx_GetBuffer_nn___pyx_t_3svd_i8_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/
static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i64_t(const char* ts); /*proto*/

static int __Pyx_GetBuffer_nn___pyx_t_3svd_i64_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast); /*proto*/

static INLINE PyObject *__Pyx_GetItemInt(PyObject *o, Py_ssize_t i, int is_unsigned) {
    PyObject *r;
    if (PyList_CheckExact(o) && 0 <= i && i < PyList_GET_SIZE(o)) {
        r = PyList_GET_ITEM(o, i);
        Py_INCREF(r);
    }
    else if (PyTuple_CheckExact(o) && 0 <= i && i < PyTuple_GET_SIZE(o)) {
        r = PyTuple_GET_ITEM(o, i);
        Py_INCREF(r);
    }
    else if (Py_TYPE(o)->tp_as_sequence && Py_TYPE(o)->tp_as_sequence->sq_item && (likely(i >= 0) || !is_unsigned))
        r = PySequence_GetItem(o, i);
    else {
        PyObject *j = (likely(i >= 0) || !is_unsigned) ? PyInt_FromLong(i) : PyLong_FromUnsignedLongLong((sizeof(unsigned long long) > sizeof(Py_ssize_t) ? (1ULL << (sizeof(Py_ssize_t)*8)) : 0) + i);
        if (!j)
            return 0;
        r = PyObject_GetItem(o, j);
        Py_DECREF(j);
    }
    return r;
}

static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
    const char *name, int exact); /*proto*/
#if PY_MAJOR_VERSION < 3
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags);
static void __Pyx_ReleaseBuffer(Py_buffer *view);
#else
#define __Pyx_GetBuffer PyObject_GetBuffer
#define __Pyx_ReleaseBuffer PyBuffer_Release
#endif

Py_ssize_t __Pyx_zeros[] = {0, 0};
Py_ssize_t __Pyx_minusones[] = {-1, -1};

static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/

static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/

static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/

static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/

static int __Pyx_Print(PyObject *, int); /*proto*/
#if PY_MAJOR_VERSION >= 3
static PyObject* __pyx_print = 0;
static PyObject* __pyx_print_kwargs = 0;
#endif

static INLINE PyObject* __Pyx_PyObject_Append(PyObject* L, PyObject* x) {
    if (likely(PyList_CheckExact(L))) {
        if (PyList_Append(L, x) < 0) return NULL;
        Py_INCREF(Py_None);
        return Py_None; // this is just to have an accurate signature
    }
    else {
        return PyObject_CallMethod(L, "append", "(O)", x);
    }
}

static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/

static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/

static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/

static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size);  /*proto*/

static PyObject *__Pyx_ImportModule(const char *name); /*proto*/

static void __Pyx_AddTraceback(const char *funcname); /*proto*/

static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/

/* Type declarations */

typedef npy_int8 __pyx_t_5numpy_int8_t;

typedef npy_int16 __pyx_t_5numpy_int16_t;

typedef npy_int32 __pyx_t_5numpy_int32_t;

typedef npy_int64 __pyx_t_5numpy_int64_t;

typedef npy_uint8 __pyx_t_5numpy_uint8_t;

typedef npy_uint16 __pyx_t_5numpy_uint16_t;

typedef npy_uint32 __pyx_t_5numpy_uint32_t;

typedef npy_uint64 __pyx_t_5numpy_uint64_t;

typedef npy_float32 __pyx_t_5numpy_float32_t;

typedef npy_float64 __pyx_t_5numpy_float64_t;

typedef npy_long __pyx_t_5numpy_int_t;

typedef npy_longlong __pyx_t_5numpy_long_t;

typedef npy_ulong __pyx_t_5numpy_uint_t;

typedef npy_ulonglong __pyx_t_5numpy_ulong_t;

typedef npy_double __pyx_t_5numpy_float_t;

typedef npy_double __pyx_t_5numpy_double_t;

typedef npy_longdouble __pyx_t_5numpy_longdouble_t;

typedef npy_cfloat __pyx_t_5numpy_cfloat_t;

typedef npy_cdouble __pyx_t_5numpy_cdouble_t;

typedef npy_clongdouble __pyx_t_5numpy_clongdouble_t;

typedef __pyx_t_5numpy_float64_t __pyx_t_3svd_f64_t;

typedef __pyx_t_5numpy_float32_t __pyx_t_3svd_f32_t;

typedef __pyx_t_5numpy_int8_t __pyx_t_3svd_i8_t;

typedef __pyx_t_5numpy_int16_t __pyx_t_3svd_i16_t;

typedef __pyx_t_5numpy_int32_t __pyx_t_3svd_i32_t;

typedef __pyx_t_5numpy_int64_t __pyx_t_3svd_i64_t;
/* Module declarations from cython */

/* Module declarations from python_buffer */

/* Module declarations from stdlib */

/* Module declarations from numpy */

/* Module declarations from numpy */

static PyTypeObject *__pyx_ptype_5numpy_dtype = 0;
static PyTypeObject *__pyx_ptype_5numpy_ndarray = 0;
/* Module declarations from svd */

static PyObject *__pyx_k_25;
static PyObject *__pyx_k_26;
static PyObject *__pyx_k_27;
static PyObject *__pyx_k_33;
static PyObject *__pyx_k_35;


/* Implementation of svd */
static char __pyx_k_23[] = "\n\tSVD is a class wrapping functionality implementing various matrix factorization algorithms,\n\tcurrently all of which are flavors of singular-value decompositions. They differ mostly in\n\thard constraints of feature values (e.g. non-negativity) and the inclusion of bias features.\n\t\n\tUsage:\n\t# first, build FlixData class data containers. \n\t# These are described and implemented in flixdata.py\n\t> modelname = '40fBRISMF'\n\ts = svd.SVD(fd, td, modelname)\n\t# Then, set the various parameters of the model\n\t> s.numfeatures = 40; s.lrateU = 0.007; s.lrateM = 0.005 #... etc\n\t\n\tThe matrices and logging information will be saved into a folder at the current directory,\n\tnamed after modelname.\n\t";
static char __pyx_k_36[] = "/home/alex/workspace/flix/results/";
static PyObject *__pyx_int_17770;
static PyObject *__pyx_int_12;
static PyObject *__pyx_int_2;
static PyObject *__pyx_int_100;
static PyObject *__pyx_int_123456789;
static PyObject *__pyx_int_0;
static PyObject *__pyx_int_1;
static PyObject *__pyx_int_480189;
static char __pyx_k_self[] = "self";
static PyObject *__pyx_kp_self;
static char __pyx_k_fd[] = "fd";
static PyObject *__pyx_kp_fd;
static char __pyx_k_td[] = "td";
static PyObject *__pyx_kp_td;
static char __pyx_k_qd[] = "qd";
static PyObject *__pyx_kp_qd;
static char __pyx_k_modelname[] = "modelname";
static PyObject *__pyx_kp_modelname;
static char __pyx_k_overwrite[] = "overwrite";
static PyObject *__pyx_kp_overwrite;
static char __pyx_k_message[] = "message";
static PyObject *__pyx_kp_message;
static char __pyx_k_displaytext[] = "displaytext";
static PyObject *__pyx_kp_displaytext;
static char __pyx_k_havemats[] = "havemats";
static PyObject *__pyx_kp_havemats;
static char __pyx_k_userIDsForUsers[] = "userIDsForUsers";
static PyObject *__pyx_kp_userIDsForUsers;
static char __pyx_k_movieIDs[] = "movieIDs";
static PyObject *__pyx_kp_movieIDs;
static char __pyx_k_predicttype[] = "predicttype";
static PyObject *__pyx_kp_predicttype;
static char __pyx_k_U[] = "U";
static PyObject *__pyx_kp_U;
static char __pyx_k_M[] = "M";
static PyObject *__pyx_kp_M;
static char __pyx_k_userRatings[] = "userRatings";
static PyObject *__pyx_kp_userRatings;
static char __pyx_k_movieRatings[] = "movieRatings";
static PyObject *__pyx_kp_movieRatings;
static char __pyx_k_userIDs[] = "userIDs";
static PyObject *__pyx_kp_userIDs;
static char __pyx_k_fraction[] = "fraction";
static PyObject *__pyx_kp_fraction;
static char __pyx_k_loadarrays[] = "loadarrays";
static PyObject *__pyx_kp_loadarrays;
static char __pyx_k_resultdir[] = "resultdir";
static PyObject *__pyx_kp_resultdir;
static char __pyx_k_numpy[] = "numpy";
static PyObject *__pyx_kp_numpy;
static char __pyx_k_N[] = "N";
static PyObject *__pyx_kp_N;
static char __pyx_k_SVD[] = "SVD";
static PyObject *__pyx_kp_SVD;
static char __pyx_k_object[] = "object";
static PyObject *__pyx_kp_object;
static char __pyx_k_24[] = "untitled_model";
static PyObject *__pyx_kp_24;
static char __pyx_k___init__[] = "__init__";
static PyObject *__pyx_kp___init__;
static char __pyx_k_startSVDLog[] = "startSVDLog";
static PyObject *__pyx_kp_startSVDLog;
static char __pyx_k_updateLog[] = "updateLog";
static PyObject *__pyx_kp_updateLog;
static char __pyx_k_svd[] = "svd";
static PyObject *__pyx_kp_svd;
static char __pyx_k_28[] = "probe";
static PyObject *__pyx_kp_28;
static char __pyx_k_makeProbePrediction[] = "makeProbePrediction";
static PyObject *__pyx_kp_makeProbePrediction;
static char __pyx_k_checkError[] = "checkError";
static PyObject *__pyx_kp_checkError;
static char __pyx_k_snmf[] = "snmf";
static PyObject *__pyx_kp_snmf;
static char __pyx_k_nsvd0[] = "nsvd0";
static PyObject *__pyx_kp_nsvd0;
static char __pyx_k_29[] = "nsvd1";
static PyObject *__pyx_kp_29;
static char __pyx_k_30[] = "nsvd2";
static PyObject *__pyx_kp_30;
static char __pyx_k_31[] = "nsvd3";
static PyObject *__pyx_kp_31;
static char __pyx_k_hybrid[] = "hybrid";
static PyObject *__pyx_kp_hybrid;
static char __pyx_k_32[] = "hybrid2";
static PyObject *__pyx_kp_32;
static char __pyx_k_rmf[] = "rmf";
static PyObject *__pyx_kp_rmf;
static char __pyx_k_brismf[] = "brismf";
static PyObject *__pyx_kp_brismf;
static char __pyx_k_bpmf[] = "bpmf";
static PyObject *__pyx_kp_bpmf;
static char __pyx_k_pmf[] = "pmf";
static PyObject *__pyx_kp_pmf;
static char __pyx_k_subsampleUsers[] = "subsampleUsers";
static PyObject *__pyx_kp_subsampleUsers;
static char __pyx_k_34[] = "restoreFromSubsample";
static PyObject *__pyx_kp_34;
static char __pyx_k_numratings[] = "numratings";
static PyObject *__pyx_kp_numratings;
static char __pyx_k_nummovies[] = "nummovies";
static PyObject *__pyx_kp_nummovies;
static char __pyx_k_numusers[] = "numusers";
static PyObject *__pyx_kp_numusers;
static char __pyx_k_37[] = "lrateU";
static PyObject *__pyx_kp_37;
static char __pyx_k_38[] = "lrateM";
static PyObject *__pyx_kp_38;
static char __pyx_k_39[] = "lrateUb";
static PyObject *__pyx_kp_39;
static char __pyx_k_40[] = "lrateMb";
static PyObject *__pyx_kp_40;
static char __pyx_k_41[] = "dampfactU";
static PyObject *__pyx_kp_41;
static char __pyx_k_42[] = "dampfactM";
static PyObject *__pyx_kp_42;
static char __pyx_k_43[] = "dampfactUb";
static PyObject *__pyx_kp_43;
static char __pyx_k_44[] = "dampfactMb";
static PyObject *__pyx_kp_44;
static char __pyx_k_45[] = "umin";
static PyObject *__pyx_kp_45;
static char __pyx_k_46[] = "umax";
static PyObject *__pyx_kp_46;
static char __pyx_k_47[] = "mmin";
static PyObject *__pyx_kp_47;
static char __pyx_k_48[] = "mmax";
static PyObject *__pyx_kp_48;
static char __pyx_k_parameters[] = "parameters";
static PyObject *__pyx_kp_parameters;
static char __pyx_k_lrateU[] = "lrateU";
static PyObject *__pyx_kp_lrateU;
static char __pyx_k_lrateM[] = "lrateM";
static PyObject *__pyx_kp_lrateM;
static char __pyx_k_dampfactU[] = "dampfactU";
static PyObject *__pyx_kp_dampfactU;
static char __pyx_k_dampfactM[] = "dampfactM";
static PyObject *__pyx_kp_dampfactM;
static char __pyx_k_lrateUb[] = "lrateUb";
static PyObject *__pyx_kp_lrateUb;
static char __pyx_k_lrateMb[] = "lrateMb";
static PyObject *__pyx_kp_lrateMb;
static char __pyx_k_dampfactUb[] = "dampfactUb";
static PyObject *__pyx_kp_dampfactUb;
static char __pyx_k_dampfactMb[] = "dampfactMb";
static PyObject *__pyx_kp_dampfactMb;
static char __pyx_k_umin[] = "umin";
static PyObject *__pyx_kp_umin;
static char __pyx_k_umax[] = "umax";
static PyObject *__pyx_kp_umax;
static char __pyx_k_mmin[] = "mmin";
static PyObject *__pyx_kp_mmin;
static char __pyx_k_mmax[] = "mmax";
static PyObject *__pyx_kp_mmax;
static char __pyx_k_49[] = "numfeatures";
static PyObject *__pyx_kp_49;
static char __pyx_k_50[] = "miniters";
static PyObject *__pyx_kp_50;
static char __pyx_k_51[] = "maxepochs";
static PyObject *__pyx_kp_51;
static char __pyx_k_52[] = "seed";
static PyObject *__pyx_kp_52;
static char __pyx_k_53[] = "algorithm";
static PyObject *__pyx_kp_53;
static char __pyx_k_54[] = "keepUpositive";
static PyObject *__pyx_kp_54;
static char __pyx_k_55[] = "keepMpositive";
static PyObject *__pyx_kp_55;
static char __pyx_k_56[] = "minimprovement";
static PyObject *__pyx_kp_56;
static char __pyx_k_properties[] = "properties";
static PyObject *__pyx_kp_properties;
static char __pyx_k_numfeatures[] = "numfeatures";
static PyObject *__pyx_kp_numfeatures;
static char __pyx_k_miniters[] = "miniters";
static PyObject *__pyx_kp_miniters;
static char __pyx_k_maxepochs[] = "maxepochs";
static PyObject *__pyx_kp_maxepochs;
static char __pyx_k_seed[] = "seed";
static PyObject *__pyx_kp_seed;
static char __pyx_k_algorithm[] = "algorithm";
static PyObject *__pyx_kp_algorithm;
static char __pyx_k_57[] = "brismf";
static PyObject *__pyx_kp_57;
static char __pyx_k_keepUpositive[] = "keepUpositive";
static PyObject *__pyx_kp_keepUpositive;
static char __pyx_k_keepMpositive[] = "keepMpositive";
static PyObject *__pyx_kp_keepMpositive;
static char __pyx_k_itersForConvergence[] = "itersForConvergence";
static PyObject *__pyx_kp_itersForConvergence;
static char __pyx_k_minimprovement[] = "minimprovement";
static PyObject *__pyx_kp_minimprovement;
static char __pyx_k_os[] = "os";
static PyObject *__pyx_kp_os;
static char __pyx_k_time[] = "time";
static PyObject *__pyx_kp_time;
static char __pyx_k_ctime[] = "ctime";
static PyObject *__pyx_kp_ctime;
static char __pyx_k_curdir[] = "curdir";
static PyObject *__pyx_kp_curdir;
static char __pyx_k_listdir[] = "listdir";
static PyObject *__pyx_kp_listdir;
static char __pyx_k_path[] = "path";
static PyObject *__pyx_kp_path;
static char __pyx_k_exists[] = "exists";
static PyObject *__pyx_kp_exists;
static char __pyx_k_IOError[] = "IOError";
static PyObject *__pyx_kp_IOError;
static char __pyx_k_makedirs[] = "makedirs";
static PyObject *__pyx_kp_makedirs;
static char __pyx_k_chdir[] = "chdir";
static PyObject *__pyx_kp_chdir;
static char __pyx_k_open[] = "open";
static PyObject *__pyx_kp_open;
static char __pyx_k_60[] = "wt";
static PyObject *__pyx_kp_60;
static char __pyx_k_logfile[] = "logfile";
static PyObject *__pyx_kp_logfile;
static char __pyx_k_write[] = "write";
static PyObject *__pyx_kp_write;
static char __pyx_k_67[] = "uf";
static PyObject *__pyx_kp_67;
static char __pyx_k_outnameU[] = "outnameU";
static PyObject *__pyx_kp_outnameU;
static char __pyx_k_68[] = "mf";
static PyObject *__pyx_kp_68;
static char __pyx_k_outnameM[] = "outnameM";
static PyObject *__pyx_kp_outnameM;
static char __pyx_k_arrayfolder[] = "arrayfolder";
static PyObject *__pyx_kp_arrayfolder;
static char __pyx_k_split[] = "split";
static PyObject *__pyx_kp_split;
static char __pyx_k_append[] = "append";
static PyObject *__pyx_kp_append;
static char __pyx_k_70[] = "results";
static PyObject *__pyx_kp_70;
static char __pyx_k_string[] = "string";
static PyObject *__pyx_kp_string;
static char __pyx_k_join[] = "join";
static PyObject *__pyx_kp_join;
static char __pyx_k_zeros[] = "zeros";
static PyObject *__pyx_kp_zeros;
static char __pyx_k_dtype[] = "dtype";
static PyObject *__pyx_kp_dtype;
static char __pyx_k_72[] = "float32";
static PyObject *__pyx_kp_72;
static char __pyx_k_73[] = "float32";
static PyObject *__pyx_kp_73;
static char __pyx_k_random[] = "random";
static PyObject *__pyx_kp_random;
static char __pyx_k_RandomState[] = "RandomState";
static PyObject *__pyx_kp_RandomState;
static char __pyx_k_range[] = "range";
static PyObject *__pyx_kp_range;
static char __pyx_k_uniform[] = "uniform";
static PyObject *__pyx_kp_uniform;
static char __pyx_k_low[] = "low";
static PyObject *__pyx_kp_low;
static char __pyx_k_high[] = "high";
static PyObject *__pyx_kp_high;
static char __pyx_k_size[] = "size";
static PyObject *__pyx_kp_size;
static char __pyx_k_astype[] = "astype";
static PyObject *__pyx_kp_astype;
static char __pyx_k_75[] = "float32";
static PyObject *__pyx_kp_75;
static char __pyx_k_76[] = "float32";
static PyObject *__pyx_kp_76;
static char __pyx_k_77[] = "float32";
static PyObject *__pyx_kp_77;
static char __pyx_k_W[] = "W";
static PyObject *__pyx_kp_W;
static char __pyx_k_78[] = "float32";
static PyObject *__pyx_kp_78;
static char __pyx_k_79[] = "float32";
static PyObject *__pyx_kp_79;
static char __pyx_k_80[] = "float32";
static PyObject *__pyx_kp_80;
static char __pyx_k_numnodes[] = "numnodes";
static PyObject *__pyx_kp_numnodes;
static char __pyx_k_81[] = "float32";
static PyObject *__pyx_kp_81;
static char __pyx_k_82[] = "float32";
static PyObject *__pyx_kp_82;
static char __pyx_k_84[] = "U";
static PyObject *__pyx_kp_84;
static char __pyx_k_85[] = "M";
static PyObject *__pyx_kp_85;
static char __pyx_k_ValueError[] = "ValueError";
static PyObject *__pyx_kp_ValueError;
static char __pyx_k_numfeaturesmf[] = "numfeaturesmf";
static PyObject *__pyx_kp_numfeaturesmf;
static char __pyx_k_87[] = "beta";
static PyObject *__pyx_kp_87;
static char __pyx_k_89[] = "numfeaturesmf";
static PyObject *__pyx_kp_89;
static char __pyx_k_91[] = "lrateUn";
static PyObject *__pyx_kp_91;
static char __pyx_k_93[] = "lrateMn";
static PyObject *__pyx_kp_93;
static char __pyx_k_95[] = "dampfactUn";
static PyObject *__pyx_kp_95;
static char __pyx_k_97[] = "dampfactMn";
static PyObject *__pyx_kp_97;
static char __pyx_k_99[] = "beta";
static PyObject *__pyx_kp_99;
static char __pyx_k_100[] = "beta";
static PyObject *__pyx_kp_100;
static char __pyx_k_101[] = "lrateUn";
static PyObject *__pyx_kp_101;
static char __pyx_k_102[] = "lrateUn";
static PyObject *__pyx_kp_102;
static char __pyx_k_103[] = "lrateMn";
static PyObject *__pyx_kp_103;
static char __pyx_k_104[] = "lrateMn";
static PyObject *__pyx_kp_104;
static char __pyx_k_105[] = "dampfactUn";
static PyObject *__pyx_kp_105;
static char __pyx_k_106[] = "dampfactUn";
static PyObject *__pyx_kp_106;
static char __pyx_k_107[] = "dampfactMn";
static PyObject *__pyx_kp_107;
static char __pyx_k_108[] = "dampfactMn";
static PyObject *__pyx_kp_108;
static char __pyx_k_109[] = "numfeaturesmf";
static PyObject *__pyx_kp_109;
static char __pyx_k_110[] = "numfeaturesmf";
static PyObject *__pyx_kp_110;
static char __pyx_k_beta[] = "beta";
static PyObject *__pyx_kp_beta;
static char __pyx_k_111[] = "numnodes";
static PyObject *__pyx_kp_111;
static char __pyx_k_113[] = "numconnectednodes";
static PyObject *__pyx_kp_113;
static char __pyx_k_115[] = "numnodes";
static PyObject *__pyx_kp_115;
static char __pyx_k_116[] = "numnodes";
static PyObject *__pyx_kp_116;
static char __pyx_k_117[] = "numconnectednodes";
static PyObject *__pyx_kp_117;
static char __pyx_k_118[] = "numconnectednoes";
static PyObject *__pyx_kp_118;
static char __pyx_k_RMSEhistory[] = "RMSEhistory";
static PyObject *__pyx_kp_RMSEhistory;
static char __pyx_k_save[] = "save";
static PyObject *__pyx_kp_save;
static char __pyx_k_124[] = "W";
static PyObject *__pyx_kp_124;
static char __pyx_k_125[] = "w";
static PyObject *__pyx_kp_125;
static char __pyx_k_load[] = "load";
static PyObject *__pyx_kp_load;
static char __pyx_k_128[] = "W";
static PyObject *__pyx_kp_128;
static char __pyx_k_129[] = "w";
static PyObject *__pyx_kp_129;
static char __pyx_k_close[] = "close";
static PyObject *__pyx_kp_close;
static char __pyx_k_131[] = "probe";
static PyObject *__pyx_kp_131;
static char __pyx_k_dump[] = "dump";
static PyObject *__pyx_kp_dump;
static char __pyx_k_132[] = "probe10ratings";
static PyObject *__pyx_kp_132;
static char __pyx_k_133[] = "qd";
static PyObject *__pyx_kp_133;
static char __pyx_k_135[] = "quiz";
static PyObject *__pyx_kp_135;
static char __pyx_k_136[] = "quizratings";
static PyObject *__pyx_kp_136;
static char __pyx_k_137[] = "probe";
static PyObject *__pyx_kp_137;
static char __pyx_k_138[] = "quiz";
static PyObject *__pyx_kp_138;
static char __pyx_k_140[] = "float32";
static PyObject *__pyx_kp_140;
static char __pyx_k_sqrt[] = "sqrt";
static PyObject *__pyx_kp_sqrt;
static char __pyx_k_float[] = "float";
static PyObject *__pyx_kp_float;
static char __pyx_k_numconnectednodes[] = "numconnectednodes";
static PyObject *__pyx_kp_numconnectednodes;
static char __pyx_k_userIndex[] = "userIndex";
static PyObject *__pyx_kp_userIndex;
static char __pyx_k_141[] = "float32";
static PyObject *__pyx_kp_141;
static char __pyx_k_arange[] = "arange";
static PyObject *__pyx_kp_arange;
static char __pyx_k_int[] = "int";
static PyObject *__pyx_kp_int;
static char __pyx_k_shuffle[] = "shuffle";
static PyObject *__pyx_kp_shuffle;
static char __pyx_k_143[] = "float32";
static PyObject *__pyx_kp_143;
static char __pyx_k_145[] = "float32";
static PyObject *__pyx_kp_145;
static char __pyx_k_movieIndex[] = "movieIndex";
static PyObject *__pyx_kp_movieIndex;
static char __pyx_k_147[] = "float32";
static PyObject *__pyx_kp_147;
static char __pyx_k_149[] = "float32";
static PyObject *__pyx_kp_149;
static char __pyx_k_151[] = "float32";
static PyObject *__pyx_kp_151;
static char __pyx_k_lrateUn[] = "lrateUn";
static PyObject *__pyx_kp_lrateUn;
static char __pyx_k_lrateMn[] = "lrateMn";
static PyObject *__pyx_kp_lrateMn;
static char __pyx_k_dampfactUn[] = "dampfactUn";
static PyObject *__pyx_kp_dampfactUn;
static char __pyx_k_dampfactMn[] = "dampfactMn";
static PyObject *__pyx_kp_dampfactMn;
static char __pyx_k_153[] = "float32";
static PyObject *__pyx_kp_153;
static char __pyx_k_argwhere[] = "argwhere";
static PyObject *__pyx_kp_argwhere;
static PyObject *__pyx_kp_23;
static PyObject *__pyx_kp_36;
static PyObject *__pyx_builtin_object;
static PyObject *__pyx_builtin_IOError;
static PyObject *__pyx_builtin_open;
static PyObject *__pyx_builtin_range;
static PyObject *__pyx_builtin_ValueError;
static PyObject *__pyx_kp_58;
static PyObject *__pyx_kp_59;
static PyObject *__pyx_kp_61;
static PyObject *__pyx_kp_62;
static PyObject *__pyx_kp_63;
static PyObject *__pyx_kp_64;
static PyObject *__pyx_kp_65;
static char __pyx_k_58[] = "Directory %s already exists. Either delete it or rename the model.";
static char __pyx_k_59[] = "log.txt";
static char __pyx_k_61[] = "Modelname: %s\n";
static char __pyx_k_62[] = "%s\n\n";
static char __pyx_k_63[] = "Parameters:\n";
static char __pyx_k_64[] = "%s:\t\t%s\n";
static char __pyx_k_65[] = "\nLog:\n";
static PyObject *__pyx_kp_66;
static char __pyx_k_66[] = "\n";
static PyObject *__pyx_kp_69;
static PyObject *__pyx_kp_71;
static PyObject *__pyx_kp_74;
static PyObject *__pyx_kp_83;
static PyObject *__pyx_kp_86;
static PyObject *__pyx_kp_88;
static PyObject *__pyx_kp_90;
static PyObject *__pyx_kp_92;
static PyObject *__pyx_kp_94;
static PyObject *__pyx_kp_96;
static PyObject *__pyx_kp_98;
static PyObject *__pyx_kp_112;
static PyObject *__pyx_kp_114;
static PyObject *__pyx_kp_119;
static PyObject *__pyx_kp_120;
static PyObject *__pyx_kp_121;
static PyObject *__pyx_kp_122;
static PyObject *__pyx_kp_123;
static PyObject *__pyx_kp_126;
static PyObject *__pyx_kp_127;
static PyObject *__pyx_kp_130;
static PyObject *__pyx_kp_134;
static char __pyx_k_69[] = "/";
static char __pyx_k_71[] = "/";
static char __pyx_k_74[] = "Initializing user and movie feature arrays...";
static char __pyx_k_83[] = "Using pre-defined matrices";
static char __pyx_k_86[] = "Must have U and M matrices declared to use the havemats=True option";
static char __pyx_k_88[] = "Need parameter beta";
static char __pyx_k_90[] = "Need parameter numfeaturesmf";
static char __pyx_k_92[] = "Need parameter lrateUn";
static char __pyx_k_94[] = "Need parameter lrateMn";
static char __pyx_k_96[] = "Need parameter dampfactUn";
static char __pyx_k_98[] = "Need parameter dampfactMn";
static char __pyx_k_112[] = "Need parameter numnodes";
static char __pyx_k_114[] = "Need paramter numconnectednodes";
static char __pyx_k_119[] = "\nRMSE Error of random initialized data: %f";
static char __pyx_k_120[] = "\nTraining epoch: %d";
static char __pyx_k_121[] = "\n\nWARNING: NaN values present!";
static char __pyx_k_122[] = "\tRMSE: %f";
static char __pyx_k_123[] = "\tTime: %f";
static char __pyx_k_126[] = ".npy";
static char __pyx_k_127[] = ".npy";
static char __pyx_k_130[] = ".npy";
static char __pyx_k_134[] = "Making quiz ratings";
static PyObject *__pyx_kp_139;
static char __pyx_k_139[] = "predicctype argument must be either \"probe\" or \"quiz\"";
static PyObject *__pyx_kp_142;
static char __pyx_k_142[] = "\tUpdating user %d";
static PyObject *__pyx_kp_144;
static char __pyx_k_144[] = "\tUpdating user %d";
static PyObject *__pyx_kp_146;
static char __pyx_k_146[] = "\tUpdating user %d";
static PyObject *__pyx_kp_148;
static char __pyx_k_148[] = "\tUpdating movie %d";
static PyObject *__pyx_kp_150;
static char __pyx_k_150[] = "\tUpdating movie %d";
static PyObject *__pyx_kp_152;
static char __pyx_k_152[] = "\tUpdating user %d";
static PyObject *__pyx_kp_154;
static char __pyx_k_154[] = "\tUpdating movie %d";
static PyObject *__pyx_kp_155;
static char __pyx_k_155[] = "\tTraining rating %d";
static PyObject *__pyx_kp_156;
static char __pyx_k_156[] = "\tTraining rating %d";
static PyObject *__pyx_kp_157;
static char __pyx_k_157[] = "\tTraining rating %d";
static PyObject *__pyx_kp_158;
static char __pyx_k_158[] = "\tTraining rating %d";
static char __pyx_k___getbuffer__[] = "__getbuffer__";
static PyObject *__pyx_kp___getbuffer__;
static char __pyx_k___releasebuffer__[] = "__releasebuffer__";
static PyObject *__pyx_kp___releasebuffer__;
static char __pyx_k_info[] = "info";
static PyObject *__pyx_kp_info;
static char __pyx_k_flags[] = "flags";
static PyObject *__pyx_kp_flags;
static char __pyx_k_iteritems[] = "iteritems";
static PyObject *__pyx_kp_iteritems;
static char __pyx_k_next[] = "next";
static PyObject *__pyx_kp_next;
static char __pyx_k_StopIteration[] = "StopIteration";
static PyObject *__pyx_kp_StopIteration;
static char __pyx_k_pop[] = "pop";
static PyObject *__pyx_kp_pop;
static char __pyx_k_RuntimeError[] = "RuntimeError";
static PyObject *__pyx_kp_RuntimeError;
static PyObject *__pyx_kp_1;
static PyObject *__pyx_kp_2;
static PyObject *__pyx_kp_20;
static PyObject *__pyx_kp_21;
static PyObject *__pyx_kp_22;
static PyObject *__pyx_builtin_StopIteration;
static PyObject *__pyx_builtin_RuntimeError;
static char __pyx_k_1[] = "ndarray is not C contiguous";
static char __pyx_k_2[] = "ndarray is not Fortran contiguous";
static char __pyx_k_3[] = "b";
static char __pyx_k_4[] = "B";
static char __pyx_k_5[] = "h";
static char __pyx_k_6[] = "H";
static char __pyx_k_7[] = "i";
static char __pyx_k_8[] = "I";
static char __pyx_k_9[] = "l";
static char __pyx_k_10[] = "L";
static char __pyx_k_11[] = "q";
static char __pyx_k_12[] = "Q";
static char __pyx_k_13[] = "f";
static char __pyx_k_14[] = "d";
static char __pyx_k_15[] = "g";
static char __pyx_k_16[] = "Zf";
static char __pyx_k_17[] = "Zd";
static char __pyx_k_18[] = "Zg";
static char __pyx_k_19[] = "O";
static char __pyx_k_20[] = "unknown dtype code in numpy.pxd (%d)";
static char __pyx_k_21[] = "Format string allocated too short.";
static char __pyx_k_22[] = "unknown dtype code in numpy.pxd (%d)";

/* "/home/alex/workspace/flix/src/svd.pyx":39
 * 	"""
 * 
 * 	def __init__(self, fd, td, qd=None, modelname='untitled_model'):             # <<<<<<<<<<<<<<
 * 		self.fd = fd # Full data FlixData class
 * 		self.td = td # Test data FlixData class (Gravity's probe10)
 */

static PyObject *__pyx_pf_3svd_3SVD___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_3svd_3SVD___init__ = {"__init__", (PyCFunction)__pyx_pf_3svd_3SVD___init__, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pf_3svd_3SVD___init__(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_fd = 0;
  PyObject *__pyx_v_td = 0;
  PyObject *__pyx_v_qd = 0;
  PyObject *__pyx_v_modelname = 0;
  PyObject *__pyx_r;
  int __pyx_1;
  PyObject *__pyx_2 = 0;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_fd,&__pyx_kp_td,&__pyx_kp_qd,&__pyx_kp_modelname,0};
  __pyx_self = __pyx_self;
  __pyx_v_qd = Py_None;
  __pyx_v_modelname = __pyx_kp_24;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_fd);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_td);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "__init__") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_fd = values[1];
    __pyx_v_td = values[2];
    if (values[3]) {
      __pyx_v_qd = values[3];
    }
    if (values[4]) {
      __pyx_v_modelname = values[4];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5:
      __pyx_v_modelname = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4:
      __pyx_v_qd = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3:
      __pyx_v_td = PyTuple_GET_ITEM(__pyx_args, 2);
      __pyx_v_fd = PyTuple_GET_ITEM(__pyx_args, 1);
      __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__init__", 0, 3, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.__init__");
  return NULL;
  __pyx_L4_argument_unpacking_done:;

  /* "/home/alex/workspace/flix/src/svd.pyx":40
 * 
 * 	def __init__(self, fd, td, qd=None, modelname='untitled_model'):
 * 		self.fd = fd # Full data FlixData class             # <<<<<<<<<<<<<<
 * 		self.td = td # Test data FlixData class (Gravity's probe10)
 * 		if qd is not None:
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_fd, __pyx_v_fd) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 40; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":41
 * 	def __init__(self, fd, td, qd=None, modelname='untitled_model'):
 * 		self.fd = fd # Full data FlixData class
 * 		self.td = td # Test data FlixData class (Gravity's probe10)             # <<<<<<<<<<<<<<
 * 		if qd is not None:
 * 			self.qd = qd # Quiz data FlixData class
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_td, __pyx_v_td) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 41; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":42
 * 		self.fd = fd # Full data FlixData class
 * 		self.td = td # Test data FlixData class (Gravity's probe10)
 * 		if qd is not None:             # <<<<<<<<<<<<<<
 * 			self.qd = qd # Quiz data FlixData class
 * 
 */
  __pyx_1 = (__pyx_v_qd != Py_None);
  if (__pyx_1) {

    /* "/home/alex/workspace/flix/src/svd.pyx":43
 * 		self.td = td # Test data FlixData class (Gravity's probe10)
 * 		if qd is not None:
 * 			self.qd = qd # Quiz data FlixData class             # <<<<<<<<<<<<<<
 * 
 * 		self.numratings = fd.numratings
 */
    if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_qd, __pyx_v_qd) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 43; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    goto __pyx_L6;
  }
  __pyx_L6:;

  /* "/home/alex/workspace/flix/src/svd.pyx":45
 * 			self.qd = qd # Quiz data FlixData class
 * 
 * 		self.numratings = fd.numratings             # <<<<<<<<<<<<<<
 * 		self.nummovies = 17770 # hard-coded for now...
 * 		self.numusers = fd.numusers
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_fd, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numratings, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 45; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":46
 * 
 * 		self.numratings = fd.numratings
 * 		self.nummovies = 17770 # hard-coded for now...             # <<<<<<<<<<<<<<
 * 		self.numusers = fd.numusers
 * 		self.modelname = modelname
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_nummovies, __pyx_int_17770) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 46; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":47
 * 		self.numratings = fd.numratings
 * 		self.nummovies = 17770 # hard-coded for now...
 * 		self.numusers = fd.numusers             # <<<<<<<<<<<<<<
 * 		self.modelname = modelname
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_fd, __pyx_kp_numusers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numusers, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 47; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":48
 * 		self.nummovies = 17770 # hard-coded for now...
 * 		self.numusers = fd.numusers
 * 		self.modelname = modelname             # <<<<<<<<<<<<<<
 * 
 * 		self.parameters = ['lrateU', 'lrateM', 'lrateUb', 'lrateMb', 'dampfactU', \
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_modelname, __pyx_v_modelname) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 48; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":52
 * 		self.parameters = ['lrateU', 'lrateM', 'lrateUb', 'lrateMb', 'dampfactU', \
 * 							'dampfactM',  'dampfactUb', 'dampfactMb', 'umin', 'umax', \
 * 							'mmin', 'mmax']             # <<<<<<<<<<<<<<
 * 		self.lrateU = 0.019
 * 		self.lrateM = 0.004
 */
  __pyx_2 = PyList_New(12); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_37);
  PyList_SET_ITEM(__pyx_2, 0, __pyx_kp_37);
  Py_INCREF(__pyx_kp_38);
  PyList_SET_ITEM(__pyx_2, 1, __pyx_kp_38);
  Py_INCREF(__pyx_kp_39);
  PyList_SET_ITEM(__pyx_2, 2, __pyx_kp_39);
  Py_INCREF(__pyx_kp_40);
  PyList_SET_ITEM(__pyx_2, 3, __pyx_kp_40);
  Py_INCREF(__pyx_kp_41);
  PyList_SET_ITEM(__pyx_2, 4, __pyx_kp_41);
  Py_INCREF(__pyx_kp_42);
  PyList_SET_ITEM(__pyx_2, 5, __pyx_kp_42);
  Py_INCREF(__pyx_kp_43);
  PyList_SET_ITEM(__pyx_2, 6, __pyx_kp_43);
  Py_INCREF(__pyx_kp_44);
  PyList_SET_ITEM(__pyx_2, 7, __pyx_kp_44);
  Py_INCREF(__pyx_kp_45);
  PyList_SET_ITEM(__pyx_2, 8, __pyx_kp_45);
  Py_INCREF(__pyx_kp_46);
  PyList_SET_ITEM(__pyx_2, 9, __pyx_kp_46);
  Py_INCREF(__pyx_kp_47);
  PyList_SET_ITEM(__pyx_2, 10, __pyx_kp_47);
  Py_INCREF(__pyx_kp_48);
  PyList_SET_ITEM(__pyx_2, 11, __pyx_kp_48);

  /* "/home/alex/workspace/flix/src/svd.pyx":50
 * 		self.modelname = modelname
 * 
 * 		self.parameters = ['lrateU', 'lrateM', 'lrateUb', 'lrateMb', 'dampfactU', \             # <<<<<<<<<<<<<<
 * 							'dampfactM',  'dampfactUb', 'dampfactMb', 'umin', 'umax', \
 * 							'mmin', 'mmax']
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_parameters, ((PyObject *)__pyx_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 50; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":53
 * 							'dampfactM',  'dampfactUb', 'dampfactMb', 'umin', 'umax', \
 * 							'mmin', 'mmax']
 * 		self.lrateU = 0.019             # <<<<<<<<<<<<<<
 * 		self.lrateM = 0.004
 * 		self.dampfactU = 0.019
 */
  __pyx_2 = PyFloat_FromDouble(0.019); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_lrateU, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 53; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":54
 * 							'mmin', 'mmax']
 * 		self.lrateU = 0.019
 * 		self.lrateM = 0.004             # <<<<<<<<<<<<<<
 * 		self.dampfactU = 0.019
 * 		self.dampfactM = 0.019
 */
  __pyx_2 = PyFloat_FromDouble(0.004); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_lrateM, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 54; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":55
 * 		self.lrateU = 0.019
 * 		self.lrateM = 0.004
 * 		self.dampfactU = 0.019             # <<<<<<<<<<<<<<
 * 		self.dampfactM = 0.019
 * 		self.lrateUb = 0.004
 */
  __pyx_2 = PyFloat_FromDouble(0.019); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_dampfactU, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 55; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":56
 * 		self.lrateM = 0.004
 * 		self.dampfactU = 0.019
 * 		self.dampfactM = 0.019             # <<<<<<<<<<<<<<
 * 		self.lrateUb = 0.004
 * 		self.lrateMb = 0.013
 */
  __pyx_2 = PyFloat_FromDouble(0.019); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_dampfactM, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 56; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":57
 * 		self.dampfactU = 0.019
 * 		self.dampfactM = 0.019
 * 		self.lrateUb = 0.004             # <<<<<<<<<<<<<<
 * 		self.lrateMb = 0.013
 * 		self.dampfactUb = 0.019
 */
  __pyx_2 = PyFloat_FromDouble(0.004); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_lrateUb, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 57; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":58
 * 		self.dampfactM = 0.019
 * 		self.lrateUb = 0.004
 * 		self.lrateMb = 0.013             # <<<<<<<<<<<<<<
 * 		self.dampfactUb = 0.019
 * 		self.dampfactMb = 0.007
 */
  __pyx_2 = PyFloat_FromDouble(0.013); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_lrateMb, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 58; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":59
 * 		self.lrateUb = 0.004
 * 		self.lrateMb = 0.013
 * 		self.dampfactUb = 0.019             # <<<<<<<<<<<<<<
 * 		self.dampfactMb = 0.007
 * 		self.umin = -0.01
 */
  __pyx_2 = PyFloat_FromDouble(0.019); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_dampfactUb, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 59; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":60
 * 		self.lrateMb = 0.013
 * 		self.dampfactUb = 0.019
 * 		self.dampfactMb = 0.007             # <<<<<<<<<<<<<<
 * 		self.umin = -0.01
 * 		self.umax = 0.01
 */
  __pyx_2 = PyFloat_FromDouble(0.007); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_dampfactMb, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 60; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":61
 * 		self.dampfactUb = 0.019
 * 		self.dampfactMb = 0.007
 * 		self.umin = -0.01             # <<<<<<<<<<<<<<
 * 		self.umax = 0.01
 * 		self.mmin = -0.01
 */
  __pyx_2 = PyFloat_FromDouble((-0.01)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_umin, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 61; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":62
 * 		self.dampfactMb = 0.007
 * 		self.umin = -0.01
 * 		self.umax = 0.01             # <<<<<<<<<<<<<<
 * 		self.mmin = -0.01
 * 		self.mmax = 0.01
 */
  __pyx_2 = PyFloat_FromDouble(0.01); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_umax, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 62; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":63
 * 		self.umin = -0.01
 * 		self.umax = 0.01
 * 		self.mmin = -0.01             # <<<<<<<<<<<<<<
 * 		self.mmax = 0.01
 * 
 */
  __pyx_2 = PyFloat_FromDouble((-0.01)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_mmin, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 63; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":64
 * 		self.umax = 0.01
 * 		self.mmin = -0.01
 * 		self.mmax = 0.01             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_2 = PyFloat_FromDouble(0.01); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_mmax, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 64; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":69
 * 
 * 		self.properties = ['numfeatures', 'miniters', 'maxepochs', 'seed', 'algorithm', \
 * 							'keepUpositive', 'keepMpositive', 'minimprovement']             # <<<<<<<<<<<<<<
 * 		self.numfeatures = 12
 * 		self.miniters = 2
 */
  __pyx_2 = PyList_New(8); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_49);
  PyList_SET_ITEM(__pyx_2, 0, __pyx_kp_49);
  Py_INCREF(__pyx_kp_50);
  PyList_SET_ITEM(__pyx_2, 1, __pyx_kp_50);
  Py_INCREF(__pyx_kp_51);
  PyList_SET_ITEM(__pyx_2, 2, __pyx_kp_51);
  Py_INCREF(__pyx_kp_52);
  PyList_SET_ITEM(__pyx_2, 3, __pyx_kp_52);
  Py_INCREF(__pyx_kp_53);
  PyList_SET_ITEM(__pyx_2, 4, __pyx_kp_53);
  Py_INCREF(__pyx_kp_54);
  PyList_SET_ITEM(__pyx_2, 5, __pyx_kp_54);
  Py_INCREF(__pyx_kp_55);
  PyList_SET_ITEM(__pyx_2, 6, __pyx_kp_55);
  Py_INCREF(__pyx_kp_56);
  PyList_SET_ITEM(__pyx_2, 7, __pyx_kp_56);

  /* "/home/alex/workspace/flix/src/svd.pyx":68
 * 
 * 
 * 		self.properties = ['numfeatures', 'miniters', 'maxepochs', 'seed', 'algorithm', \             # <<<<<<<<<<<<<<
 * 							'keepUpositive', 'keepMpositive', 'minimprovement']
 * 		self.numfeatures = 12
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_properties, ((PyObject *)__pyx_2)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 68; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":70
 * 		self.properties = ['numfeatures', 'miniters', 'maxepochs', 'seed', 'algorithm', \
 * 							'keepUpositive', 'keepMpositive', 'minimprovement']
 * 		self.numfeatures = 12             # <<<<<<<<<<<<<<
 * 		self.miniters = 2
 * 		self.maxepochs = 100
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numfeatures, __pyx_int_12) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 70; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":71
 * 							'keepUpositive', 'keepMpositive', 'minimprovement']
 * 		self.numfeatures = 12
 * 		self.miniters = 2             # <<<<<<<<<<<<<<
 * 		self.maxepochs = 100
 * 		self.seed = 123456789 # seed for the random number generator.
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_miniters, __pyx_int_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 71; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":72
 * 		self.numfeatures = 12
 * 		self.miniters = 2
 * 		self.maxepochs = 100             # <<<<<<<<<<<<<<
 * 		self.seed = 123456789 # seed for the random number generator.
 * 		self.algorithm = 'brismf'
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_maxepochs, __pyx_int_100) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 72; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":73
 * 		self.miniters = 2
 * 		self.maxepochs = 100
 * 		self.seed = 123456789 # seed for the random number generator.             # <<<<<<<<<<<<<<
 * 		self.algorithm = 'brismf'
 * 		self.keepUpositive = 0
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_seed, __pyx_int_123456789) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 73; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":74
 * 		self.maxepochs = 100
 * 		self.seed = 123456789 # seed for the random number generator.
 * 		self.algorithm = 'brismf'             # <<<<<<<<<<<<<<
 * 		self.keepUpositive = 0
 * 		self.keepMpositive = 0
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_algorithm, __pyx_kp_57) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 74; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":75
 * 		self.seed = 123456789 # seed for the random number generator.
 * 		self.algorithm = 'brismf'
 * 		self.keepUpositive = 0             # <<<<<<<<<<<<<<
 * 		self.keepMpositive = 0
 * 		self.itersForConvergence = 1 # number of iterations triggering the stopping criteria before stopping.
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_keepUpositive, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 75; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":76
 * 		self.algorithm = 'brismf'
 * 		self.keepUpositive = 0
 * 		self.keepMpositive = 0             # <<<<<<<<<<<<<<
 * 		self.itersForConvergence = 1 # number of iterations triggering the stopping criteria before stopping.
 * 		self.minimprovement = 0.00004 # pretty arbitrary, just thrown in to save time.
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_keepMpositive, __pyx_int_0) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 76; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":77
 * 		self.keepUpositive = 0
 * 		self.keepMpositive = 0
 * 		self.itersForConvergence = 1 # number of iterations triggering the stopping criteria before stopping.             # <<<<<<<<<<<<<<
 * 		self.minimprovement = 0.00004 # pretty arbitrary, just thrown in to save time.
 * 
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_itersForConvergence, __pyx_int_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 77; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":78
 * 		self.keepMpositive = 0
 * 		self.itersForConvergence = 1 # number of iterations triggering the stopping criteria before stopping.
 * 		self.minimprovement = 0.00004 # pretty arbitrary, just thrown in to save time.             # <<<<<<<<<<<<<<
 * 
 * 	def startSVDLog(self, overwrite=True):
 */
  __pyx_2 = PyFloat_FromDouble(0.00004); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_minimprovement, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 78; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_2);
  __Pyx_AddTraceback("svd.SVD.__init__");
  __pyx_r = NULL;
  __pyx_L0:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":80
 * 		self.minimprovement = 0.00004 # pretty arbitrary, just thrown in to save time.
 * 
 * 	def startSVDLog(self, overwrite=True):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Create a folder of the model, and begin a logfile in that folder.
 */

static PyObject *__pyx_pf_3svd_3SVD_startSVDLog(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_startSVDLog[] = "\n\t\tCreate a folder of the model, and begin a logfile in that folder.\n\t\tThe logfile will be consistently structures, so that later functions\n\t\tcan read lists of parameters in logfiles in order to quickly and\n\t\tconsistently rerun models. \n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_startSVDLog = {"startSVDLog", (PyCFunction)__pyx_pf_3svd_3SVD_startSVDLog, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_startSVDLog};
static PyObject *__pyx_pf_3svd_3SVD_startSVDLog(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_overwrite = 0;
  PyObject *__pyx_v_os;
  PyObject *__pyx_v_ctime;
  PyObject *__pyx_v_cwd;
  PyObject *__pyx_v_locfiles;
  PyObject *__pyx_v_parameter;
  PyObject *__pyx_v_paramvalue;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  PyObject *__pyx_3 = 0;
  int __pyx_4;
  Py_ssize_t __pyx_5 = 0;
  PyObject *__pyx_6 = 0;
  PyObject *__pyx_t_1 = NULL;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_overwrite,0};
  __pyx_self = __pyx_self;
  __pyx_v_overwrite = __pyx_k_25;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[2] = {0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "startSVDLog") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    if (values[1]) {
      __pyx_v_overwrite = values[1];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: __pyx_v_overwrite = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("startSVDLog", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.startSVDLog");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_os = Py_None; Py_INCREF(Py_None);
  __pyx_v_ctime = Py_None; Py_INCREF(Py_None);
  __pyx_v_cwd = Py_None; Py_INCREF(Py_None);
  __pyx_v_locfiles = Py_None; Py_INCREF(Py_None);
  __pyx_v_parameter = Py_None; Py_INCREF(Py_None);
  __pyx_v_paramvalue = Py_None; Py_INCREF(Py_None);

  /* "/home/alex/workspace/flix/src/svd.pyx":88
 * 		"""
 * 
 * 		import os             # <<<<<<<<<<<<<<
 * 		from time import ctime
 * 		cwd = os.curdir
 */
  __pyx_1 = __Pyx_Import(__pyx_kp_os, 0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 88; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_os);
  __pyx_v_os = __pyx_1;
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":89
 * 
 * 		import os
 * 		from time import ctime             # <<<<<<<<<<<<<<
 * 		cwd = os.curdir
 * 		locfiles = os.listdir(cwd)
 */
  __pyx_1 = PyList_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_ctime);
  PyList_SET_ITEM(__pyx_1, 0, __pyx_kp_ctime);
  __pyx_2 = __Pyx_Import(__pyx_kp_time, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_ctime); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 89; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_ctime);
  __pyx_v_ctime = __pyx_1;
  __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":90
 * 		import os
 * 		from time import ctime
 * 		cwd = os.curdir             # <<<<<<<<<<<<<<
 * 		locfiles = os.listdir(cwd)
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_os, __pyx_kp_curdir); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 90; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_cwd);
  __pyx_v_cwd = __pyx_2;
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":91
 * 		from time import ctime
 * 		cwd = os.curdir
 * 		locfiles = os.listdir(cwd)             # <<<<<<<<<<<<<<
 * 
 * 		# If the directory exists, either choke up if we want to preserve the folder's contents,
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_os, __pyx_kp_listdir); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_v_cwd);
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_cwd);
  __pyx_3 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 91; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  Py_DECREF(__pyx_v_locfiles);
  __pyx_v_locfiles = __pyx_3;
  __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":95
 * 		# If the directory exists, either choke up if we want to preserve the folder's contents,
 * 		# or allow ourselves to write over its contents if overwrite=True
 * 		if os.path.exists(self.resultdir):             # <<<<<<<<<<<<<<
 * 			if overwrite is False:
 * 				raise IOError, 'Directory %s already exists. Either delete it or rename the model.' % self.resultdir
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_os, __pyx_kp_path); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_exists); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
  __pyx_3 = 0;
  __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 95; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  if (__pyx_4) {

    /* "/home/alex/workspace/flix/src/svd.pyx":96
 * 		# or allow ourselves to write over its contents if overwrite=True
 * 		if os.path.exists(self.resultdir):
 * 			if overwrite is False:             # <<<<<<<<<<<<<<
 * 				raise IOError, 'Directory %s already exists. Either delete it or rename the model.' % self.resultdir
 * 		else:
 */
    __pyx_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 96; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = (__pyx_v_overwrite == __pyx_2);
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":97
 * 		if os.path.exists(self.resultdir):
 * 			if overwrite is False:
 * 				raise IOError, 'Directory %s already exists. Either delete it or rename the model.' % self.resultdir             # <<<<<<<<<<<<<<
 * 		else:
 * 			# makedirs doesn't choke on a path input, mkdir does.
 */
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_58, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __Pyx_Raise(__pyx_builtin_IOError, __pyx_t_1, 0);
      Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      goto __pyx_L7;
    }
    __pyx_L7:;
    goto __pyx_L6;
  }
  /*else*/ {

    /* "/home/alex/workspace/flix/src/svd.pyx":100
 * 		else:
 * 			# makedirs doesn't choke on a path input, mkdir does.
 * 			os.makedirs(self.resultdir)             # <<<<<<<<<<<<<<
 * 
 * 		os.chdir(self.resultdir)
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_os, __pyx_kp_makedirs); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
    __pyx_2 = 0;
    __pyx_2 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 100; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    Py_DECREF(__pyx_2); __pyx_2 = 0;
  }
  __pyx_L6:;

  /* "/home/alex/workspace/flix/src/svd.pyx":102
 * 			os.makedirs(self.resultdir)
 * 
 * 		os.chdir(self.resultdir)             # <<<<<<<<<<<<<<
 * 
 * 		# Open up a logfile
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_os, __pyx_kp_chdir); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 102; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":105
 * 
 * 		# Open up a logfile
 * 		self.logfile = open('log.txt', 'wt')             # <<<<<<<<<<<<<<
 * 
 * 		# Write the name and date
 */
  __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_59);
  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_kp_59);
  Py_INCREF(__pyx_kp_60);
  PyTuple_SET_ITEM(__pyx_3, 1, __pyx_kp_60);
  __pyx_2 = PyObject_Call(__pyx_builtin_open, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_logfile, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":108
 * 
 * 		# Write the name and date
 * 		self.logfile.write('Modelname: %s\n' % self.modelname)             # <<<<<<<<<<<<<<
 * 		self.logfile.write('%s\n\n' % ctime())
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_write); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_modelname); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Remainder(__pyx_kp_61, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_2 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":109
 * 		# Write the name and date
 * 		self.logfile.write('Modelname: %s\n' % self.modelname)
 * 		self.logfile.write('%s\n\n' % ctime())             # <<<<<<<<<<<<<<
 * 
 * 		# Dump each item listed in self.parameters.
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_3, __pyx_kp_write); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_2 = PyObject_Call(__pyx_v_ctime, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Remainder(__pyx_kp_62, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":114
 * 		# If a model contains a special parameter value,
 * 		# all that has to be done is to do a couple self.parameters.append()
 * 		self.logfile.write('Parameters:\n')             # <<<<<<<<<<<<<<
 * 		for parameter in self.parameters:
 * 			paramvalue = getattr(self, parameter)
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_write); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_63);
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_63);
  __pyx_1 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":115
 * 		# all that has to be done is to do a couple self.parameters.append()
 * 		self.logfile.write('Parameters:\n')
 * 		for parameter in self.parameters:             # <<<<<<<<<<<<<<
 * 			paramvalue = getattr(self, parameter)
 * 			self.logfile.write('%s:\t\t%s\n' % (parameter, str(paramvalue)))
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyList_CheckExact(__pyx_3) || PyTuple_CheckExact(__pyx_3)) {
    __pyx_5 = 0; __pyx_2 = __pyx_3; Py_INCREF(__pyx_2);
  } else {
    __pyx_5 = -1; __pyx_2 = PyObject_GetIter(__pyx_3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  }
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  for (;;) {
    if (likely(PyList_CheckExact(__pyx_2))) {
      if (__pyx_5 >= PyList_GET_SIZE(__pyx_2)) break;
      __pyx_1 = PyList_GET_ITEM(__pyx_2, __pyx_5); Py_INCREF(__pyx_1); __pyx_5++;
    } else if (likely(PyTuple_CheckExact(__pyx_2))) {
      if (__pyx_5 >= PyTuple_GET_SIZE(__pyx_2)) break;
      __pyx_1 = PyTuple_GET_ITEM(__pyx_2, __pyx_5); Py_INCREF(__pyx_1); __pyx_5++;
    } else {
      __pyx_1 = PyIter_Next(__pyx_2);
      if (!__pyx_1) {
        if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 115; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        break;
      }
    }
    Py_DECREF(__pyx_v_parameter);
    __pyx_v_parameter = __pyx_1;
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":116
 * 		self.logfile.write('Parameters:\n')
 * 		for parameter in self.parameters:
 * 			paramvalue = getattr(self, parameter)             # <<<<<<<<<<<<<<
 * 			self.logfile.write('%s:\t\t%s\n' % (parameter, str(paramvalue)))
 * 
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_v_parameter); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 116; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_paramvalue);
    __pyx_v_paramvalue = __pyx_3;
    __pyx_3 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":117
 * 		for parameter in self.parameters:
 * 			paramvalue = getattr(self, parameter)
 * 			self.logfile.write('%s:\t\t%s\n' % (parameter, str(paramvalue)))             # <<<<<<<<<<<<<<
 * 
 * 		self.logfile.write('\nLog:\n')
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_write); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_v_paramvalue);
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_paramvalue);
    __pyx_6 = PyObject_Call(((PyObject *)((PyObject*)&PyString_Type)), ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_v_parameter);
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_parameter);
    PyTuple_SET_ITEM(__pyx_1, 1, __pyx_6);
    __pyx_6 = 0;
    __pyx_t_1 = PyNumber_Remainder(__pyx_kp_64, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_1 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 117; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    Py_DECREF(__pyx_1); __pyx_1 = 0;
  }
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":119
 * 			self.logfile.write('%s:\t\t%s\n' % (parameter, str(paramvalue)))
 * 
 * 		self.logfile.write('\nLog:\n')             # <<<<<<<<<<<<<<
 * 
 * 	def updateLog(self, message, displaytext=True):
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = PyObject_GetAttr(__pyx_3, __pyx_kp_write); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_65);
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_65);
  __pyx_2 = PyObject_Call(__pyx_6, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 119; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_3);
  Py_XDECREF(__pyx_6);
  __Pyx_AddTraceback("svd.SVD.startSVDLog");
  __pyx_r = NULL;
  __pyx_L0:;
  Py_DECREF(__pyx_v_os);
  Py_DECREF(__pyx_v_ctime);
  Py_DECREF(__pyx_v_cwd);
  Py_DECREF(__pyx_v_locfiles);
  Py_DECREF(__pyx_v_parameter);
  Py_DECREF(__pyx_v_paramvalue);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":121
 * 		self.logfile.write('\nLog:\n')
 * 
 * 	def updateLog(self, message, displaytext=True):             # <<<<<<<<<<<<<<
 * 		"""
 * 		USAGE:
 */

static PyObject *__pyx_pf_3svd_3SVD_updateLog(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_updateLog[] = "\n\t\tUSAGE:\n\t\tmessage = 'RMSE=0.9728, continuing to next training round...'\n\t\tupdateLog(message, displaytext=True)\n\t\t\n\t\tThis will print the message, and save it to the logfile.\n\t\tdisplaytext is True by default. If False, then the message\n\t\twill be written to the logfile without displaying it in the console.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_updateLog = {"updateLog", (PyCFunction)__pyx_pf_3svd_3SVD_updateLog, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_updateLog};
static PyObject *__pyx_pf_3svd_3SVD_updateLog(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_message = 0;
  PyObject *__pyx_v_displaytext = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  PyObject *__pyx_3 = 0;
  PyObject *__pyx_t_1 = NULL;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_message,&__pyx_kp_displaytext,0};
  __pyx_self = __pyx_self;
  __pyx_v_displaytext = __pyx_k_26;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[3] = {0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_message);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("updateLog", 0, 2, 3, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "updateLog") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_message = values[1];
    if (values[2]) {
      __pyx_v_displaytext = values[2];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  3:
      __pyx_v_displaytext = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2:
      __pyx_v_message = PyTuple_GET_ITEM(__pyx_args, 1);
      __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("updateLog", 0, 2, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.updateLog");
  return NULL;
  __pyx_L4_argument_unpacking_done:;

  /* "/home/alex/workspace/flix/src/svd.pyx":131
 * 		will be written to the logfile without displaying it in the console.
 * 		"""
 * 		print(message)             # <<<<<<<<<<<<<<
 * 		self.logfile.write(message+'\n')
 * 
 */
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_v_message);
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_v_message);
  if (__Pyx_Print(((PyObject *)__pyx_1), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 131; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":132
 * 		"""
 * 		print(message)
 * 		self.logfile.write(message+'\n')             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_write); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_t_1 = PyNumber_Add(__pyx_v_message, __pyx_kp_66); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 132; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_3);
  __Pyx_AddTraceback("svd.SVD.updateLog");
  __pyx_r = NULL;
  __pyx_L0:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":135
 * 
 * 
 * 	def svd(self, havemats=False):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Run an SVD algorithm.
 */

static PyObject *__pyx_pf_3svd_3SVD_svd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_svd[] = "\n\t\tRun an SVD algorithm.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_svd = {"svd", (PyCFunction)__pyx_pf_3svd_3SVD_svd, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_svd};
static PyObject *__pyx_pf_3svd_3SVD_svd(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_havemats = 0;
  PyObject *__pyx_v_time;
  PyObject *__pyx_v_join;
  PyObject *__pyx_v_updateFeatures;
  PyArrayObject *__pyx_v_U;
  PyArrayObject *__pyx_v_M;
  PyObject *__pyx_v_rs;
  PyObject *__pyx_v_i;
  int __pyx_v_counter;
  int __pyx_v_epoch;
  float __pyx_v_oldRMSE;
  float __pyx_v_RMSE;
  PyObject *__pyx_v_done;
  PyObject *__pyx_v_t1;
  PyObject *__pyx_v_t2;
  PyObject *__pyx_v_deltaRMSE;
  PyObject *__pyx_v_probeRatings;
  PyObject *__pyx_v_quizRatings;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  PyObject *__pyx_3 = 0;
  int __pyx_4;
  int __pyx_5;
  PyObject *__pyx_6 = 0;
  Py_ssize_t __pyx_7 = 0;
  PyObject *__pyx_8 = 0;
  float __pyx_9;
  PyObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  int __pyx_t_3;
  PyObject *__pyx_t_4 = NULL;
  PyObject *__pyx_t_5 = NULL;
  PyArrayObject *__pyx_t_6 = NULL;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_havemats,0};
  __pyx_self = __pyx_self;
  __pyx_v_havemats = __pyx_k_27;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[2] = {0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "svd") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    if (values[1]) {
      __pyx_v_havemats = values[1];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: __pyx_v_havemats = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("svd", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.svd");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_time = Py_None; Py_INCREF(Py_None);
  __pyx_v_join = Py_None; Py_INCREF(Py_None);
  __pyx_v_updateFeatures = Py_None; Py_INCREF(Py_None);
  __pyx_v_U = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
  __pyx_v_M = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
  __pyx_v_rs = Py_None; Py_INCREF(Py_None);
  __pyx_v_i = Py_None; Py_INCREF(Py_None);
  __pyx_v_done = Py_None; Py_INCREF(Py_None);
  __pyx_v_t1 = Py_None; Py_INCREF(Py_None);
  __pyx_v_t2 = Py_None; Py_INCREF(Py_None);
  __pyx_v_deltaRMSE = Py_None; Py_INCREF(Py_None);
  __pyx_v_probeRatings = Py_None; Py_INCREF(Py_None);
  __pyx_v_quizRatings = Py_None; Py_INCREF(Py_None);
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;

  /* "/home/alex/workspace/flix/src/svd.pyx":139
 * 		Run an SVD algorithm.
 * 		"""
 * 		from time import time             # <<<<<<<<<<<<<<
 * 
 * 		# Locate the folder where the model will be stored
 */
  __pyx_1 = PyList_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_time);
  PyList_SET_ITEM(__pyx_1, 0, __pyx_kp_time);
  __pyx_2 = __Pyx_Import(__pyx_kp_time, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_time); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_time);
  __pyx_v_time = __pyx_1;
  __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":142
 * 
 * 		# Locate the folder where the model will be stored
 * 		self.outnameU = 'uf'+self.modelname             # <<<<<<<<<<<<<<
 * 		self.outnameM = 'mf'+self.modelname
 * 		self.resultdir = self.fd.arrayfolder.split('/')[:-3]
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_modelname); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Add(__pyx_kp_67, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_outnameU, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":143
 * 		# Locate the folder where the model will be stored
 * 		self.outnameU = 'uf'+self.modelname
 * 		self.outnameM = 'mf'+self.modelname             # <<<<<<<<<<<<<<
 * 		self.resultdir = self.fd.arrayfolder.split('/')[:-3]
 * 		self.resultdir.append('results')
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_modelname); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Add(__pyx_kp_68, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_outnameM, __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":144
 * 		self.outnameU = 'uf'+self.modelname
 * 		self.outnameM = 'mf'+self.modelname
 * 		self.resultdir = self.fd.arrayfolder.split('/')[:-3]             # <<<<<<<<<<<<<<
 * 		self.resultdir.append('results')
 * 		self.resultdir.append(self.modelname)
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_arrayfolder); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_split); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_69);
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_69);
  __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_2 = PySequence_GetSlice(__pyx_3, 0, -3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_resultdir, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":145
 * 		self.outnameM = 'mf'+self.modelname
 * 		self.resultdir = self.fd.arrayfolder.split('/')[:-3]
 * 		self.resultdir.append('results')             # <<<<<<<<<<<<<<
 * 		self.resultdir.append(self.modelname)
 * 		from string import join
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = __Pyx_PyObject_Append(__pyx_1, __pyx_kp_70); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":146
 * 		self.resultdir = self.fd.arrayfolder.split('/')[:-3]
 * 		self.resultdir.append('results')
 * 		self.resultdir.append(self.modelname)             # <<<<<<<<<<<<<<
 * 		from string import join
 * 		self.resultdir = join(self.resultdir, '/')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_modelname); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = __Pyx_PyObject_Append(__pyx_2, __pyx_1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":147
 * 		self.resultdir.append('results')
 * 		self.resultdir.append(self.modelname)
 * 		from string import join             # <<<<<<<<<<<<<<
 * 		self.resultdir = join(self.resultdir, '/')
 * 
 */
  __pyx_2 = PyList_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_join);
  PyList_SET_ITEM(__pyx_2, 0, __pyx_kp_join);
  __pyx_1 = __Pyx_Import(__pyx_kp_string, ((PyObject *)__pyx_2)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_join); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_join);
  __pyx_v_join = __pyx_3;
  __pyx_3 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":148
 * 		self.resultdir.append(self.modelname)
 * 		from string import join
 * 		self.resultdir = join(self.resultdir, '/')             # <<<<<<<<<<<<<<
 * 
 * 		# Begin a log of the model training
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_resultdir); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_kp_71);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_kp_71);
  __pyx_2 = 0;
  __pyx_3 = PyObject_Call(__pyx_v_join, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_resultdir, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":151
 * 
 * 		# Begin a log of the model training
 * 		self.startSVDLog()             # <<<<<<<<<<<<<<
 * 
 * 		# Get the proper update function
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_startSVDLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":154
 * 
 * 		# Get the proper update function
 * 		updateFeatures = getattr(self, self.algorithm)             # <<<<<<<<<<<<<<
 * 
 * 		# Give names and types to the user and movie arrays
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_algorithm); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(__pyx_v_updateFeatures);
  __pyx_v_updateFeatures = __pyx_2;
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":160
 * 		cdef N.ndarray[f32_t, ndim=2] M
 * 
 * 		if not havemats:             # <<<<<<<<<<<<<<
 * 			U = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 			M = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 */
  __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_v_havemats); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 160; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = (!__pyx_4);
  if (__pyx_5) {

    /* "/home/alex/workspace/flix/src/svd.pyx":161
 * 
 * 		if not havemats:
 * 			U = N.zeros((self.numusers, self.numfeatures), dtype='float32')             # <<<<<<<<<<<<<<
 * 			M = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 			print('Initializing user and movie feature arrays...')
 */
    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_zeros); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numusers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_2);
    PyTuple_SET_ITEM(__pyx_6, 1, __pyx_1);
    __pyx_2 = 0;
    __pyx_1 = 0;
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_6));
    __pyx_6 = 0;
    __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_72) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyEval_CallObjectWithKeywords(__pyx_3, ((PyObject *)__pyx_2), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    if (!(__Pyx_TypeTest(__pyx_6, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_2 = ((PyArrayObject *)__pyx_6);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __pyx_t_3 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0);
    if (unlikely(__pyx_t_3 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_1, &__pyx_t_4, &__pyx_t_5);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
            Py_XDECREF(__pyx_t_1); Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_1, __pyx_t_4, __pyx_t_5);
        }
    }
    __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
    __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
    if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 161; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_2 = 0;
    Py_DECREF(((PyObject *)__pyx_v_U));
    __pyx_v_U = ((PyArrayObject *)__pyx_6);
    __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":162
 * 		if not havemats:
 * 			U = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 			M = N.zeros((self.nummovies, self.numfeatures), dtype='float32')             # <<<<<<<<<<<<<<
 * 			print('Initializing user and movie feature arrays...')
 * 			rs = N.random.RandomState(self.seed)
 */
    __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nummovies); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_1);
    PyTuple_SET_ITEM(__pyx_3, 1, __pyx_6);
    __pyx_1 = 0;
    __pyx_6 = 0;
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_1, 0, ((PyObject *)__pyx_3));
    __pyx_3 = 0;
    __pyx_6 = PyDict_New(); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (PyDict_SetItem(__pyx_6, __pyx_kp_dtype, __pyx_kp_73) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_1), ((PyObject *)__pyx_6)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    if (!(__Pyx_TypeTest(__pyx_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_6 = ((PyArrayObject *)__pyx_3);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __pyx_t_3 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_6, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0);
    if (unlikely(__pyx_t_3 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_5, &__pyx_t_4, &__pyx_t_1);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_1);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_4, __pyx_t_1);
        }
    }
    __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
    __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
    if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 162; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_6 = 0;
    Py_DECREF(((PyObject *)__pyx_v_M));
    __pyx_v_M = ((PyArrayObject *)__pyx_3);
    __pyx_3 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":163
 * 			U = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 			M = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 			print('Initializing user and movie feature arrays...')             # <<<<<<<<<<<<<<
 * 			rs = N.random.RandomState(self.seed)
 * 			# We fill up the arrays with with random numbers sampled from a uniform distribution described
 */
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_74);
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_74);
    if (__Pyx_Print(((PyObject *)__pyx_2), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 163; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":164
 * 			M = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 			print('Initializing user and movie feature arrays...')
 * 			rs = N.random.RandomState(self.seed)             # <<<<<<<<<<<<<<
 * 			# We fill up the arrays with with random numbers sampled from a uniform distribution described
 * 			# by either umin and umax or mmin and mmax. We fill them up column-by-column to avoid
 */
    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_GetAttr(__pyx_1, __pyx_kp_random); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_3 = PyObject_GetAttr(__pyx_6, __pyx_kp_RandomState); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_seed); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
    __pyx_2 = 0;
    __pyx_6 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 164; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    Py_DECREF(__pyx_v_rs);
    __pyx_v_rs = __pyx_6;
    __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":168
 * 			# by either umin and umax or mmin and mmax. We fill them up column-by-column to avoid
 * 			# a whole-array memory copy. Kind of hacky, but it works. No help from the NumPy message boards on an alternative.
 * 			for i in range(self.numfeatures):             # <<<<<<<<<<<<<<
 * 				U[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 				M[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 */
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
    __pyx_2 = 0;
    __pyx_1 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
    if (PyList_CheckExact(__pyx_1) || PyTuple_CheckExact(__pyx_1)) {
      __pyx_7 = 0; __pyx_6 = __pyx_1; Py_INCREF(__pyx_6);
    } else {
      __pyx_7 = -1; __pyx_6 = PyObject_GetIter(__pyx_1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    for (;;) {
      if (likely(PyList_CheckExact(__pyx_6))) {
        if (__pyx_7 >= PyList_GET_SIZE(__pyx_6)) break;
        __pyx_2 = PyList_GET_ITEM(__pyx_6, __pyx_7); Py_INCREF(__pyx_2); __pyx_7++;
      } else if (likely(PyTuple_CheckExact(__pyx_6))) {
        if (__pyx_7 >= PyTuple_GET_SIZE(__pyx_6)) break;
        __pyx_2 = PyTuple_GET_ITEM(__pyx_6, __pyx_7); Py_INCREF(__pyx_2); __pyx_7++;
      } else {
        __pyx_2 = PyIter_Next(__pyx_6);
        if (!__pyx_2) {
          if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          break;
        }
      }
      Py_DECREF(__pyx_v_i);
      __pyx_v_i = __pyx_2;
      __pyx_2 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":169
 * 			# a whole-array memory copy. Kind of hacky, but it works. No help from the NumPy message boards on an alternative.
 * 			for i in range(self.numfeatures):
 * 				U[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')             # <<<<<<<<<<<<<<
 * 				M[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			if updateFeatures == self.nsvd1 or updateFeatures == self.hybrid:
 */
      __pyx_3 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_uniform); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umin); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_1, __pyx_kp_low, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umax); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_1, __pyx_kp_high, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numusers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_1, __pyx_kp_size, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_2 = PyEval_CallObjectWithKeywords(__pyx_3, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      __pyx_3 = PyObject_GetAttr(__pyx_2, __pyx_kp_astype); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(__pyx_kp_75);
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_75);
      __pyx_2 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_3);
      Py_INCREF(__pyx_v_i);
      PyTuple_SET_ITEM(__pyx_1, 1, __pyx_v_i);
      __pyx_3 = 0;
      if (PyObject_SetItem(((PyObject *)__pyx_v_U), ((PyObject *)__pyx_1), __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 169; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":170
 * 			for i in range(self.numfeatures):
 * 				U[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 				M[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')             # <<<<<<<<<<<<<<
 * 			if updateFeatures == self.nsvd1 or updateFeatures == self.hybrid:
 * 				self.W = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 */
      __pyx_3 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_uniform); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyDict_New(); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_mmin); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_2, __pyx_kp_low, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_mmax); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_2, __pyx_kp_high, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nummovies); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_2, __pyx_kp_size, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyEval_CallObjectWithKeywords(__pyx_3, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_2)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_astype); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(__pyx_kp_76);
      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_76);
      __pyx_1 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_3);
      Py_INCREF(__pyx_v_i);
      PyTuple_SET_ITEM(__pyx_2, 1, __pyx_v_i);
      __pyx_3 = 0;
      if (PyObject_SetItem(((PyObject *)__pyx_v_M), ((PyObject *)__pyx_2), __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 170; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
    }
    Py_DECREF(__pyx_6); __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":171
 * 				U[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 				M[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			if updateFeatures == self.nsvd1 or updateFeatures == self.hybrid:             # <<<<<<<<<<<<<<
 * 				self.W = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_29); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_3, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    if (!__pyx_4) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_hybrid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_2, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 171; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
    }
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":172
 * 				M[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			if updateFeatures == self.nsvd1 or updateFeatures == self.hybrid:
 * 				self.W = N.zeros((self.nummovies, self.numfeatures), dtype='float32')             # <<<<<<<<<<<<<<
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 */
      __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_3, __pyx_kp_zeros); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nummovies); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_3, 0, __pyx_2);
      PyTuple_SET_ITEM(__pyx_3, 1, __pyx_6);
      __pyx_2 = 0;
      __pyx_6 = 0;
      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_3));
      __pyx_3 = 0;
      __pyx_6 = PyDict_New(); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_6, __pyx_kp_dtype, __pyx_kp_77) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyEval_CallObjectWithKeywords(__pyx_1, ((PyObject *)__pyx_2), ((PyObject *)__pyx_6)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
      if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_W, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 172; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":173
 * 			if updateFeatures == self.nsvd1 or updateFeatures == self.hybrid:
 * 				self.W = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):             # <<<<<<<<<<<<<<
 * 					self.W[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			elif updateFeatures==self.nsvd2 or updateFeatures==self.hybrid2:
 */
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
      __pyx_1 = 0;
      __pyx_6 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      if (PyList_CheckExact(__pyx_6) || PyTuple_CheckExact(__pyx_6)) {
        __pyx_7 = 0; __pyx_3 = __pyx_6; Py_INCREF(__pyx_3);
      } else {
        __pyx_7 = -1; __pyx_3 = PyObject_GetIter(__pyx_6); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      for (;;) {
        if (likely(PyList_CheckExact(__pyx_3))) {
          if (__pyx_7 >= PyList_GET_SIZE(__pyx_3)) break;
          __pyx_1 = PyList_GET_ITEM(__pyx_3, __pyx_7); Py_INCREF(__pyx_1); __pyx_7++;
        } else if (likely(PyTuple_CheckExact(__pyx_3))) {
          if (__pyx_7 >= PyTuple_GET_SIZE(__pyx_3)) break;
          __pyx_1 = PyTuple_GET_ITEM(__pyx_3, __pyx_7); Py_INCREF(__pyx_1); __pyx_7++;
        } else {
          __pyx_1 = PyIter_Next(__pyx_3);
          if (!__pyx_1) {
            if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 173; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
            break;
          }
        }
        Py_DECREF(__pyx_v_i);
        __pyx_v_i = __pyx_1;
        __pyx_1 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":174
 * 				self.W = N.zeros((self.nummovies, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')             # <<<<<<<<<<<<<<
 * 			elif updateFeatures==self.nsvd2 or updateFeatures==self.hybrid2:
 * 				self.W = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 */
        __pyx_2 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_uniform); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PyDict_New(); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_mmin); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_low, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_1); __pyx_1 = 0;
        __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_mmax); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_high, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_1); __pyx_1 = 0;
        __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nummovies); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_size, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_1); __pyx_1 = 0;
        __pyx_1 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_6)); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_astype); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_1); __pyx_1 = 0;
        __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_INCREF(__pyx_kp_78);
        PyTuple_SET_ITEM(__pyx_6, 0, __pyx_kp_78);
        __pyx_1 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_8 = PyTuple_New(2); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        PyTuple_SET_ITEM(__pyx_8, 0, __pyx_6);
        Py_INCREF(__pyx_v_i);
        PyTuple_SET_ITEM(__pyx_8, 1, __pyx_v_i);
        __pyx_6 = 0;
        if (PyObject_SetItem(__pyx_2, ((PyObject *)__pyx_8), __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 174; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
        Py_DECREF(__pyx_1); __pyx_1 = 0;
      }
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      goto __pyx_L9;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":175
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			elif updateFeatures==self.nsvd2 or updateFeatures==self.hybrid2:             # <<<<<<<<<<<<<<
 * 				self.W = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 */
    __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_30); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_6, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    if (!__pyx_5) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_32); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_2, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 175; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
    }
    if (__pyx_5) {

      /* "/home/alex/workspace/flix/src/svd.pyx":176
 * 					self.W[:,i] = rs.uniform(low=self.mmin, high=self.mmax, size=self.nummovies).astype('float32')
 * 			elif updateFeatures==self.nsvd2 or updateFeatures==self.hybrid2:
 * 				self.W = N.zeros((self.numusers, self.numfeatures), dtype='float32')             # <<<<<<<<<<<<<<
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 */
      __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_GetAttr(__pyx_3, __pyx_kp_zeros); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numusers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyTuple_New(2); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_8, 0, __pyx_1);
      PyTuple_SET_ITEM(__pyx_8, 1, __pyx_2);
      __pyx_1 = 0;
      __pyx_2 = 0;
      __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_8));
      __pyx_8 = 0;
      __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_79) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyEval_CallObjectWithKeywords(__pyx_6, ((PyObject *)__pyx_3), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_W, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 176; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":177
 * 			elif updateFeatures==self.nsvd2 or updateFeatures==self.hybrid2:
 * 				self.W = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):             # <<<<<<<<<<<<<<
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 			elif updateFeatures==self.snmf:
 */
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_6, 0, __pyx_8);
      __pyx_8 = 0;
      __pyx_3 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
      if (PyList_CheckExact(__pyx_3) || PyTuple_CheckExact(__pyx_3)) {
        __pyx_7 = 0; __pyx_1 = __pyx_3; Py_INCREF(__pyx_1);
      } else {
        __pyx_7 = -1; __pyx_1 = PyObject_GetIter(__pyx_3); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      for (;;) {
        if (likely(PyList_CheckExact(__pyx_1))) {
          if (__pyx_7 >= PyList_GET_SIZE(__pyx_1)) break;
          __pyx_2 = PyList_GET_ITEM(__pyx_1, __pyx_7); Py_INCREF(__pyx_2); __pyx_7++;
        } else if (likely(PyTuple_CheckExact(__pyx_1))) {
          if (__pyx_7 >= PyTuple_GET_SIZE(__pyx_1)) break;
          __pyx_2 = PyTuple_GET_ITEM(__pyx_1, __pyx_7); Py_INCREF(__pyx_2); __pyx_7++;
        } else {
          __pyx_2 = PyIter_Next(__pyx_1);
          if (!__pyx_2) {
            if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 177; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
            break;
          }
        }
        Py_DECREF(__pyx_v_i);
        __pyx_v_i = __pyx_2;
        __pyx_2 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":178
 * 				self.W = N.zeros((self.numusers, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')             # <<<<<<<<<<<<<<
 * 			elif updateFeatures==self.snmf:
 * 				self.W = N.zeros((self.numnodes, self.numfeatures), dtype='float32')
 */
        __pyx_8 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_uniform); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PyDict_New(); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umin); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_low, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umax); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_high, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numusers); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_6, __pyx_kp_size, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_2 = PyEval_CallObjectWithKeywords(__pyx_8, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_6)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_8); __pyx_8 = 0;
        Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
        __pyx_3 = PyObject_GetAttr(__pyx_2, __pyx_kp_astype); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        __pyx_8 = PyTuple_New(1); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_INCREF(__pyx_kp_80);
        PyTuple_SET_ITEM(__pyx_8, 0, __pyx_kp_80);
        __pyx_6 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_8), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_8 = PyTuple_New(2); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        PyTuple_SET_ITEM(__pyx_8, 0, __pyx_3);
        Py_INCREF(__pyx_v_i);
        PyTuple_SET_ITEM(__pyx_8, 1, __pyx_v_i);
        __pyx_3 = 0;
        if (PyObject_SetItem(__pyx_2, ((PyObject *)__pyx_8), __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 178; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
        Py_DECREF(__pyx_6); __pyx_6 = 0;
      }
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L9;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":179
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 			elif updateFeatures==self.snmf:             # <<<<<<<<<<<<<<
 * 				self.W = N.zeros((self.numnodes, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_snmf); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_3, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":180
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numusers).astype('float32')
 * 			elif updateFeatures==self.snmf:
 * 				self.W = N.zeros((self.numnodes, self.numfeatures), dtype='float32')             # <<<<<<<<<<<<<<
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numnodes).astype('float32')
 */
      __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_GetAttr(__pyx_2, __pyx_kp_zeros); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numnodes); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_6, 0, __pyx_1);
      PyTuple_SET_ITEM(__pyx_6, 1, __pyx_3);
      __pyx_1 = 0;
      __pyx_3 = 0;
      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_6));
      __pyx_6 = 0;
      __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_81) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyEval_CallObjectWithKeywords(__pyx_8, ((PyObject *)__pyx_2), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_W, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 180; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":181
 * 			elif updateFeatures==self.snmf:
 * 				self.W = N.zeros((self.numnodes, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):             # <<<<<<<<<<<<<<
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numnodes).astype('float32')
 * 		else:
 */
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyTuple_New(1); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_8, 0, __pyx_6);
      __pyx_6 = 0;
      __pyx_2 = PyObject_Call(__pyx_builtin_range, ((PyObject *)__pyx_8), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
      if (PyList_CheckExact(__pyx_2) || PyTuple_CheckExact(__pyx_2)) {
        __pyx_7 = 0; __pyx_1 = __pyx_2; Py_INCREF(__pyx_1);
      } else {
        __pyx_7 = -1; __pyx_1 = PyObject_GetIter(__pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      for (;;) {
        if (likely(PyList_CheckExact(__pyx_1))) {
          if (__pyx_7 >= PyList_GET_SIZE(__pyx_1)) break;
          __pyx_3 = PyList_GET_ITEM(__pyx_1, __pyx_7); Py_INCREF(__pyx_3); __pyx_7++;
        } else if (likely(PyTuple_CheckExact(__pyx_1))) {
          if (__pyx_7 >= PyTuple_GET_SIZE(__pyx_1)) break;
          __pyx_3 = PyTuple_GET_ITEM(__pyx_1, __pyx_7); Py_INCREF(__pyx_3); __pyx_7++;
        } else {
          __pyx_3 = PyIter_Next(__pyx_1);
          if (!__pyx_3) {
            if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 181; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
            break;
          }
        }
        Py_DECREF(__pyx_v_i);
        __pyx_v_i = __pyx_3;
        __pyx_3 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":182
 * 				self.W = N.zeros((self.numnodes, self.numfeatures), dtype='float32')
 * 				for i in range(self.numfeatures):
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numnodes).astype('float32')             # <<<<<<<<<<<<<<
 * 		else:
 * 			print('Using pre-defined matrices')
 */
        __pyx_6 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_uniform); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_8 = PyDict_New(); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umin); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_8, __pyx_kp_low, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_umax); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_8, __pyx_kp_high, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numnodes); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (PyDict_SetItem(__pyx_8, __pyx_kp_size, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        __pyx_3 = PyEval_CallObjectWithKeywords(__pyx_6, ((PyObject *)__pyx_empty_tuple), ((PyObject *)__pyx_8)); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_6); __pyx_6 = 0;
        Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
        __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_kp_astype); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_INCREF(__pyx_kp_82);
        PyTuple_SET_ITEM(__pyx_6, 0, __pyx_kp_82);
        __pyx_8 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
        __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        PyTuple_SET_ITEM(__pyx_6, 0, __pyx_2);
        Py_INCREF(__pyx_v_i);
        PyTuple_SET_ITEM(__pyx_6, 1, __pyx_v_i);
        __pyx_2 = 0;
        if (PyObject_SetItem(__pyx_3, ((PyObject *)__pyx_6), __pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
        Py_DECREF(__pyx_8); __pyx_8 = 0;
      }
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L9;
    }
    __pyx_L9:;
    goto __pyx_L6;
  }
  /*else*/ {

    /* "/home/alex/workspace/flix/src/svd.pyx":184
 * 					self.W[:,i] = rs.uniform(low=self.umin, high=self.umax, size=self.numnodes).astype('float32')
 * 		else:
 * 			print('Using pre-defined matrices')             # <<<<<<<<<<<<<<
 * 			if not hasattr(self, 'U') and not hasattr(self, 'M'):
 * 				raise ValueError, 'Must have U and M matrices declared to use the havemats=True option'
 */
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_83);
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_83);
    if (__Pyx_Print(((PyObject *)__pyx_2), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 184; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":185
 * 		else:
 * 			print('Using pre-defined matrices')
 * 			if not hasattr(self, 'U') and not hasattr(self, 'M'):             # <<<<<<<<<<<<<<
 * 				raise ValueError, 'Must have U and M matrices declared to use the havemats=True option'
 * 			U = self.U
 */
    __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_84); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!__pyx_4);
    if (__pyx_5) {
      __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_85); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_5 = (!__pyx_4);
    }
    if (__pyx_5) {

      /* "/home/alex/workspace/flix/src/svd.pyx":186
 * 			print('Using pre-defined matrices')
 * 			if not hasattr(self, 'U') and not hasattr(self, 'M'):
 * 				raise ValueError, 'Must have U and M matrices declared to use the havemats=True option'             # <<<<<<<<<<<<<<
 * 			U = self.U
 * 			M = self.M
 */
      __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_86, 0);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      goto __pyx_L16;
    }
    __pyx_L16:;

    /* "/home/alex/workspace/flix/src/svd.pyx":187
 * 			if not hasattr(self, 'U') and not hasattr(self, 'M'):
 * 				raise ValueError, 'Must have U and M matrices declared to use the havemats=True option'
 * 			U = self.U             # <<<<<<<<<<<<<<
 * 			M = self.M
 * 
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_U); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_8, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_2 = ((PyArrayObject *)__pyx_8);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __pyx_t_3 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0);
    if (unlikely(__pyx_t_3 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_1, &__pyx_t_4, &__pyx_t_5);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
            Py_XDECREF(__pyx_t_1); Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_5);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_1, __pyx_t_4, __pyx_t_5);
        }
    }
    __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
    __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
    if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 187; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_2 = 0;
    Py_DECREF(((PyObject *)__pyx_v_U));
    __pyx_v_U = ((PyArrayObject *)__pyx_8);
    __pyx_8 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":188
 * 				raise ValueError, 'Must have U and M matrices declared to use the havemats=True option'
 * 			U = self.U
 * 			M = self.M             # <<<<<<<<<<<<<<
 * 
 * 		if updateFeatures in [self.brismf, self.nsvd0, self.nsvd1, self.nsvd2, self.nsvd3, self.snmf]:
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_M); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_6 = ((PyArrayObject *)__pyx_3);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __pyx_t_3 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_6, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0);
    if (unlikely(__pyx_t_3 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_5, &__pyx_t_4, &__pyx_t_1);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
            Py_XDECREF(__pyx_t_5); Py_XDECREF(__pyx_t_4); Py_XDECREF(__pyx_t_1);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_5, __pyx_t_4, __pyx_t_1);
        }
    }
    __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
    __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
    if (unlikely(__pyx_t_3 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 188; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_6 = 0;
    Py_DECREF(((PyObject *)__pyx_v_M));
    __pyx_v_M = ((PyArrayObject *)__pyx_3);
    __pyx_3 = 0;
  }
  __pyx_L6:;

  /* "/home/alex/workspace/flix/src/svd.pyx":190
 * 			M = self.M
 * 
 * 		if updateFeatures in [self.brismf, self.nsvd0, self.nsvd1, self.nsvd2, self.nsvd3, self.snmf]:             # <<<<<<<<<<<<<<
 * 			U[:,0] = 1.0
 * 			M[:,1] = 1.0
 */
  __pyx_6 = __pyx_v_updateFeatures;
  Py_INCREF(__pyx_6);
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_brismf); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_RichCompare(__pyx_6, __pyx_1, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_4 = ((int)__pyx_5);
  if (!__pyx_4) {
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nsvd0); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_RichCompare(__pyx_6, __pyx_8, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_4 = ((int)__pyx_5);
  }
  if (!__pyx_4) {
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_29); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_RichCompare(__pyx_6, __pyx_1, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = ((int)__pyx_5);
  }
  if (!__pyx_4) {
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_30); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_RichCompare(__pyx_6, __pyx_8, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_4 = ((int)__pyx_5);
  }
  if (!__pyx_4) {
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_31); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_RichCompare(__pyx_6, __pyx_1, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = ((int)__pyx_5);
  }
  if (!__pyx_4) {
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_snmf); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_RichCompare(__pyx_6, __pyx_8, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 190; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_4 = ((int)__pyx_5);
  }
  if (__pyx_4) {

    /* "/home/alex/workspace/flix/src/svd.pyx":191
 * 
 * 		if updateFeatures in [self.brismf, self.nsvd0, self.nsvd1, self.nsvd2, self.nsvd3, self.snmf]:
 * 			U[:,0] = 1.0             # <<<<<<<<<<<<<<
 * 			M[:,1] = 1.0
 * 
 */
    __pyx_1 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_2);
    Py_INCREF(__pyx_int_0);
    PyTuple_SET_ITEM(__pyx_6, 1, __pyx_int_0);
    __pyx_2 = 0;
    if (PyObject_SetItem(((PyObject *)__pyx_v_U), ((PyObject *)__pyx_6), __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 191; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    Py_DECREF(__pyx_1); __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":192
 * 		if updateFeatures in [self.brismf, self.nsvd0, self.nsvd1, self.nsvd2, self.nsvd3, self.snmf]:
 * 			U[:,0] = 1.0
 * 			M[:,1] = 1.0             # <<<<<<<<<<<<<<
 * 
 * 		if updateFeatures in [self.hybrid, self.hybrid2]:
 */
    __pyx_8 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_3);
    Py_INCREF(__pyx_int_1);
    PyTuple_SET_ITEM(__pyx_2, 1, __pyx_int_1);
    __pyx_3 = 0;
    if (PyObject_SetItem(((PyObject *)__pyx_v_M), ((PyObject *)__pyx_2), __pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    goto __pyx_L17;
  }
  __pyx_L17:;

  /* "/home/alex/workspace/flix/src/svd.pyx":194
 * 			M[:,1] = 1.0
 * 
 * 		if updateFeatures in [self.hybrid, self.hybrid2]:             # <<<<<<<<<<<<<<
 * 			U[:,self.numfeaturesmf] = 1.0
 * 			M[:,self.numfeaturesmf+1] = 1.0
 */
  __pyx_1 = __pyx_v_updateFeatures;
  Py_INCREF(__pyx_1);
  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_hybrid); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyObject_RichCompare(__pyx_1, __pyx_6, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_5 = ((int)__pyx_4);
  if (!__pyx_5) {
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_32); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_RichCompare(__pyx_1, __pyx_8, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 194; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_5 = ((int)__pyx_4);
  }
  if (__pyx_5) {

    /* "/home/alex/workspace/flix/src/svd.pyx":195
 * 
 * 		if updateFeatures in [self.hybrid, self.hybrid2]:
 * 			U[:,self.numfeaturesmf] = 1.0             # <<<<<<<<<<<<<<
 * 			M[:,self.numfeaturesmf+1] = 1.0
 * 			assert hasattr(self, 'beta'), 'Need parameter beta'
 */
    __pyx_6 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_8 = PyTuple_New(2); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_8, 0, __pyx_3);
    PyTuple_SET_ITEM(__pyx_8, 1, __pyx_1);
    __pyx_3 = 0;
    __pyx_1 = 0;
    if (PyObject_SetItem(((PyObject *)__pyx_v_U), ((PyObject *)__pyx_8), __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
    Py_DECREF(__pyx_6); __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":196
 * 		if updateFeatures in [self.hybrid, self.hybrid2]:
 * 			U[:,self.numfeaturesmf] = 1.0
 * 			M[:,self.numfeaturesmf+1] = 1.0             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'beta'), 'Need parameter beta'
 * 			assert hasattr(self, 'numfeaturesmf'), 'Need parameter numfeaturesmf'
 */
    __pyx_2 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_1 = PyNumber_Add(__pyx_1, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_3);
    PyTuple_SET_ITEM(__pyx_6, 1, __pyx_t_1);
    __pyx_3 = 0;
    __pyx_t_1 = 0;
    if (PyObject_SetItem(((PyObject *)__pyx_v_M), ((PyObject *)__pyx_6), __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    Py_DECREF(__pyx_2); __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":197
 * 			U[:,self.numfeaturesmf] = 1.0
 * 			M[:,self.numfeaturesmf+1] = 1.0
 * 			assert hasattr(self, 'beta'), 'Need parameter beta'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'numfeaturesmf'), 'Need parameter numfeaturesmf'
 * 			assert hasattr(self, 'lrateUn'), 'Need parameter lrateUn'
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_87); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_4)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_88);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 197; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":198
 * 			M[:,self.numfeaturesmf+1] = 1.0
 * 			assert hasattr(self, 'beta'), 'Need parameter beta'
 * 			assert hasattr(self, 'numfeaturesmf'), 'Need parameter numfeaturesmf'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'lrateUn'), 'Need parameter lrateUn'
 * 			assert hasattr(self, 'lrateMn'), 'Need parameter lrateMn'
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_5 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_89); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_5)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_90);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":199
 * 			assert hasattr(self, 'beta'), 'Need parameter beta'
 * 			assert hasattr(self, 'numfeaturesmf'), 'Need parameter numfeaturesmf'
 * 			assert hasattr(self, 'lrateUn'), 'Need parameter lrateUn'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'lrateMn'), 'Need parameter lrateMn'
 * 			assert hasattr(self, 'dampfactUn'), 'Need parameter dampfactUn'
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_91); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_4)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_92);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":200
 * 			assert hasattr(self, 'numfeaturesmf'), 'Need parameter numfeaturesmf'
 * 			assert hasattr(self, 'lrateUn'), 'Need parameter lrateUn'
 * 			assert hasattr(self, 'lrateMn'), 'Need parameter lrateMn'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'dampfactUn'), 'Need parameter dampfactUn'
 * 			assert hasattr(self, 'dampfactMn'), 'Need parameter dampfactMn'
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_5 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_93); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_5)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_94);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":201
 * 			assert hasattr(self, 'lrateUn'), 'Need parameter lrateUn'
 * 			assert hasattr(self, 'lrateMn'), 'Need parameter lrateMn'
 * 			assert hasattr(self, 'dampfactUn'), 'Need parameter dampfactUn'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'dampfactMn'), 'Need parameter dampfactMn'
 * 			if 'beta' not in self.parameters: self.parameters.append('beta')
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_95); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_4)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_96);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":202
 * 			assert hasattr(self, 'lrateMn'), 'Need parameter lrateMn'
 * 			assert hasattr(self, 'dampfactUn'), 'Need parameter dampfactUn'
 * 			assert hasattr(self, 'dampfactMn'), 'Need parameter dampfactMn'             # <<<<<<<<<<<<<<
 * 			if 'beta' not in self.parameters: self.parameters.append('beta')
 * 			if 'lrateUn' not in self.parameters: self.parameters.append('lrateUn')
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_5 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_97); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_5)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_98);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 202; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":203
 * 			assert hasattr(self, 'dampfactUn'), 'Need parameter dampfactUn'
 * 			assert hasattr(self, 'dampfactMn'), 'Need parameter dampfactMn'
 * 			if 'beta' not in self.parameters: self.parameters.append('beta')             # <<<<<<<<<<<<<<
 * 			if 'lrateUn' not in self.parameters: self.parameters.append('lrateUn')
 * 			if 'lrateMn' not in self.parameters: self.parameters.append('lrateMn')
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = (!PySequence_Contains(__pyx_8, __pyx_kp_99)); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    if (__pyx_4) {
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = __Pyx_PyObject_Append(__pyx_1, __pyx_kp_100); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 203; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      goto __pyx_L19;
    }
    __pyx_L19:;

    /* "/home/alex/workspace/flix/src/svd.pyx":204
 * 			assert hasattr(self, 'dampfactMn'), 'Need parameter dampfactMn'
 * 			if 'beta' not in self.parameters: self.parameters.append('beta')
 * 			if 'lrateUn' not in self.parameters: self.parameters.append('lrateUn')             # <<<<<<<<<<<<<<
 * 			if 'lrateMn' not in self.parameters: self.parameters.append('lrateMn')
 * 			if 'dampfactUn' not in self.parameters: self.parameters.append('dampfactUn')
 */
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!PySequence_Contains(__pyx_2, __pyx_kp_101)); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    if (__pyx_5) {
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = __Pyx_PyObject_Append(__pyx_6, __pyx_kp_102); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      goto __pyx_L20;
    }
    __pyx_L20:;

    /* "/home/alex/workspace/flix/src/svd.pyx":205
 * 			if 'beta' not in self.parameters: self.parameters.append('beta')
 * 			if 'lrateUn' not in self.parameters: self.parameters.append('lrateUn')
 * 			if 'lrateMn' not in self.parameters: self.parameters.append('lrateMn')             # <<<<<<<<<<<<<<
 * 			if 'dampfactUn' not in self.parameters: self.parameters.append('dampfactUn')
 * 			if 'dampfactMn' not in self.parameters: self.parameters.append('dampfactMn')
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = (!PySequence_Contains(__pyx_1, __pyx_kp_103)); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    if (__pyx_4) {
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = __Pyx_PyObject_Append(__pyx_3, __pyx_kp_104); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      goto __pyx_L21;
    }
    __pyx_L21:;

    /* "/home/alex/workspace/flix/src/svd.pyx":206
 * 			if 'lrateUn' not in self.parameters: self.parameters.append('lrateUn')
 * 			if 'lrateMn' not in self.parameters: self.parameters.append('lrateMn')
 * 			if 'dampfactUn' not in self.parameters: self.parameters.append('dampfactUn')             # <<<<<<<<<<<<<<
 * 			if 'dampfactMn' not in self.parameters: self.parameters.append('dampfactMn')
 * 			if 'numfeaturesmf' not in self.properties: self.properties.append('numfeaturesmf')
 */
    __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!PySequence_Contains(__pyx_6, __pyx_kp_105)); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    if (__pyx_5) {
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = __Pyx_PyObject_Append(__pyx_8, __pyx_kp_106); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L22;
    }
    __pyx_L22:;

    /* "/home/alex/workspace/flix/src/svd.pyx":207
 * 			if 'lrateMn' not in self.parameters: self.parameters.append('lrateMn')
 * 			if 'dampfactUn' not in self.parameters: self.parameters.append('dampfactUn')
 * 			if 'dampfactMn' not in self.parameters: self.parameters.append('dampfactMn')             # <<<<<<<<<<<<<<
 * 			if 'numfeaturesmf' not in self.properties: self.properties.append('numfeaturesmf')
 * 			if updateFeatures == self.hybrid:
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = (!PySequence_Contains(__pyx_3, __pyx_kp_107)); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    if (__pyx_4) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_parameters); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = __Pyx_PyObject_Append(__pyx_2, __pyx_kp_108); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      goto __pyx_L23;
    }
    __pyx_L23:;

    /* "/home/alex/workspace/flix/src/svd.pyx":208
 * 			if 'dampfactUn' not in self.parameters: self.parameters.append('dampfactUn')
 * 			if 'dampfactMn' not in self.parameters: self.parameters.append('dampfactMn')
 * 			if 'numfeaturesmf' not in self.properties: self.properties.append('numfeaturesmf')             # <<<<<<<<<<<<<<
 * 			if updateFeatures == self.hybrid:
 * 				U[:,0:self.numfeaturesmf] = U[:,0:self.numfeaturesmf]*self.beta
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!PySequence_Contains(__pyx_8, __pyx_kp_109)); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    if (__pyx_5) {
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = __Pyx_PyObject_Append(__pyx_1, __pyx_kp_110); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 208; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      goto __pyx_L24;
    }
    __pyx_L24:;

    /* "/home/alex/workspace/flix/src/svd.pyx":209
 * 			if 'dampfactMn' not in self.parameters: self.parameters.append('dampfactMn')
 * 			if 'numfeaturesmf' not in self.properties: self.properties.append('numfeaturesmf')
 * 			if updateFeatures == self.hybrid:             # <<<<<<<<<<<<<<
 * 				U[:,0:self.numfeaturesmf] = U[:,0:self.numfeaturesmf]*self.beta
 * 			elif updateFeatures == self.hybrid2:
 */
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_hybrid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_2, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 209; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":210
 * 			if 'numfeaturesmf' not in self.properties: self.properties.append('numfeaturesmf')
 * 			if updateFeatures == self.hybrid:
 * 				U[:,0:self.numfeaturesmf] = U[:,0:self.numfeaturesmf]*self.beta             # <<<<<<<<<<<<<<
 * 			elif updateFeatures == self.hybrid2:
 * 				M[:,0:self.numfeaturesmf] = M[:,0:self.numfeaturesmf]*self.beta
 */
      __pyx_8 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PySlice_New(__pyx_int_0, __pyx_1, Py_None); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_8);
      PyTuple_SET_ITEM(__pyx_2, 1, __pyx_3);
      __pyx_8 = 0;
      __pyx_3 = 0;
      __pyx_6 = PyObject_GetItem(((PyObject *)__pyx_v_U), ((PyObject *)__pyx_2)); if (!__pyx_6) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_beta); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Multiply(__pyx_6, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_8 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PySlice_New(__pyx_int_0, __pyx_3, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_6 = PyTuple_New(2); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_6, 0, __pyx_8);
      PyTuple_SET_ITEM(__pyx_6, 1, __pyx_2);
      __pyx_8 = 0;
      __pyx_2 = 0;
      if (PyObject_SetItem(((PyObject *)__pyx_v_U), ((PyObject *)__pyx_6), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
      Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      goto __pyx_L25;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":211
 * 			if updateFeatures == self.hybrid:
 * 				U[:,0:self.numfeaturesmf] = U[:,0:self.numfeaturesmf]*self.beta
 * 			elif updateFeatures == self.hybrid2:             # <<<<<<<<<<<<<<
 * 				M[:,0:self.numfeaturesmf] = M[:,0:self.numfeaturesmf]*self.beta
 * 
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_32); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_RichCompare(__pyx_v_updateFeatures, __pyx_1, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 211; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    if (__pyx_5) {

      /* "/home/alex/workspace/flix/src/svd.pyx":212
 * 				U[:,0:self.numfeaturesmf] = U[:,0:self.numfeaturesmf]*self.beta
 * 			elif updateFeatures == self.hybrid2:
 * 				M[:,0:self.numfeaturesmf] = M[:,0:self.numfeaturesmf]*self.beta             # <<<<<<<<<<<<<<
 * 
 * 		if updateFeatures in [self.snmf]:
 */
      __pyx_8 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PySlice_New(__pyx_int_0, __pyx_2, Py_None); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_8);
      PyTuple_SET_ITEM(__pyx_1, 1, __pyx_6);
      __pyx_8 = 0;
      __pyx_6 = 0;
      __pyx_3 = PyObject_GetItem(((PyObject *)__pyx_v_M), ((PyObject *)__pyx_1)); if (!__pyx_3) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_beta); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Multiply(__pyx_3, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_8 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PySlice_New(__pyx_int_0, __pyx_6, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_3, 0, __pyx_8);
      PyTuple_SET_ITEM(__pyx_3, 1, __pyx_1);
      __pyx_8 = 0;
      __pyx_1 = 0;
      if (PyObject_SetItem(((PyObject *)__pyx_v_M), ((PyObject *)__pyx_3), __pyx_t_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 212; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
      Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      goto __pyx_L25;
    }
    __pyx_L25:;
    goto __pyx_L18;
  }
  __pyx_L18:;

  /* "/home/alex/workspace/flix/src/svd.pyx":214
 * 				M[:,0:self.numfeaturesmf] = M[:,0:self.numfeaturesmf]*self.beta
 * 
 * 		if updateFeatures in [self.snmf]:             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'numnodes'), 'Need parameter numnodes'
 * 			assert hasattr(self, 'numconnectednodes'), 'Need paramter numconnectednodes'
 */
  __pyx_2 = __pyx_v_updateFeatures;
  Py_INCREF(__pyx_2);
  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_snmf); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_8 = PyObject_RichCompare(__pyx_2, __pyx_6, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 214; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  __pyx_5 = ((int)__pyx_4);
  if (__pyx_5) {

    /* "/home/alex/workspace/flix/src/svd.pyx":215
 * 
 * 		if updateFeatures in [self.snmf]:
 * 			assert hasattr(self, 'numnodes'), 'Need parameter numnodes'             # <<<<<<<<<<<<<<
 * 			assert hasattr(self, 'numconnectednodes'), 'Need paramter numconnectednodes'
 * 			if 'numnodes' not in self.properties: self.properties.append('numnodes')
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_111); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_4)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_112);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 215; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":216
 * 		if updateFeatures in [self.snmf]:
 * 			assert hasattr(self, 'numnodes'), 'Need parameter numnodes'
 * 			assert hasattr(self, 'numconnectednodes'), 'Need paramter numconnectednodes'             # <<<<<<<<<<<<<<
 * 			if 'numnodes' not in self.properties: self.properties.append('numnodes')
 * 			if 'numconnectednodes' not in self.properties: self.properties.append('numconnectednoes')
 */
    #ifndef PYREX_WITHOUT_ASSERTIONS
    __pyx_5 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_113); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (unlikely(!__pyx_5)) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_114);
      {__pyx_filename = __pyx_f[0]; __pyx_lineno = 216; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    #endif

    /* "/home/alex/workspace/flix/src/svd.pyx":217
 * 			assert hasattr(self, 'numnodes'), 'Need parameter numnodes'
 * 			assert hasattr(self, 'numconnectednodes'), 'Need paramter numconnectednodes'
 * 			if 'numnodes' not in self.properties: self.properties.append('numnodes')             # <<<<<<<<<<<<<<
 * 			if 'numconnectednodes' not in self.properties: self.properties.append('numconnectednoes')
 * 
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = (!PySequence_Contains(__pyx_1, __pyx_kp_115)); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    if (__pyx_4) {
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = __Pyx_PyObject_Append(__pyx_3, __pyx_kp_116); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 217; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      goto __pyx_L27;
    }
    __pyx_L27:;

    /* "/home/alex/workspace/flix/src/svd.pyx":218
 * 			assert hasattr(self, 'numconnectednodes'), 'Need paramter numconnectednodes'
 * 			if 'numnodes' not in self.properties: self.properties.append('numnodes')
 * 			if 'numconnectednodes' not in self.properties: self.properties.append('numconnectednoes')             # <<<<<<<<<<<<<<
 * 
 * 		cdef int counter	  = 0
 */
    __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!PySequence_Contains(__pyx_6, __pyx_kp_117)); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    if (__pyx_5) {
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_properties); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = __Pyx_PyObject_Append(__pyx_8, __pyx_kp_118); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 218; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L28;
    }
    __pyx_L28:;
    goto __pyx_L26;
  }
  __pyx_L26:;

  /* "/home/alex/workspace/flix/src/svd.pyx":220
 * 			if 'numconnectednodes' not in self.properties: self.properties.append('numconnectednoes')
 * 
 * 		cdef int counter	  = 0             # <<<<<<<<<<<<<<
 * 		cdef int epoch		  = 0
 * 		cdef float oldRMSE	  = 0.0
 */
  __pyx_v_counter = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":221
 * 
 * 		cdef int counter	  = 0
 * 		cdef int epoch		  = 0             # <<<<<<<<<<<<<<
 * 		cdef float oldRMSE	  = 0.0
 * 		cdef float RMSE		  = 0.0
 */
  __pyx_v_epoch = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":222
 * 		cdef int counter	  = 0
 * 		cdef int epoch		  = 0
 * 		cdef float oldRMSE	  = 0.0             # <<<<<<<<<<<<<<
 * 		cdef float RMSE		  = 0.0
 * 		self.RMSEhistory	  = []
 */
  __pyx_v_oldRMSE = 0.0;

  /* "/home/alex/workspace/flix/src/svd.pyx":223
 * 		cdef int epoch		  = 0
 * 		cdef float oldRMSE	  = 0.0
 * 		cdef float RMSE		  = 0.0             # <<<<<<<<<<<<<<
 * 		self.RMSEhistory	  = []
 * 		done = False
 */
  __pyx_v_RMSE = 0.0;

  /* "/home/alex/workspace/flix/src/svd.pyx":224
 * 		cdef float oldRMSE	  = 0.0
 * 		cdef float RMSE		  = 0.0
 * 		self.RMSEhistory	  = []             # <<<<<<<<<<<<<<
 * 		done = False
 * 
 */
  __pyx_3 = PyList_New(0); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_RMSEhistory, ((PyObject *)__pyx_3)) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 224; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":225
 * 		cdef float RMSE		  = 0.0
 * 		self.RMSEhistory	  = []
 * 		done = False             # <<<<<<<<<<<<<<
 * 
 * 		RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs)
 */
  __pyx_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 225; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_done);
  __pyx_v_done = __pyx_2;
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":227
 * 		done = False
 * 
 * 		RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs)             # <<<<<<<<<<<<<<
 * 
 * 		self.updateLog('\nRMSE Error of random initialized data: %f' % RMSE)
 */
  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_checkError); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_8, __pyx_kp_userRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyObject_GetAttr(__pyx_8, __pyx_kp_movieIDs); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  __pyx_8 = PyTuple_New(5); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(((PyObject *)__pyx_v_U));
  PyTuple_SET_ITEM(__pyx_8, 0, ((PyObject *)__pyx_v_U));
  Py_INCREF(((PyObject *)__pyx_v_M));
  PyTuple_SET_ITEM(__pyx_8, 1, ((PyObject *)__pyx_v_M));
  PyTuple_SET_ITEM(__pyx_8, 2, __pyx_1);
  PyTuple_SET_ITEM(__pyx_8, 3, __pyx_2);
  PyTuple_SET_ITEM(__pyx_8, 4, __pyx_3);
  __pyx_1 = 0;
  __pyx_2 = 0;
  __pyx_3 = 0;
  __pyx_1 = PyObject_Call(__pyx_6, ((PyObject *)__pyx_8), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
  __pyx_9 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 227; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_RMSE = __pyx_9;

  /* "/home/alex/workspace/flix/src/svd.pyx":229
 * 		RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs)
 * 
 * 		self.updateLog('\nRMSE Error of random initialized data: %f' % RMSE)             # <<<<<<<<<<<<<<
 * 
 * 		while not done:
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyFloat_FromDouble(__pyx_v_RMSE); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Remainder(__pyx_kp_119, __pyx_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_8 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 229; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
  Py_DECREF(__pyx_8); __pyx_8 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":231
 * 		self.updateLog('\nRMSE Error of random initialized data: %f' % RMSE)
 * 
 * 		while not done:             # <<<<<<<<<<<<<<
 * 			epoch += 1
 * 			self.updateLog('\nTraining epoch: %d' % epoch)
 */
  while (1) {
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_v_done); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 231; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = (!__pyx_4);
    if (!__pyx_5) break;

    /* "/home/alex/workspace/flix/src/svd.pyx":232
 * 
 * 		while not done:
 * 			epoch += 1             # <<<<<<<<<<<<<<
 * 			self.updateLog('\nTraining epoch: %d' % epoch)
 * 
 */
    __pyx_v_epoch += 1;

    /* "/home/alex/workspace/flix/src/svd.pyx":233
 * 		while not done:
 * 			epoch += 1
 * 			self.updateLog('\nTraining epoch: %d' % epoch)             # <<<<<<<<<<<<<<
 * 
 * 
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyInt_FromLong(__pyx_v_epoch); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_1 = PyNumber_Remainder(__pyx_kp_120, __pyx_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_6 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 233; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    Py_DECREF(__pyx_6); __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":236
 * 
 * 
 * 			t1 = time()             # <<<<<<<<<<<<<<
 * 			# Update all features
 * 			if updateFeatures in [self.nsvd2, self.hybrid2, self.nsvd3]:
 */
    __pyx_8 = PyObject_Call(__pyx_v_time, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 236; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_t1);
    __pyx_v_t1 = __pyx_8;
    __pyx_8 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":238
 * 			t1 = time()
 * 			# Update all features
 * 			if updateFeatures in [self.nsvd2, self.hybrid2, self.nsvd3]:             # <<<<<<<<<<<<<<
 * 				updateFeatures(U, M, self.fd.movieRatings, self.fd.userIDs)
 * 			elif updateFeatures in [self.rmf, self.brismf, self.pmf, self.bpmf]:
 */
    __pyx_3 = __pyx_v_updateFeatures;
    Py_INCREF(__pyx_3);
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_30); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_RichCompare(__pyx_3, __pyx_1, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = ((int)__pyx_5);
    if (!__pyx_4) {
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_32); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_RichCompare(__pyx_3, __pyx_6, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      __pyx_4 = ((int)__pyx_5);
    }
    if (!__pyx_4) {
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_31); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_RichCompare(__pyx_3, __pyx_1, Py_EQ); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 238; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_4 = ((int)__pyx_5);
    }
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":239
 * 			# Update all features
 * 			if updateFeatures in [self.nsvd2, self.hybrid2, self.nsvd3]:
 * 				updateFeatures(U, M, self.fd.movieRatings, self.fd.userIDs)             # <<<<<<<<<<<<<<
 * 			elif updateFeatures in [self.rmf, self.brismf, self.pmf, self.bpmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.userIDsForUsers, self.fd.movieIDs)
 */
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_GetAttr(__pyx_6, __pyx_kp_movieRatings); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_3, __pyx_kp_userIDs); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_2 = PyTuple_New(4); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(((PyObject *)__pyx_v_U));
      PyTuple_SET_ITEM(__pyx_2, 0, ((PyObject *)__pyx_v_U));
      Py_INCREF(((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_2, 1, ((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_2, 2, __pyx_8);
      PyTuple_SET_ITEM(__pyx_2, 3, __pyx_1);
      __pyx_8 = 0;
      __pyx_1 = 0;
      __pyx_6 = PyObject_Call(__pyx_v_updateFeatures, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 239; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      goto __pyx_L31;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":240
 * 			if updateFeatures in [self.nsvd2, self.hybrid2, self.nsvd3]:
 * 				updateFeatures(U, M, self.fd.movieRatings, self.fd.userIDs)
 * 			elif updateFeatures in [self.rmf, self.brismf, self.pmf, self.bpmf]:             # <<<<<<<<<<<<<<
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.userIDsForUsers, self.fd.movieIDs)
 * 			elif updateFeatures in [self.nsvd0, self.nsvd1, self.hybrid, self.snmf]:
 */
    __pyx_3 = __pyx_v_updateFeatures;
    Py_INCREF(__pyx_3);
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_rmf); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_RichCompare(__pyx_3, __pyx_8, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = ((int)__pyx_4);
    if (!__pyx_5) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_brismf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_3, __pyx_2, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_5 = ((int)__pyx_4);
    }
    if (!__pyx_5) {
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_pmf); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_RichCompare(__pyx_3, __pyx_8, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_1); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_5 = ((int)__pyx_4);
    }
    if (!__pyx_5) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_bpmf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_3, __pyx_2, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely((__pyx_4 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 240; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_5 = ((int)__pyx_4);
    }
    if (__pyx_5) {

      /* "/home/alex/workspace/flix/src/svd.pyx":241
 * 				updateFeatures(U, M, self.fd.movieRatings, self.fd.userIDs)
 * 			elif updateFeatures in [self.rmf, self.brismf, self.pmf, self.bpmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.userIDsForUsers, self.fd.movieIDs)             # <<<<<<<<<<<<<<
 * 			elif updateFeatures in [self.nsvd0, self.nsvd1, self.hybrid, self.snmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.movieIDs)
 */
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_8, __pyx_kp_userRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_GetAttr(__pyx_6, __pyx_kp_movieIDs); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_3 = PyTuple_New(5); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(((PyObject *)__pyx_v_U));
      PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_v_U));
      Py_INCREF(((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_3, 1, ((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_3, 2, __pyx_1);
      PyTuple_SET_ITEM(__pyx_3, 3, __pyx_2);
      PyTuple_SET_ITEM(__pyx_3, 4, __pyx_8);
      __pyx_1 = 0;
      __pyx_2 = 0;
      __pyx_8 = 0;
      __pyx_6 = PyObject_Call(__pyx_v_updateFeatures, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 241; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      goto __pyx_L31;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":242
 * 			elif updateFeatures in [self.rmf, self.brismf, self.pmf, self.bpmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.userIDsForUsers, self.fd.movieIDs)
 * 			elif updateFeatures in [self.nsvd0, self.nsvd1, self.hybrid, self.snmf]:             # <<<<<<<<<<<<<<
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.movieIDs)
 * 			t2 = time()
 */
    __pyx_1 = __pyx_v_updateFeatures;
    Py_INCREF(__pyx_1);
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_nsvd0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_8 = PyObject_RichCompare(__pyx_1, __pyx_2, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_4 = ((int)__pyx_5);
    if (!__pyx_4) {
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_29); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_1, __pyx_3, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_4 = ((int)__pyx_5);
    }
    if (!__pyx_4) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_hybrid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_RichCompare(__pyx_1, __pyx_2, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      __pyx_4 = ((int)__pyx_5);
    }
    if (!__pyx_4) {
      __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_snmf); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_1, __pyx_3, Py_EQ); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(__pyx_3); __pyx_3 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely((__pyx_5 == (int)-1))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      __pyx_4 = ((int)__pyx_5);
    }
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":243
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.userIDsForUsers, self.fd.movieIDs)
 * 			elif updateFeatures in [self.nsvd0, self.nsvd1, self.hybrid, self.snmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.movieIDs)             # <<<<<<<<<<<<<<
 * 			t2 = time()
 * 
 */
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_GetAttr(__pyx_2, __pyx_kp_userRatings); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_movieIDs); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_6 = PyTuple_New(4); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(((PyObject *)__pyx_v_U));
      PyTuple_SET_ITEM(__pyx_6, 0, ((PyObject *)__pyx_v_U));
      Py_INCREF(((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_6, 1, ((PyObject *)__pyx_v_M));
      PyTuple_SET_ITEM(__pyx_6, 2, __pyx_8);
      PyTuple_SET_ITEM(__pyx_6, 3, __pyx_3);
      __pyx_8 = 0;
      __pyx_3 = 0;
      __pyx_2 = PyObject_Call(__pyx_v_updateFeatures, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      goto __pyx_L31;
    }
    __pyx_L31:;

    /* "/home/alex/workspace/flix/src/svd.pyx":244
 * 			elif updateFeatures in [self.nsvd0, self.nsvd1, self.hybrid, self.snmf]:
 * 				updateFeatures(U, M, self.fd.userRatings, self.fd.movieIDs)
 * 			t2 = time()             # <<<<<<<<<<<<<<
 * 
 * 			oldRMSE = RMSE
 */
    __pyx_1 = PyObject_Call(__pyx_v_time, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 244; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_t2);
    __pyx_v_t2 = __pyx_1;
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":246
 * 			t2 = time()
 * 
 * 			oldRMSE = RMSE             # <<<<<<<<<<<<<<
 * 
 * 			RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs) # Calculate the RMSE
 */
    __pyx_v_oldRMSE = __pyx_v_RMSE;

    /* "/home/alex/workspace/flix/src/svd.pyx":248
 * 			oldRMSE = RMSE
 * 
 * 			RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs) # Calculate the RMSE             # <<<<<<<<<<<<<<
 * 
 * 			if not RMSE < 0 and not RMSE > 0: # check for nan
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_checkError); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_GetAttr(__pyx_3, __pyx_kp_userRatings); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_3, __pyx_kp_movieIDs); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_3 = PyTuple_New(5); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(((PyObject *)__pyx_v_U));
    PyTuple_SET_ITEM(__pyx_3, 0, ((PyObject *)__pyx_v_U));
    Py_INCREF(((PyObject *)__pyx_v_M));
    PyTuple_SET_ITEM(__pyx_3, 1, ((PyObject *)__pyx_v_M));
    PyTuple_SET_ITEM(__pyx_3, 2, __pyx_6);
    PyTuple_SET_ITEM(__pyx_3, 3, __pyx_1);
    PyTuple_SET_ITEM(__pyx_3, 4, __pyx_2);
    __pyx_6 = 0;
    __pyx_1 = 0;
    __pyx_2 = 0;
    __pyx_6 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
    __pyx_9 = __pyx_PyFloat_AsDouble(__pyx_6); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 248; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    __pyx_v_RMSE = __pyx_9;

    /* "/home/alex/workspace/flix/src/svd.pyx":250
 * 			RMSE = self.checkError(U, M, self.td.userRatings, self.td.userIDsForUsers, self.td.movieIDs) # Calculate the RMSE
 * 
 * 			if not RMSE < 0 and not RMSE > 0: # check for nan             # <<<<<<<<<<<<<<
 * 				self.updateLog('\n\nWARNING: NaN values present!')
 * 				RMSE = 99999.0
 */
    __pyx_5 = (!(__pyx_v_RMSE < 0));
    if (__pyx_5) {
      __pyx_5 = (!(__pyx_v_RMSE > 0));
    }
    if (__pyx_5) {

      /* "/home/alex/workspace/flix/src/svd.pyx":251
 * 
 * 			if not RMSE < 0 and not RMSE > 0: # check for nan
 * 				self.updateLog('\n\nWARNING: NaN values present!')             # <<<<<<<<<<<<<<
 * 				RMSE = 99999.0
 * 				done = True
 */
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_INCREF(__pyx_kp_121);
      PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_121);
      __pyx_8 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
      Py_DECREF(__pyx_8); __pyx_8 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":252
 * 			if not RMSE < 0 and not RMSE > 0: # check for nan
 * 				self.updateLog('\n\nWARNING: NaN values present!')
 * 				RMSE = 99999.0             # <<<<<<<<<<<<<<
 * 				done = True
 * 				continue
 */
      __pyx_v_RMSE = 99999.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":253
 * 				self.updateLog('\n\nWARNING: NaN values present!')
 * 				RMSE = 99999.0
 * 				done = True             # <<<<<<<<<<<<<<
 * 				continue
 * 
 */
      __pyx_3 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_v_done);
      __pyx_v_done = __pyx_3;
      __pyx_3 = 0;

      /* "/home/alex/workspace/flix/src/svd.pyx":254
 * 				RMSE = 99999.0
 * 				done = True
 * 				continue             # <<<<<<<<<<<<<<
 * 
 * 			self.RMSEhistory.append(RMSE)
 */
      goto __pyx_L29;
      goto __pyx_L32;
    }
    __pyx_L32:;

    /* "/home/alex/workspace/flix/src/svd.pyx":256
 * 				continue
 * 
 * 			self.RMSEhistory.append(RMSE)             # <<<<<<<<<<<<<<
 * 			self.updateLog('\tRMSE: %f' % RMSE)
 * 			self.updateLog('\tTime: %f' % (t2-t1))
 */
    __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_RMSEhistory); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyFloat_FromDouble(__pyx_v_RMSE); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = __Pyx_PyObject_Append(__pyx_6, __pyx_1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(__pyx_2); __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":257
 * 
 * 			self.RMSEhistory.append(RMSE)
 * 			self.updateLog('\tRMSE: %f' % RMSE)             # <<<<<<<<<<<<<<
 * 			self.updateLog('\tTime: %f' % (t2-t1))
 * 
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyFloat_FromDouble(__pyx_v_RMSE); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_1 = PyNumber_Remainder(__pyx_kp_122, __pyx_3); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_1 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    Py_DECREF(__pyx_1); __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":258
 * 			self.RMSEhistory.append(RMSE)
 * 			self.updateLog('\tRMSE: %f' % RMSE)
 * 			self.updateLog('\tTime: %f' % (t2-t1))             # <<<<<<<<<<<<<<
 * 
 * 			deltaRMSE = oldRMSE - RMSE
 */
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_1 = PyNumber_Subtract(__pyx_v_t2, __pyx_v_t1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_4 = PyNumber_Remainder(__pyx_kp_123, __pyx_t_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_4);
    __pyx_t_4 = 0;
    __pyx_8 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
    Py_DECREF(__pyx_8); __pyx_8 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":260
 * 			self.updateLog('\tTime: %f' % (t2-t1))
 * 
 * 			deltaRMSE = oldRMSE - RMSE             # <<<<<<<<<<<<<<
 * 			if epoch >= self.miniters:
 * 				if deltaRMSE <= self.minimprovement:
 */
    __pyx_6 = PyFloat_FromDouble((__pyx_v_oldRMSE - __pyx_v_RMSE)); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 260; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_deltaRMSE);
    __pyx_v_deltaRMSE = __pyx_6;
    __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":261
 * 
 * 			deltaRMSE = oldRMSE - RMSE
 * 			if epoch >= self.miniters:             # <<<<<<<<<<<<<<
 * 				if deltaRMSE <= self.minimprovement:
 * 					counter += 1
 */
    __pyx_1 = PyInt_FromLong(__pyx_v_epoch); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_miniters); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_RichCompare(__pyx_1, __pyx_2, Py_GE); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 261; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    if (__pyx_4) {

      /* "/home/alex/workspace/flix/src/svd.pyx":262
 * 			deltaRMSE = oldRMSE - RMSE
 * 			if epoch >= self.miniters:
 * 				if deltaRMSE <= self.minimprovement:             # <<<<<<<<<<<<<<
 * 					counter += 1
 * 					if counter == self.itersForConvergence:
 */
      __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_minimprovement); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_6 = PyObject_RichCompare(__pyx_v_deltaRMSE, __pyx_8, Py_LE); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_6); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      if (__pyx_5) {

        /* "/home/alex/workspace/flix/src/svd.pyx":263
 * 			if epoch >= self.miniters:
 * 				if deltaRMSE <= self.minimprovement:
 * 					counter += 1             # <<<<<<<<<<<<<<
 * 					if counter == self.itersForConvergence:
 * 						done = True
 */
        __pyx_v_counter += 1;

        /* "/home/alex/workspace/flix/src/svd.pyx":264
 * 				if deltaRMSE <= self.minimprovement:
 * 					counter += 1
 * 					if counter == self.itersForConvergence:             # <<<<<<<<<<<<<<
 * 						done = True
 * 					continue
 */
        __pyx_1 = PyInt_FromLong(__pyx_v_counter); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_itersForConvergence); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_3 = PyObject_RichCompare(__pyx_1, __pyx_2, Py_EQ); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_1); __pyx_1 = 0;
        Py_DECREF(__pyx_2); __pyx_2 = 0;
        __pyx_4 = __Pyx_PyObject_IsTrue(__pyx_3); if (unlikely(__pyx_4 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 264; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        if (__pyx_4) {

          /* "/home/alex/workspace/flix/src/svd.pyx":265
 * 					counter += 1
 * 					if counter == self.itersForConvergence:
 * 						done = True             # <<<<<<<<<<<<<<
 * 					continue
 * 				elif RMSE > self.minimprovement:
 */
          __pyx_8 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 265; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_v_done);
          __pyx_v_done = __pyx_8;
          __pyx_8 = 0;
          goto __pyx_L35;
        }
        __pyx_L35:;

        /* "/home/alex/workspace/flix/src/svd.pyx":266
 * 					if counter == self.itersForConvergence:
 * 						done = True
 * 					continue             # <<<<<<<<<<<<<<
 * 				elif RMSE > self.minimprovement:
 * 					N.save(self.outnameU, U)
 */
        goto __pyx_L29;
        goto __pyx_L34;
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":267
 * 						done = True
 * 					continue
 * 				elif RMSE > self.minimprovement:             # <<<<<<<<<<<<<<
 * 					N.save(self.outnameU, U)
 * 					N.save(self.outnameM, M)
 */
      __pyx_6 = PyFloat_FromDouble(__pyx_v_RMSE); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_minimprovement); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_RichCompare(__pyx_6, __pyx_1, Py_GT); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_2); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 267; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      if (__pyx_5) {

        /* "/home/alex/workspace/flix/src/svd.pyx":268
 * 					continue
 * 				elif RMSE > self.minimprovement:
 * 					N.save(self.outnameU, U)             # <<<<<<<<<<<<<<
 * 					N.save(self.outnameM, M)
 * 					if hasattr(self, 'W'):
 */
        __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_8 = PyObject_GetAttr(__pyx_3, __pyx_kp_save); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameU); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        PyTuple_SET_ITEM(__pyx_1, 0, __pyx_6);
        Py_INCREF(((PyObject *)__pyx_v_U));
        PyTuple_SET_ITEM(__pyx_1, 1, ((PyObject *)__pyx_v_U));
        __pyx_6 = 0;
        __pyx_2 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 268; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_8); __pyx_8 = 0;
        Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
        Py_DECREF(__pyx_2); __pyx_2 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":269
 * 				elif RMSE > self.minimprovement:
 * 					N.save(self.outnameU, U)
 * 					N.save(self.outnameM, M)             # <<<<<<<<<<<<<<
 * 					if hasattr(self, 'W'):
 * 						N.save('w' + self.outnameU[1:], self.W)
 */
        __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PyObject_GetAttr(__pyx_3, __pyx_kp_save); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_3); __pyx_3 = 0;
        __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameM); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        PyTuple_SET_ITEM(__pyx_1, 0, __pyx_8);
        Py_INCREF(((PyObject *)__pyx_v_M));
        PyTuple_SET_ITEM(__pyx_1, 1, ((PyObject *)__pyx_v_M));
        __pyx_8 = 0;
        __pyx_2 = PyObject_Call(__pyx_6, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 269; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_6); __pyx_6 = 0;
        Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
        Py_DECREF(__pyx_2); __pyx_2 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":270
 * 					N.save(self.outnameU, U)
 * 					N.save(self.outnameM, M)
 * 					if hasattr(self, 'W'):             # <<<<<<<<<<<<<<
 * 						N.save('w' + self.outnameU[1:], self.W)
 * 
 */
        __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_124); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 270; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        if (__pyx_4) {

          /* "/home/alex/workspace/flix/src/svd.pyx":271
 * 					N.save(self.outnameM, M)
 * 					if hasattr(self, 'W'):
 * 						N.save('w' + self.outnameU[1:], self.W)             # <<<<<<<<<<<<<<
 * 
 * 				if epoch == self.maxepochs:
 */
          __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          __pyx_8 = PyObject_GetAttr(__pyx_3, __pyx_kp_save); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_3); __pyx_3 = 0;
          __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameU); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          __pyx_1 = PySequence_GetSlice(__pyx_6, 1, PY_SSIZE_T_MAX); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_6); __pyx_6 = 0;
          __pyx_t_4 = PyNumber_Add(__pyx_kp_125, __pyx_1); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_1); __pyx_1 = 0;
          __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          __pyx_3 = PyTuple_New(2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_4);
          PyTuple_SET_ITEM(__pyx_3, 1, __pyx_2);
          __pyx_t_4 = 0;
          __pyx_2 = 0;
          __pyx_6 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 271; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_8); __pyx_8 = 0;
          Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
          Py_DECREF(__pyx_6); __pyx_6 = 0;
          goto __pyx_L36;
        }
        __pyx_L36:;
        goto __pyx_L34;
      }
      __pyx_L34:;

      /* "/home/alex/workspace/flix/src/svd.pyx":273
 * 						N.save('w' + self.outnameU[1:], self.W)
 * 
 * 				if epoch == self.maxepochs:             # <<<<<<<<<<<<<<
 * 					done = True
 * 					continue
 */
      __pyx_1 = PyInt_FromLong(__pyx_v_epoch); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_maxepochs); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_8 = PyObject_RichCompare(__pyx_1, __pyx_2, Py_EQ); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_5 = __Pyx_PyObject_IsTrue(__pyx_8); if (unlikely(__pyx_5 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 273; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_8); __pyx_8 = 0;
      if (__pyx_5) {

        /* "/home/alex/workspace/flix/src/svd.pyx":274
 * 
 * 				if epoch == self.maxepochs:
 * 					done = True             # <<<<<<<<<<<<<<
 * 					continue
 * 				else:
 */
        __pyx_3 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 274; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_v_done);
        __pyx_v_done = __pyx_3;
        __pyx_3 = 0;

        /* "/home/alex/workspace/flix/src/svd.pyx":275
 * 				if epoch == self.maxepochs:
 * 					done = True
 * 					continue             # <<<<<<<<<<<<<<
 * 				else:
 * 					counter = 0
 */
        goto __pyx_L29;
        goto __pyx_L37;
      }
      /*else*/ {

        /* "/home/alex/workspace/flix/src/svd.pyx":277
 * 					continue
 * 				else:
 * 					counter = 0             # <<<<<<<<<<<<<<
 * 
 * 		# If the run was successful, load the models in,
 */
        __pyx_v_counter = 0;
      }
      __pyx_L37:;
      goto __pyx_L33;
    }
    __pyx_L33:;
    __pyx_L29:;
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":280
 * 
 * 		# If the run was successful, load the models in,
 * 		self.U = N.load(self.outnameU + '.npy')             # <<<<<<<<<<<<<<
 * 		self.M = N.load(self.outnameM + '.npy')
 * 		if hasattr(self, 'W'):
 */
  __pyx_6 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_6, __pyx_kp_load); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = PyNumber_Add(__pyx_2, __pyx_kp_126); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_8 = PyTuple_New(1); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_8, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_3 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_8), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_U, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 280; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":281
 * 		# If the run was successful, load the models in,
 * 		self.U = N.load(self.outnameU + '.npy')
 * 		self.M = N.load(self.outnameM + '.npy')             # <<<<<<<<<<<<<<
 * 		if hasattr(self, 'W'):
 * 			self.W = N.load('w'+self.outnameU[1:] + '.npy')
 */
  __pyx_6 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_6, __pyx_kp_load); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = PyNumber_Add(__pyx_1, __pyx_kp_127); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_8 = PyTuple_New(1); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_8, 0, __pyx_t_4);
  __pyx_t_4 = 0;
  __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_8), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_8)); __pyx_8 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_M, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 281; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":282
 * 		self.U = N.load(self.outnameU + '.npy')
 * 		self.M = N.load(self.outnameM + '.npy')
 * 		if hasattr(self, 'W'):             # <<<<<<<<<<<<<<
 * 			self.W = N.load('w'+self.outnameU[1:] + '.npy')
 * 		# close the logfile,
 */
  __pyx_4 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_128); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 282; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (__pyx_4) {

    /* "/home/alex/workspace/flix/src/svd.pyx":283
 * 		self.M = N.load(self.outnameM + '.npy')
 * 		if hasattr(self, 'W'):
 * 			self.W = N.load('w'+self.outnameU[1:] + '.npy')             # <<<<<<<<<<<<<<
 * 		# close the logfile,
 * 		self.logfile.close()
 */
    __pyx_6 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_6, __pyx_kp_load); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_outnameU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_8 = PySequence_GetSlice(__pyx_2, 1, PY_SSIZE_T_MAX); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_4 = PyNumber_Add(__pyx_kp_129, __pyx_8); if (unlikely(!__pyx_t_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    __pyx_t_1 = PyNumber_Add(__pyx_t_4, __pyx_kp_130); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_6 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
    if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_W, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 283; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_6); __pyx_6 = 0;
    goto __pyx_L38;
  }
  __pyx_L38:;

  /* "/home/alex/workspace/flix/src/svd.pyx":285
 * 			self.W = N.load('w'+self.outnameU[1:] + '.npy')
 * 		# close the logfile,
 * 		self.logfile.close()             # <<<<<<<<<<<<<<
 * 		# and spit out a probe10 prediction
 * 		probeRatings = self.makeProbePrediction(self.td.userIDsForUsers, self.td.movieIDs, 'probe')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_logfile); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_8 = PyObject_GetAttr(__pyx_2, __pyx_kp_close); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_1 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 285; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":287
 * 		self.logfile.close()
 * 		# and spit out a probe10 prediction
 * 		probeRatings = self.makeProbePrediction(self.td.userIDsForUsers, self.td.movieIDs, 'probe')             # <<<<<<<<<<<<<<
 * 		probeRatings.dump('probe10ratings')
 * 
 */
  __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_makeProbePrediction); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_6, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_8, __pyx_kp_movieIDs); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  __pyx_6 = PyTuple_New(3); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_2);
  PyTuple_SET_ITEM(__pyx_6, 1, __pyx_1);
  Py_INCREF(__pyx_kp_131);
  PyTuple_SET_ITEM(__pyx_6, 2, __pyx_kp_131);
  __pyx_2 = 0;
  __pyx_1 = 0;
  __pyx_8 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 287; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
  Py_DECREF(__pyx_v_probeRatings);
  __pyx_v_probeRatings = __pyx_8;
  __pyx_8 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":288
 * 		# and spit out a probe10 prediction
 * 		probeRatings = self.makeProbePrediction(self.td.userIDsForUsers, self.td.movieIDs, 'probe')
 * 		probeRatings.dump('probe10ratings')             # <<<<<<<<<<<<<<
 * 
 * 		if hasattr(self, 'qd'):
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_probeRatings, __pyx_kp_dump); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_132);
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_kp_132);
  __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 288; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  Py_DECREF(__pyx_3); __pyx_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":290
 * 		probeRatings.dump('probe10ratings')
 * 
 * 		if hasattr(self, 'qd'):             # <<<<<<<<<<<<<<
 * 			print('Making quiz ratings')
 * 			quizRatings = self.makeProbePrediction(self.qd.userIDsForUsers, self.qd.movieIDs, 'quiz')
 */
  __pyx_5 = PyObject_HasAttr(__pyx_v_self, __pyx_kp_133); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (__pyx_5) {

    /* "/home/alex/workspace/flix/src/svd.pyx":291
 * 
 * 		if hasattr(self, 'qd'):
 * 			print('Making quiz ratings')             # <<<<<<<<<<<<<<
 * 			quizRatings = self.makeProbePrediction(self.qd.userIDsForUsers, self.qd.movieIDs, 'quiz')
 * 			quizRatings.dump('quizratings')
 */
    __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_134);
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_kp_134);
    if (__Pyx_Print(((PyObject *)__pyx_6), 1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 291; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":292
 * 		if hasattr(self, 'qd'):
 * 			print('Making quiz ratings')
 * 			quizRatings = self.makeProbePrediction(self.qd.userIDsForUsers, self.qd.movieIDs, 'quiz')             # <<<<<<<<<<<<<<
 * 			quizRatings.dump('quizratings')
 * 
 */
    __pyx_8 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_makeProbePrediction); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_qd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_3 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_qd); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyObject_GetAttr(__pyx_3, __pyx_kp_movieIDs); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_2 = PyTuple_New(3); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
    PyTuple_SET_ITEM(__pyx_2, 1, __pyx_6);
    Py_INCREF(__pyx_kp_135);
    PyTuple_SET_ITEM(__pyx_2, 2, __pyx_kp_135);
    __pyx_1 = 0;
    __pyx_6 = 0;
    __pyx_3 = PyObject_Call(__pyx_8, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 292; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    Py_DECREF(__pyx_v_quizRatings);
    __pyx_v_quizRatings = __pyx_3;
    __pyx_3 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":293
 * 			print('Making quiz ratings')
 * 			quizRatings = self.makeProbePrediction(self.qd.userIDsForUsers, self.qd.movieIDs, 'quiz')
 * 			quizRatings.dump('quizratings')             # <<<<<<<<<<<<<<
 * 
 * 
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_quizRatings, __pyx_kp_dump); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_136);
    PyTuple_SET_ITEM(__pyx_6, 0, __pyx_kp_136);
    __pyx_8 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
    Py_DECREF(__pyx_8); __pyx_8 = 0;
    goto __pyx_L39;
  }
  __pyx_L39:;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_3);
  Py_XDECREF(__pyx_6);
  Py_XDECREF(__pyx_8);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.svd");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  Py_DECREF(__pyx_v_time);
  Py_DECREF(__pyx_v_join);
  Py_DECREF(__pyx_v_updateFeatures);
  Py_DECREF(__pyx_v_U);
  Py_DECREF(__pyx_v_M);
  Py_DECREF(__pyx_v_rs);
  Py_DECREF(__pyx_v_i);
  Py_DECREF(__pyx_v_done);
  Py_DECREF(__pyx_v_t1);
  Py_DECREF(__pyx_v_t2);
  Py_DECREF(__pyx_v_deltaRMSE);
  Py_DECREF(__pyx_v_probeRatings);
  Py_DECREF(__pyx_v_quizRatings);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":297
 * 
 * 
 * 	def makeProbePrediction(self, N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs, predicttype='probe'):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Make predictions for the probe data based on the loaded model.
 */

static PyObject *__pyx_pf_3svd_3SVD_makeProbePrediction(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_makeProbePrediction[] = "\n\t\tMake predictions for the probe data based on the loaded model.\n\t\tIt's not very efficient code, because it doesn't particularly need to be.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_makeProbePrediction = {"makeProbePrediction", (PyCFunction)__pyx_pf_3svd_3SVD_makeProbePrediction, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_makeProbePrediction};
static PyObject *__pyx_pf_3svd_3SVD_makeProbePrediction(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  PyObject *__pyx_v_predicttype = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyObject *__pyx_v_tmp;
  int __pyx_v_numratings;
  int __pyx_v_numfeatures;
  int __pyx_v_uid;
  int __pyx_v_mid;
  int __pyx_v_i;
  int __pyx_v_k;
  float __pyx_v_prediction;
  PyArrayObject *__pyx_v_probeRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_probeRatings;
  Py_ssize_t __pyx_bstride_0_probeRatings = 0;
  Py_ssize_t __pyx_bshape_0_probeRatings = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  int __pyx_2;
  PyObject *__pyx_3 = 0;
  int __pyx_4;
  PyObject *__pyx_5 = 0;
  PyObject *__pyx_6 = 0;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyArrayObject *__pyx_t_3 = NULL;
  int __pyx_t_4;
  int __pyx_t_5;
  int __pyx_t_6;
  int __pyx_t_7;
  int __pyx_t_8;
  int __pyx_t_9;
  int __pyx_t_10;
  int __pyx_t_11;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,&__pyx_kp_predicttype,0};
  __pyx_self = __pyx_self;
  __pyx_v_predicttype = __pyx_kp_28;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[4] = {0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("makeProbePrediction", 0, 3, 4, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("makeProbePrediction", 0, 3, 4, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "makeProbePrediction") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[1]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[2]);
    if (values[3]) {
      __pyx_v_predicttype = values[3];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  4:
      __pyx_v_predicttype = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3:
      __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
      __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
      __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("makeProbePrediction", 0, 3, 4, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.makeProbePrediction");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_tmp = Py_None; Py_INCREF(Py_None);
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_probeRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":303
 * 		"""
 * 
 * 		cdef N.ndarray[f32_t, ndim=2] U = self.U             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=2] M = self.M
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_U); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_U = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_U.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
    __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_U = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":304
 * 
 * 		cdef N.ndarray[f32_t, ndim=2] U = self.U
 * 		cdef N.ndarray[f32_t, ndim=2] M = self.M             # <<<<<<<<<<<<<<
 * 
 * 		if predicttype is 'probe':
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_M); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_M = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_M.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
    __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_M = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":306
 * 		cdef N.ndarray[f32_t, ndim=2] M = self.M
 * 
 * 		if predicttype is 'probe':             # <<<<<<<<<<<<<<
 * 			tmp = self.td.numratings
 * 		elif predicttype is 'quiz':
 */
  __pyx_2 = (__pyx_v_predicttype == __pyx_kp_137);
  if (__pyx_2) {

    /* "/home/alex/workspace/flix/src/svd.pyx":307
 * 
 * 		if predicttype is 'probe':
 * 			tmp = self.td.numratings             # <<<<<<<<<<<<<<
 * 		elif predicttype is 'quiz':
 * 			tmp = userIDsForUsers.size
 */
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(__pyx_v_tmp);
    __pyx_v_tmp = __pyx_3;
    __pyx_3 = 0;
    goto __pyx_L6;
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":308
 * 		if predicttype is 'probe':
 * 			tmp = self.td.numratings
 * 		elif predicttype is 'quiz':             # <<<<<<<<<<<<<<
 * 			tmp = userIDsForUsers.size
 * 		else:
 */
  __pyx_2 = (__pyx_v_predicttype == __pyx_kp_138);
  if (__pyx_2) {

    /* "/home/alex/workspace/flix/src/svd.pyx":309
 * 			tmp = self.td.numratings
 * 		elif predicttype is 'quiz':
 * 			tmp = userIDsForUsers.size             # <<<<<<<<<<<<<<
 * 		else:
 * 			raise ValueError, 'predicctype argument must be either "probe" or "quiz"'
 */
    __pyx_1 = PyObject_GetAttr(((PyObject *)__pyx_v_userIDsForUsers), __pyx_kp_size); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_tmp);
    __pyx_v_tmp = __pyx_1;
    __pyx_1 = 0;
    goto __pyx_L6;
  }
  /*else*/ {

    /* "/home/alex/workspace/flix/src/svd.pyx":311
 * 			tmp = userIDsForUsers.size
 * 		else:
 * 			raise ValueError, 'predicctype argument must be either "probe" or "quiz"'             # <<<<<<<<<<<<<<
 * 		cdef int numratings = tmp
 * 
 */
    __Pyx_Raise(__pyx_builtin_ValueError, __pyx_kp_139, 0);
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  }
  __pyx_L6:;

  /* "/home/alex/workspace/flix/src/svd.pyx":312
 * 		else:
 * 			raise ValueError, 'predicctype argument must be either "probe" or "quiz"'
 * 		cdef int numratings = tmp             # <<<<<<<<<<<<<<
 * 
 * 		cdef int numfeatures = U.shape[1]
 */
  __pyx_4 = __pyx_PyInt_int(__pyx_v_tmp); if (unlikely((__pyx_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_v_numratings = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":314
 * 		cdef int numratings = tmp
 * 
 * 		cdef int numfeatures = U.shape[1]             # <<<<<<<<<<<<<<
 * 		cdef int uid, mid, i, k
 * 		cdef float prediction
 */
  __pyx_v_numfeatures = (__pyx_v_U->dimensions[1]);

  /* "/home/alex/workspace/flix/src/svd.pyx":318
 * 		cdef float prediction
 * 
 * 		cdef N.ndarray[f32_t, ndim=1] probeRatings = N.zeros(numratings, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < numratings:
 */
  __pyx_3 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_3, __pyx_kp_zeros); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  __pyx_3 = PyInt_FromLong(__pyx_v_numratings); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_5, 0, __pyx_3);
  __pyx_3 = 0;
  __pyx_3 = PyDict_New(); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_3, __pyx_kp_dtype, __pyx_kp_140) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = PyEval_CallObjectWithKeywords(__pyx_1, ((PyObject *)__pyx_5), ((PyObject *)__pyx_3)); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
  Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
  if (!(__Pyx_TypeTest(__pyx_6, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_3 = ((PyArrayObject *)__pyx_6);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_3, &__pyx_bstruct_probeRatings, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_probeRatings = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_probeRatings.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 318; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_probeRatings = __pyx_bstruct_probeRatings.strides[0];
    __pyx_bshape_0_probeRatings = __pyx_bstruct_probeRatings.shape[0];
  }
  __pyx_t_3 = 0;
  __pyx_v_probeRatings = ((PyArrayObject *)__pyx_6);
  __pyx_6 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":320
 * 		cdef N.ndarray[f32_t, ndim=1] probeRatings = N.zeros(numratings, dtype='float32')
 * 
 * 		for i from 0 <= i < numratings:             # <<<<<<<<<<<<<<
 * 			uid = userIDsForUsers[i]
 * 			mid = movieIDs[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":321
 * 
 * 		for i from 0 <= i < numratings:
 * 			uid = userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = movieIDs[i]
 * 
 */
    __pyx_t_4 = __pyx_v_i;
    __pyx_t_5 = -1;
    if (__pyx_t_4 < 0) {
      __pyx_t_4 += __pyx_bshape_0_userIDsForUsers;
      if (unlikely(__pyx_t_4 < 0)) __pyx_t_5 = 0;
    } else if (unlikely(__pyx_t_4 >= __pyx_bshape_0_userIDsForUsers)) __pyx_t_5 = 0;
    if (unlikely(__pyx_t_5 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_5);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_uid = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_4, __pyx_bstride_0_userIDsForUsers));

    /* "/home/alex/workspace/flix/src/svd.pyx":322
 * 		for i from 0 <= i < numratings:
 * 			uid = userIDsForUsers[i]
 * 			mid = movieIDs[i]             # <<<<<<<<<<<<<<
 * 
 * 			prediction = 0.0
 */
    __pyx_t_5 = __pyx_v_i;
    __pyx_t_6 = -1;
    if (__pyx_t_5 < 0) {
      __pyx_t_5 += __pyx_bshape_0_movieIDs;
      if (unlikely(__pyx_t_5 < 0)) __pyx_t_6 = 0;
    } else if (unlikely(__pyx_t_5 >= __pyx_bshape_0_movieIDs)) __pyx_t_6 = 0;
    if (unlikely(__pyx_t_6 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_6);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 322; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_mid = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_5, __pyx_bstride_0_movieIDs));

    /* "/home/alex/workspace/flix/src/svd.pyx":324
 * 			mid = movieIDs[i]
 * 
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":325
 * 
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":326
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 
 * 			probeRatings[i] = prediction
 */
      __pyx_t_6 = __pyx_v_uid;
      __pyx_t_7 = __pyx_v_k;
      __pyx_t_8 = -1;
      if (__pyx_t_6 < 0) {
        __pyx_t_6 += __pyx_bshape_0_U;
        if (unlikely(__pyx_t_6 < 0)) __pyx_t_8 = 0;
      } else if (unlikely(__pyx_t_6 >= __pyx_bshape_0_U)) __pyx_t_8 = 0;
      if (__pyx_t_7 < 0) {
        __pyx_t_7 += __pyx_bshape_1_U;
        if (unlikely(__pyx_t_7 < 0)) __pyx_t_8 = 1;
      } else if (unlikely(__pyx_t_7 >= __pyx_bshape_1_U)) __pyx_t_8 = 1;
      if (unlikely(__pyx_t_8 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_8);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_t_8 = __pyx_v_mid;
      __pyx_t_9 = __pyx_v_k;
      __pyx_t_10 = -1;
      if (__pyx_t_8 < 0) {
        __pyx_t_8 += __pyx_bshape_0_M;
        if (unlikely(__pyx_t_8 < 0)) __pyx_t_10 = 0;
      } else if (unlikely(__pyx_t_8 >= __pyx_bshape_0_M)) __pyx_t_10 = 0;
      if (__pyx_t_9 < 0) {
        __pyx_t_9 += __pyx_bshape_1_M;
        if (unlikely(__pyx_t_9 < 0)) __pyx_t_10 = 1;
      } else if (unlikely(__pyx_t_9 >= __pyx_bshape_1_M)) __pyx_t_10 = 1;
      if (unlikely(__pyx_t_10 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_10);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 326; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_6, __pyx_bstride_0_U, __pyx_t_7, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_8, __pyx_bstride_0_M, __pyx_t_9, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":328
 * 				prediction += U[uid,k]*M[mid,k]
 * 
 * 			probeRatings[i] = prediction             # <<<<<<<<<<<<<<
 * 
 * 		# Clip predictions
 */
    __pyx_t_10 = __pyx_v_i;
    __pyx_t_11 = -1;
    if (__pyx_t_10 < 0) {
      __pyx_t_10 += __pyx_bshape_0_probeRatings;
      if (unlikely(__pyx_t_10 < 0)) __pyx_t_11 = 0;
    } else if (unlikely(__pyx_t_10 >= __pyx_bshape_0_probeRatings)) __pyx_t_11 = 0;
    if (unlikely(__pyx_t_11 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_11);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_probeRatings.buf, __pyx_t_10, __pyx_bstride_0_probeRatings) = __pyx_v_prediction;
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":331
 * 
 * 		# Clip predictions
 * 		probeRatings[probeRatings<1.0] = 1.0             # <<<<<<<<<<<<<<
 * 		probeRatings[probeRatings>5.0] = 5.0
 * 		return probeRatings
 */
  __pyx_1 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyFloat_FromDouble(1.0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyObject_RichCompare(((PyObject *)__pyx_v_probeRatings), __pyx_5, Py_LT); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  if (PyObject_SetItem(((PyObject *)__pyx_v_probeRatings), __pyx_3, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 331; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":332
 * 		# Clip predictions
 * 		probeRatings[probeRatings<1.0] = 1.0
 * 		probeRatings[probeRatings>5.0] = 5.0             # <<<<<<<<<<<<<<
 * 		return probeRatings
 * 
 */
  __pyx_6 = PyFloat_FromDouble(5.0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyFloat_FromDouble(5.0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_RichCompare(((PyObject *)__pyx_v_probeRatings), __pyx_5, Py_GT); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  if (PyObject_SetItem(((PyObject *)__pyx_v_probeRatings), __pyx_1, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 332; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_6); __pyx_6 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":333
 * 		probeRatings[probeRatings<1.0] = 1.0
 * 		probeRatings[probeRatings>5.0] = 5.0
 * 		return probeRatings             # <<<<<<<<<<<<<<
 * 
 * 	def checkError(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \
 */
  Py_INCREF(((PyObject *)__pyx_v_probeRatings));
  __pyx_r = ((PyObject *)__pyx_v_probeRatings);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_3);
  Py_XDECREF(__pyx_5);
  Py_XDECREF(__pyx_6);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_probeRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.makeProbePrediction");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_probeRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_U);
  Py_XDECREF(__pyx_v_M);
  Py_DECREF(__pyx_v_tmp);
  Py_XDECREF(__pyx_v_probeRatings);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":335
 * 		return probeRatings
 * 
 * 	def checkError(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 
 */

static PyObject *__pyx_pf_3svd_3SVD_checkError(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_3svd_3SVD_checkError = {"checkError", (PyCFunction)__pyx_pf_3svd_3SVD_checkError, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pf_3svd_3SVD_checkError(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  float __pyx_v_error;
  float __pyx_v_prediction;
  int __pyx_v_uid;
  int __pyx_v_mid;
  int __pyx_v_i;
  int __pyx_v_k;
  int __pyx_v_numratings;
  PyObject *__pyx_v_numfeatures;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  PyObject *__pyx_6 = 0;
  int __pyx_t_1;
  int __pyx_t_2;
  int __pyx_t_3;
  int __pyx_t_4;
  int __pyx_t_5;
  int __pyx_t_6;
  int __pyx_t_7;
  int __pyx_t_8;
  int __pyx_t_9;
  PyObject *__pyx_t_10 = NULL;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[6] = {0,0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  5:
      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[5])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "checkError") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[4]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[5]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("checkError", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.checkError");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_numfeatures = Py_None; Py_INCREF(Py_None);
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 336; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":340
 * 		cdef float error, prediction
 * 		cdef int uid, mid, i, k
 * 		cdef int numratings = self.td.numratings             # <<<<<<<<<<<<<<
 * 		numfeatures = self.numfeatures
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = __pyx_PyInt_int(__pyx_2); if (unlikely((__pyx_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 340; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = __pyx_3;

  /* "/home/alex/workspace/flix/src/svd.pyx":341
 * 		cdef int uid, mid, i, k
 * 		cdef int numratings = self.td.numratings
 * 		numfeatures = self.numfeatures             # <<<<<<<<<<<<<<
 * 
 * 		error = 0.0
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 341; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_numfeatures);
  __pyx_v_numfeatures = __pyx_1;
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":343
 * 		numfeatures = self.numfeatures
 * 
 * 		error = 0.0             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < numratings:
 */
  __pyx_v_error = 0.0;

  /* "/home/alex/workspace/flix/src/svd.pyx":345
 * 		error = 0.0
 * 
 * 		for i from 0 <= i < numratings:             # <<<<<<<<<<<<<<
 * 			uid = userIDsForUsers[i]
 * 			mid = movieIDs[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":346
 * 
 * 		for i from 0 <= i < numratings:
 * 			uid = userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = movieIDs[i]
 * 
 */
    __pyx_t_1 = __pyx_v_i;
    __pyx_t_2 = -1;
    if (__pyx_t_1 < 0) {
      __pyx_t_1 += __pyx_bshape_0_userIDsForUsers;
      if (unlikely(__pyx_t_1 < 0)) __pyx_t_2 = 0;
    } else if (unlikely(__pyx_t_1 >= __pyx_bshape_0_userIDsForUsers)) __pyx_t_2 = 0;
    if (unlikely(__pyx_t_2 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_2);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 346; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_uid = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_1, __pyx_bstride_0_userIDsForUsers));

    /* "/home/alex/workspace/flix/src/svd.pyx":347
 * 		for i from 0 <= i < numratings:
 * 			uid = userIDsForUsers[i]
 * 			mid = movieIDs[i]             # <<<<<<<<<<<<<<
 * 
 * 			prediction = 0.0
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_t_3 = -1;
    if (__pyx_t_2 < 0) {
      __pyx_t_2 += __pyx_bshape_0_movieIDs;
      if (unlikely(__pyx_t_2 < 0)) __pyx_t_3 = 0;
    } else if (unlikely(__pyx_t_2 >= __pyx_bshape_0_movieIDs)) __pyx_t_3 = 0;
    if (unlikely(__pyx_t_3 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_3);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 347; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_mid = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_2, __pyx_bstride_0_movieIDs));

    /* "/home/alex/workspace/flix/src/svd.pyx":349
 * 			mid = movieIDs[i]
 * 
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":350
 * 
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error += (userRatings[i] - prediction)*(userRatings[i] - prediction)
 */
    __pyx_3 = __pyx_PyInt_int(__pyx_v_numfeatures); if (unlikely((__pyx_3 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 350; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_3; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":351
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 			error += (userRatings[i] - prediction)*(userRatings[i] - prediction)
 * 
 */
      __pyx_t_3 = __pyx_v_uid;
      __pyx_t_4 = __pyx_v_k;
      __pyx_t_5 = -1;
      if (__pyx_t_3 < 0) {
        __pyx_t_3 += __pyx_bshape_0_U;
        if (unlikely(__pyx_t_3 < 0)) __pyx_t_5 = 0;
      } else if (unlikely(__pyx_t_3 >= __pyx_bshape_0_U)) __pyx_t_5 = 0;
      if (__pyx_t_4 < 0) {
        __pyx_t_4 += __pyx_bshape_1_U;
        if (unlikely(__pyx_t_4 < 0)) __pyx_t_5 = 1;
      } else if (unlikely(__pyx_t_4 >= __pyx_bshape_1_U)) __pyx_t_5 = 1;
      if (unlikely(__pyx_t_5 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_5);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_t_5 = __pyx_v_mid;
      __pyx_t_6 = __pyx_v_k;
      __pyx_t_7 = -1;
      if (__pyx_t_5 < 0) {
        __pyx_t_5 += __pyx_bshape_0_M;
        if (unlikely(__pyx_t_5 < 0)) __pyx_t_7 = 0;
      } else if (unlikely(__pyx_t_5 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
      if (__pyx_t_6 < 0) {
        __pyx_t_6 += __pyx_bshape_1_M;
        if (unlikely(__pyx_t_6 < 0)) __pyx_t_7 = 1;
      } else if (unlikely(__pyx_t_6 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 351; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_3, __pyx_bstride_0_U, __pyx_t_4, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_5, __pyx_bstride_0_M, __pyx_t_6, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":352
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error += (userRatings[i] - prediction)*(userRatings[i] - prediction)             # <<<<<<<<<<<<<<
 * 
 * 		return N.sqrt(error/N.float(numratings))
 */
    __pyx_t_7 = __pyx_v_i;
    __pyx_t_8 = -1;
    if (__pyx_t_7 < 0) {
      __pyx_t_7 += __pyx_bshape_0_userRatings;
      if (unlikely(__pyx_t_7 < 0)) __pyx_t_8 = 0;
    } else if (unlikely(__pyx_t_7 >= __pyx_bshape_0_userRatings)) __pyx_t_8 = 0;
    if (unlikely(__pyx_t_8 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_8);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_t_8 = __pyx_v_i;
    __pyx_t_9 = -1;
    if (__pyx_t_8 < 0) {
      __pyx_t_8 += __pyx_bshape_0_userRatings;
      if (unlikely(__pyx_t_8 < 0)) __pyx_t_9 = 0;
    } else if (unlikely(__pyx_t_8 >= __pyx_bshape_0_userRatings)) __pyx_t_9 = 0;
    if (unlikely(__pyx_t_9 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_9);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 352; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_error += (((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_7, __pyx_bstride_0_userRatings)) - __pyx_v_prediction) * ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_8, __pyx_bstride_0_userRatings)) - __pyx_v_prediction));
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":354
 * 			error += (userRatings[i] - prediction)*(userRatings[i] - prediction)
 * 
 * 		return N.sqrt(error/N.float(numratings))             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_2 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_sqrt); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_2 = PyFloat_FromDouble(__pyx_v_error); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyObject_GetAttr(__pyx_4, __pyx_kp_float); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_4 = PyInt_FromLong(__pyx_v_numratings); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = PyTuple_New(1); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_6, 0, __pyx_4);
  __pyx_4 = 0;
  __pyx_4 = PyObject_Call(__pyx_5, ((PyObject *)__pyx_6), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  Py_DECREF(((PyObject *)__pyx_6)); __pyx_6 = 0;
  __pyx_t_10 = __Pyx_PyNumber_Divide(__pyx_2, __pyx_4); if (unlikely(!__pyx_t_10)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_5, 0, __pyx_t_10);
  __pyx_t_10 = 0;
  __pyx_6 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 354; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
  __pyx_r = __pyx_6;
  __pyx_6 = 0;
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  Py_XDECREF(__pyx_6);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.checkError");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  Py_DECREF(__pyx_v_numfeatures);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":397
 * 	# ============================================================
 * 
 * 	def snmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_snmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_snmf[] = "\n\t\tThe beginning of an experiment in generalizing Arek paterek's NSVD1.\n\t\tThe rows of the W matrix in NSVD1 each represent movies. \n\t\tSparse Node Matrix Factorization relaxes that definition, and each row is simply a node\n\t\tthat is randomly connected to users, representing some aspect in movie-space.\n\t\tWe'll see how it works.\n\t\t\n\t\tThe main drawback that I can think of right now is that users cannot modify\n\t\ttheir linkage at all to various sparse nodes, even if they do not do a good job\n\t\tdescribing that user.\n\t\tSo, allow some parameter to vary the link strength, in [0,1]\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_snmf = {"snmf", (PyCFunction)__pyx_pf_3svd_3SVD_snmf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_snmf};
static PyObject *__pyx_pf_3svd_3SVD_snmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  PyArrayObject *__pyx_v_W = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_nid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  float __pyx_v_usernorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_numusers;
  unsigned int __pyx_v_numnodes;
  unsigned int __pyx_v_numconnectednodes;
  PyArrayObject *__pyx_v_userIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForUser = 0;
  PyArrayObject *__pyx_v_userFeatureCache = 0;
  PyArrayObject *__pyx_v_nodelist;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  PyObject *__pyx_v_rs;
  Py_buffer __pyx_bstruct_nodelist;
  Py_ssize_t __pyx_bstride_0_nodelist = 0;
  Py_ssize_t __pyx_bshape_0_nodelist = 0;
  Py_buffer __pyx_bstruct_userFeatureCache;
  Py_ssize_t __pyx_bstride_0_userFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_userFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_numRatingsForUser;
  Py_ssize_t __pyx_bstride_0_numRatingsForUser = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForUser = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_W;
  Py_ssize_t __pyx_bstride_0_W = 0;
  Py_ssize_t __pyx_bstride_1_W = 0;
  Py_ssize_t __pyx_bshape_0_W = 0;
  Py_ssize_t __pyx_bshape_1_W = 0;
  Py_buffer __pyx_bstruct_userIndex;
  Py_ssize_t __pyx_bstride_0_userIndex = 0;
  Py_ssize_t __pyx_bstride_1_userIndex = 0;
  Py_ssize_t __pyx_bshape_0_userIndex = 0;
  Py_ssize_t __pyx_bshape_1_userIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  PyArrayObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  PyArrayObject *__pyx_t_10 = NULL;
  PyObject *__pyx_t_11 = NULL;
  PyObject *__pyx_t_12 = NULL;
  unsigned int __pyx_t_13;
  unsigned int __pyx_t_14;
  unsigned int __pyx_t_15;
  unsigned int __pyx_t_16;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  unsigned int __pyx_t_45;
  unsigned int __pyx_t_46;
  unsigned int __pyx_t_47;
  unsigned int __pyx_t_48;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("snmf", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("snmf", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("snmf", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("snmf", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "snmf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("snmf", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.snmf");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_nodelist = ((PyArrayObject *)Py_None); Py_INCREF(Py_None);
  __pyx_v_rs = Py_None; Py_INCREF(Py_None);
  __pyx_bstruct_W.buf = NULL;
  __pyx_bstruct_userIndex.buf = NULL;
  __pyx_bstruct_numRatingsForUser.buf = NULL;
  __pyx_bstruct_userFeatureCache.buf = NULL;
  __pyx_bstruct_nodelist.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 398; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":413
 * 
 * 		# This is the special, extra item matrix that NSVD1 requires.
 * 		cdef N.ndarray[f32_t, ndim=2] W = self.W             # <<<<<<<<<<<<<<
 * 
 * 		cdef unsigned int i, k, uid, mid, nid, inumRatings, istart
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_W, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {
    __pyx_v_W = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_W.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 413; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_W = __pyx_bstruct_W.strides[0]; __pyx_bstride_1_W = __pyx_bstruct_W.strides[1];
    __pyx_bshape_0_W = __pyx_bstruct_W.shape[0]; __pyx_bshape_1_W = __pyx_bstruct_W.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_W = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":416
 * 
 * 		cdef unsigned int i, k, uid, mid, nid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, tmpu, tmpm
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":417
 * 		cdef unsigned int i, k, uid, mid, nid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, tmpu, tmpm
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":420
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, tmpu, tmpm
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 420; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":421
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 		cdef unsigned int numnodes = <unsigned int>self.numnodes
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 421; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":422
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numnodes = <unsigned int>self.numnodes
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_numusers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 422; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numusers = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":423
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 		cdef unsigned int numnodes = <unsigned int>self.numnodes             # <<<<<<<<<<<<<<
 * 
 * 		# WARNING ALERT WA WA WA: HARD-WIRED 0.5 CONNECTION PROBABILITY
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numnodes); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 423; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numnodes = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":426
 * 
 * 		# WARNING ALERT WA WA WA: HARD-WIRED 0.5 CONNECTION PROBABILITY
 * 		cdef unsigned int numconnectednodes = <unsigned int>self.numconnectednodes             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numconnectednodes); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 426; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numconnectednodes = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":428
 * 		cdef unsigned int numconnectednodes = <unsigned int>self.numconnectednodes
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIndex); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_userIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_userIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 428; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userIndex = __pyx_bstruct_userIndex.strides[0]; __pyx_bstride_1_userIndex = __pyx_bstruct_userIndex.strides[1];
    __pyx_bshape_0_userIndex = __pyx_bstruct_userIndex.shape[0]; __pyx_bshape_1_userIndex = __pyx_bstruct_userIndex.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_userIndex = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":429
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 		cdef N.ndarray[i64_t, ndim=1] nodelist
 */
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_int_1);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_1)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_4)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_3 = PyNumber_Subtract(__pyx_2, __pyx_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_t_3);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_numRatingsForUser, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForUser = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForUser.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 429; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.strides[0];
    __pyx_bshape_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_numRatingsForUser = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":430
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i64_t, ndim=1] nodelist
 * 
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_141) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_4), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_5 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_userFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 430; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
  }
  __pyx_t_5 = 0;
  __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":433
 * 		cdef N.ndarray[i64_t, ndim=1] nodelist
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 433; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":434
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 434; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":435
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 435; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":436
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 436; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":439
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 439; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":440
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 440; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":441
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 441; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":442
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 442; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":446
 * 
 * 
 * 		for uid from 0 <= uid < numusers:             # <<<<<<<<<<<<<<
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 */
  for (__pyx_v_uid = 0; __pyx_v_uid < __pyx_v_numusers; __pyx_v_uid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":447
 * 
 * 		for uid from 0 <= uid < numusers:
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 */
    __pyx_7 = ((__pyx_v_uid % 20000) == 0);
    if (__pyx_7) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_4 = PyLong_FromUnsignedLong(__pyx_v_uid); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_3 = PyNumber_Remainder(__pyx_kp_142, __pyx_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_5 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 447; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_5); __pyx_5 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":449
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 
 */
    __pyx_t_6 = __pyx_v_uid;
    __pyx_t_7 = -1;
    if (unlikely(__pyx_t_6 >= __pyx_bshape_0_numRatingsForUser)) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_7 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_7);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 449; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForUser.buf, __pyx_t_6, __pyx_bstride_0_numRatingsForUser)));

    /* "/home/alex/workspace/flix/src/svd.pyx":450
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]             # <<<<<<<<<<<<<<
 * 
 * 			# Make a nodelist, and shuffle it using the userID as a seed.
 */
    __pyx_t_8 = __pyx_v_uid;
    __pyx_t_9 = __pyx_v_u0;
    __pyx_t_7 = -1;
    if (unlikely(__pyx_t_8 >= __pyx_bshape_0_userIndex)) __pyx_t_7 = 0;
    if (unlikely(__pyx_t_9 >= __pyx_bshape_1_userIndex)) __pyx_t_7 = 1;
    if (unlikely(__pyx_t_7 != -1)) {
        __Pyx_RaiseBufferIndexError(__pyx_t_7);
        {__pyx_filename = __pyx_f[0]; __pyx_lineno = 450; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    }
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIndex.buf, __pyx_t_8, __pyx_bstride_0_userIndex, __pyx_t_9, __pyx_bstride_1_userIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":455
 * 			# This way, we get a replicable shuffle for each user, and
 * 			# we don't have to store the giant connection matrix in memory.
 * 			nodelist = N.arange(numnodes)             # <<<<<<<<<<<<<<
 * 			rs = N.random.RandomState(N.int(uid))
 * 			rs.shuffle(nodelist)
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_arange); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numnodes); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    if (!(__Pyx_TypeTest(__pyx_4, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_10 = ((PyArrayObject *)__pyx_4);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_nodelist);
    __pyx_t_7 = __Pyx_GetBuffer_nn___pyx_t_3svd_i64_t((PyObject*)__pyx_t_10, &__pyx_bstruct_nodelist, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0);
    if (unlikely(__pyx_t_7 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_3, &__pyx_t_11, &__pyx_t_12);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i64_t((PyObject*)__pyx_v_nodelist, &__pyx_bstruct_nodelist, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_3); Py_XDECREF(__pyx_t_11); Py_XDECREF(__pyx_t_12);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_3, __pyx_t_11, __pyx_t_12);
        }
    }
    __pyx_bstride_0_nodelist = __pyx_bstruct_nodelist.strides[0];
    __pyx_bshape_0_nodelist = __pyx_bstruct_nodelist.shape[0];
    if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 455; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_10 = 0;
    Py_DECREF(((PyObject *)__pyx_v_nodelist));
    __pyx_v_nodelist = ((PyArrayObject *)__pyx_4);
    __pyx_4 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":456
 * 			# we don't have to store the giant connection matrix in memory.
 * 			nodelist = N.arange(numnodes)
 * 			rs = N.random.RandomState(N.int(uid))             # <<<<<<<<<<<<<<
 * 			rs.shuffle(nodelist)
 * 
 */
    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_random); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_5 = PyObject_GetAttr(__pyx_2, __pyx_kp_RandomState); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyObject_GetAttr(__pyx_4, __pyx_kp_int); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_2 = PyLong_FromUnsignedLong(__pyx_v_uid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
    __pyx_2 = 0;
    __pyx_2 = PyObject_Call(__pyx_1, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
    __pyx_2 = 0;
    __pyx_4 = PyObject_Call(__pyx_5, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 456; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_5); __pyx_5 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    Py_DECREF(__pyx_v_rs);
    __pyx_v_rs = __pyx_4;
    __pyx_4 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":457
 * 			nodelist = N.arange(numnodes)
 * 			rs = N.random.RandomState(N.int(uid))
 * 			rs.shuffle(nodelist)             # <<<<<<<<<<<<<<
 * 
 * 			# construct the user vector from movie vectors
 */
    __pyx_2 = PyObject_GetAttr(__pyx_v_rs, __pyx_kp_shuffle); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(((PyObject *)__pyx_v_nodelist));
    PyTuple_SET_ITEM(__pyx_5, 0, ((PyObject *)__pyx_v_nodelist));
    __pyx_1 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 457; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    Py_DECREF(__pyx_1); __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":460
 * 
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < numconnectednodes:             # <<<<<<<<<<<<<<
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numconnectednodes; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":461
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < numconnectednodes:
 * 				nid = <unsigned int>nodelist[i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[nid,k]
 */
      __pyx_t_13 = __pyx_v_i;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_13 >= __pyx_bshape_0_nodelist)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 461; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_nid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i64_t *, __pyx_bstruct_nodelist.buf, __pyx_t_13, __pyx_bstride_0_nodelist)));

      /* "/home/alex/workspace/flix/src/svd.pyx":462
 * 			for i from 0 <= i < numconnectednodes:
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					userFeatureCache[k] += W[nid,k]
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":463
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[nid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on movie support
 */
        __pyx_t_14 = __pyx_v_nid;
        __pyx_t_15 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_14 >= __pyx_bshape_0_W)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_15 >= __pyx_bshape_1_W)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_t_16 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_16 >= __pyx_bshape_0_userFeatureCache)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 463; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_16, __pyx_bstride_0_userFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_14, __pyx_bstride_0_W, __pyx_t_15, __pyx_bstride_1_W));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":466
 * 
 * 			# normalize based on movie support
 * 			usernorm = 1/N.sqrt(numnodes)             # <<<<<<<<<<<<<<
 * 			userFeatureCache *= usernorm
 * 
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_sqrt); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_5 = PyLong_FromUnsignedLong(__pyx_v_numnodes); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_1, 0, __pyx_5);
    __pyx_5 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
    __pyx_t_12 = __Pyx_PyNumber_Divide(__pyx_int_1, __pyx_4); if (unlikely(!__pyx_t_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_t_12); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 466; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_12); __pyx_t_12 = 0;
    __pyx_v_usernorm = __pyx_6;

    /* "/home/alex/workspace/flix/src/svd.pyx":467
 * 			# normalize based on movie support
 * 			usernorm = 1/N.sqrt(numnodes)
 * 			userFeatureCache *= usernorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_2 = PyFloat_FromDouble(__pyx_v_usernorm); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_userFeatureCache), __pyx_2); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_5 = ((PyArrayObject *)__pyx_5);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __pyx_t_7 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_7 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_12, &__pyx_t_11, &__pyx_t_3);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_userFeatureCache, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_12); Py_XDECREF(__pyx_t_11); Py_XDECREF(__pyx_t_3);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_12, __pyx_t_11, __pyx_t_3);
        }
    }
    __pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
    if (unlikely(__pyx_t_7 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 467; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = 0;
    Py_DECREF(((PyObject *)__pyx_v_userFeatureCache));
    __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_5);
    __pyx_5 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":470
 * 
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				U[uid,k] = userFeatureCache[k]
 * 
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":471
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:
 * 				U[uid,k] = userFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_17 >= __pyx_bshape_0_userFeatureCache)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_t_18 = __pyx_v_uid;
      __pyx_t_19 = __pyx_v_k;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_18 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_19 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 471; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_18, __pyx_bstride_0_U, __pyx_t_19, __pyx_bstride_1_U) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_17, __pyx_bstride_0_userFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":475
 * 
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":476
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_20 >= __pyx_bshape_0_userRatings)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 476; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_20, __pyx_bstride_0_userRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L15;
        goto __pyx_L17;
      }
      __pyx_L17:;

      /* "/home/alex/workspace/flix/src/svd.pyx":477
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_21 = (__pyx_v_istart + __pyx_v_i);
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_21 >= __pyx_bshape_0_movieIDs)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 477; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_21, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":480
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":481
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":482
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = userRatings[istart+i] - prediction
 * 
 */
        __pyx_t_22 = __pyx_v_uid;
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_22 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_23 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_t_24 = __pyx_v_mid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_24 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_25 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 482; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_22, __pyx_bstride_0_U, __pyx_t_23, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_24, __pyx_bstride_0_M, __pyx_t_25, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":483
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_26 = (__pyx_v_istart + __pyx_v_i);
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_26 >= __pyx_bshape_0_userRatings)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 483; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_26, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":486
 * 
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1] + M[mid,u0]             # <<<<<<<<<<<<<<
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 */
      __pyx_t_27 = __pyx_v_uid;
      __pyx_t_28 = __pyx_v_u1;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_27 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_28 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_t_29 = __pyx_v_mid;
      __pyx_t_30 = __pyx_v_u0;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_29 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_30 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 486; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_27, __pyx_bstride_0_U, __pyx_t_28, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_29, __pyx_bstride_0_M, __pyx_t_30, __pyx_bstride_1_M)));

      /* "/home/alex/workspace/flix/src/svd.pyx":487
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1] + M[mid,u0]
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 * 
 */
      __pyx_t_31 = __pyx_v_uid;
      __pyx_t_32 = __pyx_v_u1;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_31 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_32 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 487; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_31, __pyx_bstride_0_U, __pyx_t_32, __pyx_bstride_1_U) += (__pyx_v_lrateUb * (__pyx_v_error - (__pyx_v_dampfactUb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":488
 * 				biasreg = U[uid,u1] + M[mid,u0]
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the meat of the features
 */
      __pyx_t_33 = __pyx_v_mid;
      __pyx_t_34 = __pyx_v_u0;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_33 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_34 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 488; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_33, __pyx_bstride_0_M, __pyx_t_34, __pyx_bstride_1_M) += (__pyx_v_lrateMb * (__pyx_v_error - (__pyx_v_dampfactMb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":491
 * 
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":492
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
        __pyx_t_35 = __pyx_v_uid;
        __pyx_t_36 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_35 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_36 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 492; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_35, __pyx_bstride_0_U, __pyx_t_36, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":493
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
        __pyx_t_37 = __pyx_v_mid;
        __pyx_t_38 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_37 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_38 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 493; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_37, __pyx_bstride_0_M, __pyx_t_38, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":494
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
        __pyx_t_39 = __pyx_v_uid;
        __pyx_t_40 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_39 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_40 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 494; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_39, __pyx_bstride_0_U, __pyx_t_40, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":495
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the node vectors
 */
        __pyx_t_41 = __pyx_v_mid;
        __pyx_t_42 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_41 >= __pyx_bshape_0_M)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_42 >= __pyx_bshape_1_M)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 495; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_41, __pyx_bstride_0_M, __pyx_t_42, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }
      __pyx_L15:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":498
 * 
 * 			# 4. Update the node vectors
 * 			for i from 0 <= i < numconnectednodes:             # <<<<<<<<<<<<<<
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numconnectednodes; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":499
 * 			# 4. Update the node vectors
 * 			for i from 0 <= i < numconnectednodes:
 * 				nid = <unsigned int>nodelist[i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					W[nid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 */
      __pyx_t_43 = __pyx_v_i;
      __pyx_t_7 = -1;
      if (unlikely(__pyx_t_43 >= __pyx_bshape_0_nodelist)) __pyx_t_7 = 0;
      if (unlikely(__pyx_t_7 != -1)) {
          __Pyx_RaiseBufferIndexError(__pyx_t_7);
          {__pyx_filename = __pyx_f[0]; __pyx_lineno = 499; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      }
      __pyx_v_nid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i64_t *, __pyx_bstruct_nodelist.buf, __pyx_t_43, __pyx_bstride_0_nodelist)));

      /* "/home/alex/workspace/flix/src/svd.pyx":500
 * 			for i from 0 <= i < numconnectednodes:
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					W[nid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":501
 * 				nid = <unsigned int>nodelist[i]
 * 				for k from 2 <= k < numfeatures:
 * 					W[nid,k] += (U[uid,k] - userFeatureCache[k])*usernorm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
        __pyx_t_44 = __pyx_v_uid;
        __pyx_t_45 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_44 >= __pyx_bshape_0_U)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_45 >= __pyx_bshape_1_U)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_t_46 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_46 >= __pyx_bshape_0_userFeatureCache)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        __pyx_t_47 = __pyx_v_nid;
        __pyx_t_48 = __pyx_v_k;
        __pyx_t_7 = -1;
        if (unlikely(__pyx_t_47 >= __pyx_bshape_0_W)) __pyx_t_7 = 0;
        if (unlikely(__pyx_t_48 >= __pyx_bshape_1_W)) __pyx_t_7 = 1;
        if (unlikely(__pyx_t_7 != -1)) {
            __Pyx_RaiseBufferIndexError(__pyx_t_7);
            {__pyx_filename = __pyx_f[0]; __pyx_lineno = 501; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        }
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_47, __pyx_bstride_0_W, __pyx_t_48, __pyx_bstride_1_W) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_44, __pyx_bstride_0_U, __pyx_t_45, __pyx_bstride_1_U)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_46, __pyx_bstride_0_userFeatureCache))) * __pyx_v_usernorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":503
 * 					W[nid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 	@cython.boundscheck(False)
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_nodelist);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.snmf");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_nodelist);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_W);
  Py_XDECREF(__pyx_v_userIndex);
  Py_XDECREF(__pyx_v_numRatingsForUser);
  Py_XDECREF(__pyx_v_userFeatureCache);
  Py_DECREF(__pyx_v_nodelist);
  Py_DECREF(__pyx_v_rs);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":506
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd0(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_nsvd0(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_nsvd0[] = "\n\t\tArek Paterek's NSVD1 algorithm, implemented a la Gravity's suggestion, from\n\t\tTakacs et al., \"A Unified Approach of Factor Models and Neighbor Based Methods for Large Recommender Systems\"\n\t\tAlgorithm 1.\n\t\tHOWEVER, for nsvd0, w = q, that is, there is only ONE set of movie features.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_nsvd0 = {"nsvd0", (PyCFunction)__pyx_pf_3svd_3SVD_nsvd0, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_nsvd0};
static PyObject *__pyx_pf_3svd_3SVD_nsvd0(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_usernorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_numusers;
  PyArrayObject *__pyx_v_userIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForUser = 0;
  PyArrayObject *__pyx_v_userFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_userFeatureCache;
  Py_ssize_t __pyx_bstride_0_userFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_userFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_numRatingsForUser;
  Py_ssize_t __pyx_bstride_0_numRatingsForUser = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForUser = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_userIndex;
  Py_ssize_t __pyx_bstride_0_userIndex = 0;
  Py_ssize_t __pyx_bstride_1_userIndex = 0;
  Py_ssize_t __pyx_bshape_0_userIndex = 0;
  Py_ssize_t __pyx_bshape_1_userIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  PyArrayObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  unsigned int __pyx_t_14;
  unsigned int __pyx_t_15;
  unsigned int __pyx_t_16;
  int __pyx_t_17;
  PyObject *__pyx_t_18 = NULL;
  PyObject *__pyx_t_19 = NULL;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  unsigned int __pyx_t_45;
  unsigned int __pyx_t_46;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd0", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd0", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd0", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd0", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "nsvd0") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("nsvd0", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.nsvd0");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_userIndex.buf = NULL;
  __pyx_bstruct_numRatingsForUser.buf = NULL;
  __pyx_bstruct_userFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 507; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":515
 * 		"""
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":516
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":519
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 519; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":520
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 520; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":521
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_numusers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 521; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numusers = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":523
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIndex); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_userIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_userIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 523; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userIndex = __pyx_bstruct_userIndex.strides[0]; __pyx_bstride_1_userIndex = __pyx_bstruct_userIndex.strides[1];
    __pyx_bshape_0_userIndex = __pyx_bstruct_userIndex.shape[0]; __pyx_bshape_1_userIndex = __pyx_bstruct_userIndex.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_userIndex = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":524
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_int_1);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_1)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_4)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_2 = PyNumber_Subtract(__pyx_2, __pyx_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_3 = ((PyArrayObject *)__pyx_t_2);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_3, &__pyx_bstruct_numRatingsForUser, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForUser = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForUser.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 524; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.strides[0];
    __pyx_bshape_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.shape[0];
  }
  __pyx_t_3 = 0;
  __pyx_v_numRatingsForUser = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":525
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_143) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_4), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_userFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 525; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":527
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 527; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":528
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 528; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":529
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 529; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":530
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 530; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 530; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":533
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 533; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":534
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 534; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":535
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 535; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":536
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 536; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":539
 * 
 * 
 * 		for uid from 0 <= uid < numusers:             # <<<<<<<<<<<<<<
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 */
  for (__pyx_v_uid = 0; __pyx_v_uid < __pyx_v_numusers; __pyx_v_uid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":540
 * 
 * 		for uid from 0 <= uid < numusers:
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 */
    __pyx_7 = ((__pyx_v_uid % 20000) == 0);
    if (__pyx_7) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_4 = PyLong_FromUnsignedLong(__pyx_v_uid); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_2 = PyNumber_Remainder(__pyx_kp_144, __pyx_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_2);
      __pyx_t_2 = 0;
      __pyx_5 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 540; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_5); __pyx_5 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":542
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = 1/N.sqrt(inumRatings)
 */
    __pyx_t_5 = __pyx_v_uid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForUser.buf, __pyx_t_5, __pyx_bstride_0_numRatingsForUser)));

    /* "/home/alex/workspace/flix/src/svd.pyx":543
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]             # <<<<<<<<<<<<<<
 * 			usernorm = 1/N.sqrt(inumRatings)
 * 
 */
    __pyx_t_6 = __pyx_v_uid;
    __pyx_t_7 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIndex.buf, __pyx_t_6, __pyx_bstride_0_userIndex, __pyx_t_7, __pyx_bstride_1_userIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":544
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = 1/N.sqrt(inumRatings)             # <<<<<<<<<<<<<<
 * 
 * 			# zero the user vector
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_sqrt); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_inumRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_int_1, __pyx_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 544; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_v_usernorm = __pyx_6;

    /* "/home/alex/workspace/flix/src/svd.pyx":547
 * 
 * 			# zero the user vector
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				userFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":548
 * 			# zero the user vector
 * 			for k from 0 <= k < numfeatures:
 * 				userFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# load the biases
 */
      __pyx_t_8 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_8, __pyx_bstride_0_userFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":551
 * 
 * 			# load the biases
 * 			userFeatureCache[u0] = 1.0             # <<<<<<<<<<<<<<
 * 			userFeatureCache[u1] = U[uid,u1]
 * 
 */
    __pyx_t_9 = __pyx_v_u0;
    *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_9, __pyx_bstride_0_userFeatureCache) = 1.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":552
 * 			# load the biases
 * 			userFeatureCache[u0] = 1.0
 * 			userFeatureCache[u1] = U[uid,u1]             # <<<<<<<<<<<<<<
 * 
 * 			# construct the user vector from movie vectors
 */
    __pyx_t_10 = __pyx_v_uid;
    __pyx_t_11 = __pyx_v_u1;
    __pyx_t_12 = __pyx_v_u1;
    *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_12, __pyx_bstride_0_userFeatureCache) = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_10, __pyx_bstride_0_U, __pyx_t_11, __pyx_bstride_1_U));

    /* "/home/alex/workspace/flix/src/svd.pyx":555
 * 
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":556
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += M[mid,k]
 */
      __pyx_t_13 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_13, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":557
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					userFeatureCache[k] += M[mid,k]
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":558
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += M[mid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on movie support
 */
        __pyx_t_14 = __pyx_v_mid;
        __pyx_t_15 = __pyx_v_k;
        __pyx_t_16 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_16, __pyx_bstride_0_userFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_14, __pyx_bstride_0_M, __pyx_t_15, __pyx_bstride_1_M));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":561
 * 
 * 			# normalize based on movie support
 * 			userFeatureCache *= usernorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_2 = PyFloat_FromDouble(__pyx_v_usernorm); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_userFeatureCache), __pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_4 = ((PyArrayObject *)__pyx_1);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __pyx_t_17 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_17 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_2, &__pyx_t_18, &__pyx_t_19);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_userFeatureCache, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_2); Py_XDECREF(__pyx_t_18); Py_XDECREF(__pyx_t_19);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_2, __pyx_t_18, __pyx_t_19);
        }
    }
    __pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
    if (unlikely(__pyx_t_17 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 561; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_4 = 0;
    Py_DECREF(((PyObject *)__pyx_v_userFeatureCache));
    __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_1);
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":564
 * 
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				U[uid,k] = userFeatureCache[k]
 * 
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":565
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:
 * 				U[uid,k] = userFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_20 = __pyx_v_k;
      __pyx_t_21 = __pyx_v_uid;
      __pyx_t_22 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_21, __pyx_bstride_0_U, __pyx_t_22, __pyx_bstride_1_U) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_20, __pyx_bstride_0_userFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":569
 * 
 * 			# The Engine of NSVD0 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":570
 * 			# The Engine of NSVD0 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_23 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_23, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":573
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":574
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":575
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = userRatings[istart+i] - prediction
 * 
 */
        __pyx_t_24 = __pyx_v_uid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_t_26 = __pyx_v_mid;
        __pyx_t_27 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_24, __pyx_bstride_0_U, __pyx_t_25, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_26, __pyx_bstride_0_M, __pyx_t_27, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":576
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_28 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_28, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":582
 * 				# U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)
 * 				 # M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 * 				U[uid,u1] += lrateUb*error             # <<<<<<<<<<<<<<
 * 				M[mid,u0] += lrateMb*error
 * 
 */
      __pyx_t_29 = __pyx_v_uid;
      __pyx_t_30 = __pyx_v_u1;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_29, __pyx_bstride_0_U, __pyx_t_30, __pyx_bstride_1_U) += (__pyx_v_lrateUb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":583
 * 				 # M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 * 				U[uid,u1] += lrateUb*error
 * 				M[mid,u0] += lrateMb*error             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the meat of the features
 */
      __pyx_t_31 = __pyx_v_mid;
      __pyx_t_32 = __pyx_v_u0;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_31, __pyx_bstride_0_M, __pyx_t_32, __pyx_bstride_1_M) += (__pyx_v_lrateMb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":586
 * 
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":587
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
        __pyx_t_33 = __pyx_v_uid;
        __pyx_t_34 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_33, __pyx_bstride_0_U, __pyx_t_34, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":588
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
        __pyx_t_35 = __pyx_v_mid;
        __pyx_t_36 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_35, __pyx_bstride_0_M, __pyx_t_36, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":589
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
        __pyx_t_37 = __pyx_v_uid;
        __pyx_t_38 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_37, __pyx_bstride_0_U, __pyx_t_38, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":590
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_39 = __pyx_v_mid;
        __pyx_t_40 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_39, __pyx_bstride_0_M, __pyx_t_40, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":593
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":594
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					M[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 */
      __pyx_t_41 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_41, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":595
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					M[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":596
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					M[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
        __pyx_t_42 = __pyx_v_uid;
        __pyx_t_43 = __pyx_v_k;
        __pyx_t_44 = __pyx_v_k;
        __pyx_t_45 = __pyx_v_mid;
        __pyx_t_46 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_45, __pyx_bstride_0_M, __pyx_t_46, __pyx_bstride_1_M) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_42, __pyx_bstride_0_U, __pyx_t_43, __pyx_bstride_1_U)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_44, __pyx_bstride_0_userFeatureCache))) * __pyx_v_usernorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":598
 * 					M[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.nsvd0");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_userIndex);
  Py_XDECREF(__pyx_v_numRatingsForUser);
  Py_XDECREF(__pyx_v_userFeatureCache);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":602
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd1(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_nsvd1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_nsvd1[] = "\n\t\tArek Paterek's NSVD1 algorithm, implemented a la Gravity's suggestion, from\n\t\tTakacs et al., \"A Unified Approach of Factor Models and Neighbor Based Methods for Large Recommender Systems\"\n\t\tAlgorithm 1.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_nsvd1 = {"nsvd1", (PyCFunction)__pyx_pf_3svd_3SVD_nsvd1, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_nsvd1};
static PyObject *__pyx_pf_3svd_3SVD_nsvd1(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  PyArrayObject *__pyx_v_W = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  float __pyx_v_usernorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_numusers;
  PyArrayObject *__pyx_v_userIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForUser = 0;
  PyArrayObject *__pyx_v_userFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_userFeatureCache;
  Py_ssize_t __pyx_bstride_0_userFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_userFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_numRatingsForUser;
  Py_ssize_t __pyx_bstride_0_numRatingsForUser = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForUser = 0;
  Py_buffer __pyx_bstruct_W;
  Py_ssize_t __pyx_bstride_0_W = 0;
  Py_ssize_t __pyx_bstride_1_W = 0;
  Py_ssize_t __pyx_bshape_0_W = 0;
  Py_ssize_t __pyx_bshape_1_W = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_userIndex;
  Py_ssize_t __pyx_bstride_0_userIndex = 0;
  Py_ssize_t __pyx_bstride_1_userIndex = 0;
  Py_ssize_t __pyx_bshape_0_userIndex = 0;
  Py_ssize_t __pyx_bshape_1_userIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  PyArrayObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  PyObject *__pyx_t_16 = NULL;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  unsigned int __pyx_t_45;
  unsigned int __pyx_t_46;
  unsigned int __pyx_t_47;
  unsigned int __pyx_t_48;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd1", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd1", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd1", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd1", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "nsvd1") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("nsvd1", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.nsvd1");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_W.buf = NULL;
  __pyx_bstruct_userIndex.buf = NULL;
  __pyx_bstruct_numRatingsForUser.buf = NULL;
  __pyx_bstruct_userFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 603; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":611
 * 
 * 		# This is the special, extra item matrix that NSVD1 requires.
 * 		cdef N.ndarray[f32_t, ndim=2] W = self.W             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 611; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 611; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_W, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {
    __pyx_v_W = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_W.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 611; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_W = __pyx_bstruct_W.strides[0]; __pyx_bstride_1_W = __pyx_bstruct_W.strides[1];
    __pyx_bshape_0_W = __pyx_bstruct_W.shape[0]; __pyx_bshape_1_W = __pyx_bstruct_W.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_W = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":615
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":616
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":619
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 619; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":620
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 620; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":621
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_numusers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 621; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numusers = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":623
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 623; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIndex); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 623; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 623; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_userIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_userIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 623; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userIndex = __pyx_bstruct_userIndex.strides[0]; __pyx_bstride_1_userIndex = __pyx_bstruct_userIndex.strides[1];
    __pyx_bshape_0_userIndex = __pyx_bstruct_userIndex.shape[0]; __pyx_bshape_1_userIndex = __pyx_bstruct_userIndex.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_userIndex = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":624
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_int_1);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_1)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_4)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_3 = PyNumber_Subtract(__pyx_2, __pyx_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_t_3);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_numRatingsForUser, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForUser = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForUser.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 624; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.strides[0];
    __pyx_bshape_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_numRatingsForUser = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":625
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_145) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_4), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_5 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_userFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 625; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
  }
  __pyx_t_5 = 0;
  __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":627
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 627; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":628
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 628; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":629
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 629; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":630
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 630; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":633
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 633; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":634
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 634; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":635
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 635; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":636
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 636; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":639
 * 
 * 
 * 		for uid from 0 <= uid < numusers:             # <<<<<<<<<<<<<<
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 */
  for (__pyx_v_uid = 0; __pyx_v_uid < __pyx_v_numusers; __pyx_v_uid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":640
 * 
 * 		for uid from 0 <= uid < numusers:
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 */
    __pyx_7 = ((__pyx_v_uid % 20000) == 0);
    if (__pyx_7) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_4 = PyLong_FromUnsignedLong(__pyx_v_uid); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_3 = PyNumber_Remainder(__pyx_kp_146, __pyx_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_5 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 640; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_5); __pyx_5 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":642
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = 1/N.sqrt(inumRatings)
 */
    __pyx_t_6 = __pyx_v_uid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForUser.buf, __pyx_t_6, __pyx_bstride_0_numRatingsForUser)));

    /* "/home/alex/workspace/flix/src/svd.pyx":643
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]             # <<<<<<<<<<<<<<
 * 			usernorm = 1/N.sqrt(inumRatings)
 * 
 */
    __pyx_t_7 = __pyx_v_uid;
    __pyx_t_8 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIndex.buf, __pyx_t_7, __pyx_bstride_0_userIndex, __pyx_t_8, __pyx_bstride_1_userIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":644
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = 1/N.sqrt(inumRatings)             # <<<<<<<<<<<<<<
 * 
 * 			# zero the user vector
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_sqrt); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_inumRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_int_1, __pyx_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 644; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_v_usernorm = __pyx_6;

    /* "/home/alex/workspace/flix/src/svd.pyx":647
 * 
 * 			# zero the user vector
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				userFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":648
 * 			# zero the user vector
 * 			for k from 0 <= k < numfeatures:
 * 				userFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# construct the user vector from movie vectors
 */
      __pyx_t_9 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_9, __pyx_bstride_0_userFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":651
 * 
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":652
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[mid,k]
 */
      __pyx_t_10 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_10, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":653
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					userFeatureCache[k] += W[mid,k]
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":654
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[mid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on movie support
 */
        __pyx_t_11 = __pyx_v_mid;
        __pyx_t_12 = __pyx_v_k;
        __pyx_t_13 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_13, __pyx_bstride_0_userFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_11, __pyx_bstride_0_W, __pyx_t_12, __pyx_bstride_1_W));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":657
 * 
 * 			# normalize based on movie support
 * 			userFeatureCache *= usernorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_2 = PyFloat_FromDouble(__pyx_v_usernorm); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_userFeatureCache), __pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_5 = ((PyArrayObject *)__pyx_1);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __pyx_t_14 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_14 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_3, &__pyx_t_15, &__pyx_t_16);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_userFeatureCache, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_3); Py_XDECREF(__pyx_t_15); Py_XDECREF(__pyx_t_16);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_3, __pyx_t_15, __pyx_t_16);
        }
    }
    __pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
    if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 657; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = 0;
    Py_DECREF(((PyObject *)__pyx_v_userFeatureCache));
    __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_1);
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":660
 * 
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				U[uid,k] = userFeatureCache[k]
 * 
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":661
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:
 * 				U[uid,k] = userFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_18 = __pyx_v_uid;
      __pyx_t_19 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_18, __pyx_bstride_0_U, __pyx_t_19, __pyx_bstride_1_U) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_17, __pyx_bstride_0_userFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":665
 * 
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":666
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_20, __pyx_bstride_0_userRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L17;
        goto __pyx_L19;
      }
      __pyx_L19:;

      /* "/home/alex/workspace/flix/src/svd.pyx":667
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_21 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_21, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":670
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":671
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":672
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = userRatings[istart+i] - prediction
 * 
 */
        __pyx_t_22 = __pyx_v_uid;
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_24 = __pyx_v_mid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_22, __pyx_bstride_0_U, __pyx_t_23, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_24, __pyx_bstride_0_M, __pyx_t_25, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":673
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_26 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_26, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":676
 * 
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1] + M[mid,u0]             # <<<<<<<<<<<<<<
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 */
      __pyx_t_27 = __pyx_v_uid;
      __pyx_t_28 = __pyx_v_u1;
      __pyx_t_29 = __pyx_v_mid;
      __pyx_t_30 = __pyx_v_u0;
      __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_27, __pyx_bstride_0_U, __pyx_t_28, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_29, __pyx_bstride_0_M, __pyx_t_30, __pyx_bstride_1_M)));

      /* "/home/alex/workspace/flix/src/svd.pyx":677
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1] + M[mid,u0]
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)
 * 
 */
      __pyx_t_31 = __pyx_v_uid;
      __pyx_t_32 = __pyx_v_u1;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_31, __pyx_bstride_0_U, __pyx_t_32, __pyx_bstride_1_U) += (__pyx_v_lrateUb * (__pyx_v_error - (__pyx_v_dampfactUb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":678
 * 				biasreg = U[uid,u1] + M[mid,u0]
 * 				U[uid,u1] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0] += lrateMb*(error - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the meat of the features
 */
      __pyx_t_33 = __pyx_v_mid;
      __pyx_t_34 = __pyx_v_u0;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_33, __pyx_bstride_0_M, __pyx_t_34, __pyx_bstride_1_M) += (__pyx_v_lrateMb * (__pyx_v_error - (__pyx_v_dampfactMb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":681
 * 
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":682
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
        __pyx_t_35 = __pyx_v_uid;
        __pyx_t_36 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_35, __pyx_bstride_0_U, __pyx_t_36, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":683
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
        __pyx_t_37 = __pyx_v_mid;
        __pyx_t_38 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_37, __pyx_bstride_0_M, __pyx_t_38, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":684
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
        __pyx_t_39 = __pyx_v_uid;
        __pyx_t_40 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_39, __pyx_bstride_0_U, __pyx_t_40, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":685
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_41 = __pyx_v_mid;
        __pyx_t_42 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_41, __pyx_bstride_0_M, __pyx_t_42, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }
      __pyx_L17:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":688
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":689
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 */
      __pyx_t_43 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_43, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":690
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":691
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
        __pyx_t_44 = __pyx_v_uid;
        __pyx_t_45 = __pyx_v_k;
        __pyx_t_46 = __pyx_v_k;
        __pyx_t_47 = __pyx_v_mid;
        __pyx_t_48 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_47, __pyx_bstride_0_W, __pyx_t_48, __pyx_bstride_1_W) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_44, __pyx_bstride_0_U, __pyx_t_45, __pyx_bstride_1_U)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_46, __pyx_bstride_0_userFeatureCache))) * __pyx_v_usernorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":693
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.nsvd1");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_W);
  Py_XDECREF(__pyx_v_userIndex);
  Py_XDECREF(__pyx_v_numRatingsForUser);
  Py_XDECREF(__pyx_v_userFeatureCache);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":697
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd2(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_nsvd2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_nsvd2[] = "\n\t\tArek Paterek's NSVD1 algorithm, implemented a la Gravity's suggestion, from\n\t\tTakacs et al., \"A Unified Approach of Factor Models and Neighbor Based Methods for Large Recommender Systems\"\n\t\tAlgorithm 1.\n\t\tHOWEVER, NSVD2 is user-oriented. The W matrix is an extra USER matrix, not item.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_nsvd2 = {"nsvd2", (PyCFunction)__pyx_pf_3svd_3SVD_nsvd2, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_nsvd2};
static PyObject *__pyx_pf_3svd_3SVD_nsvd2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_movieRatings = 0;
  PyArrayObject *__pyx_v_userIDs = 0;
  PyArrayObject *__pyx_v_W = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_movienorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_nummovies;
  PyArrayObject *__pyx_v_movieIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForMovie = 0;
  PyArrayObject *__pyx_v_movieFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_numRatingsForMovie;
  Py_ssize_t __pyx_bstride_0_numRatingsForMovie = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForMovie = 0;
  Py_buffer __pyx_bstruct_userIDs;
  Py_ssize_t __pyx_bstride_0_userIDs = 0;
  Py_ssize_t __pyx_bshape_0_userIDs = 0;
  Py_buffer __pyx_bstruct_movieRatings;
  Py_ssize_t __pyx_bstride_0_movieRatings = 0;
  Py_ssize_t __pyx_bshape_0_movieRatings = 0;
  Py_buffer __pyx_bstruct_W;
  Py_ssize_t __pyx_bstride_0_W = 0;
  Py_ssize_t __pyx_bstride_1_W = 0;
  Py_ssize_t __pyx_bshape_0_W = 0;
  Py_ssize_t __pyx_bshape_1_W = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_movieFeatureCache;
  Py_ssize_t __pyx_bstride_0_movieFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_movieFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIndex;
  Py_ssize_t __pyx_bstride_0_movieIndex = 0;
  Py_ssize_t __pyx_bstride_1_movieIndex = 0;
  Py_ssize_t __pyx_bshape_0_movieIndex = 0;
  Py_ssize_t __pyx_bshape_1_movieIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  PyArrayObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  PyObject *__pyx_t_16 = NULL;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_movieRatings,&__pyx_kp_userIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd2", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd2", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd2", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd2", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "nsvd2") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_movieRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_movieRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("nsvd2", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.nsvd2");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_W.buf = NULL;
  __pyx_bstruct_movieIndex.buf = NULL;
  __pyx_bstruct_numRatingsForMovie.buf = NULL;
  __pyx_bstruct_movieFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_movieRatings.buf = NULL;
  __pyx_bstruct_userIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieRatings), __pyx_ptype_5numpy_ndarray, 1, "movieRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDs), __pyx_ptype_5numpy_ndarray, 1, "userIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 698; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_movieRatings, &__pyx_bstruct_movieRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieRatings = __pyx_bstruct_movieRatings.strides[0];
  __pyx_bshape_0_movieRatings = __pyx_bstruct_movieRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDs, &__pyx_bstruct_userIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDs = __pyx_bstruct_userIDs.strides[0];
  __pyx_bshape_0_userIDs = __pyx_bstruct_userIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":707
 * 
 * 		# This is the special, extra user matrix that NSVD2 requires.
 * 		cdef N.ndarray[f32_t, ndim=2] W = self.W             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_W, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {
    __pyx_v_W = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_W.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 707; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_W = __pyx_bstruct_W.strides[0]; __pyx_bstride_1_W = __pyx_bstruct_W.strides[1];
    __pyx_bshape_0_W = __pyx_bstruct_W.shape[0]; __pyx_bshape_1_W = __pyx_bstruct_W.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_W = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":711
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":712
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":715
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 715; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":716
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 716; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":717
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_nummovies); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 717; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_nummovies = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":719
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_movieIndex); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_movieIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_movieIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 719; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieIndex = __pyx_bstruct_movieIndex.strides[0]; __pyx_bstride_1_movieIndex = __pyx_bstruct_movieIndex.strides[1];
    __pyx_bshape_0_movieIndex = __pyx_bstruct_movieIndex.shape[0]; __pyx_bshape_1_movieIndex = __pyx_bstruct_movieIndex.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_movieIndex = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":720
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_int_1);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_1)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_4)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_3 = PyNumber_Subtract(__pyx_2, __pyx_1); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_t_3);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_numRatingsForMovie, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForMovie = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForMovie.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 720; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.strides[0];
    __pyx_bshape_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_numRatingsForMovie = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":721
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_147) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_4), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_5 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_movieFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 721; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
  }
  __pyx_t_5 = 0;
  __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":723
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 723; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":724
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 724; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":725
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 725; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":726
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 726; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 726; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":729
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 729; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":730
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 730; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":731
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 731; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":732
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 732; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":735
 * 
 * 
 * 		for mid from 0 <= mid < nummovies:             # <<<<<<<<<<<<<<
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 */
  for (__pyx_v_mid = 0; __pyx_v_mid < __pyx_v_nummovies; __pyx_v_mid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":736
 * 
 * 		for mid from 0 <= mid < nummovies:
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 */
    __pyx_7 = ((__pyx_v_mid % 2000) == 0);
    if (__pyx_7) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_4 = PyLong_FromUnsignedLong(__pyx_v_mid); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_3 = PyNumber_Remainder(__pyx_kp_148, __pyx_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_5 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 736; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_5); __pyx_5 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":738
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm = 1/N.sqrt(inumRatings)
 */
    __pyx_t_6 = __pyx_v_mid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForMovie.buf, __pyx_t_6, __pyx_bstride_0_numRatingsForMovie)));

    /* "/home/alex/workspace/flix/src/svd.pyx":739
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]             # <<<<<<<<<<<<<<
 * 			movienorm = 1/N.sqrt(inumRatings)
 * 
 */
    __pyx_t_7 = __pyx_v_mid;
    __pyx_t_8 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_movieIndex.buf, __pyx_t_7, __pyx_bstride_0_movieIndex, __pyx_t_8, __pyx_bstride_1_movieIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":740
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm = 1/N.sqrt(inumRatings)             # <<<<<<<<<<<<<<
 * 
 * 			# zero the movie vector
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_sqrt); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_inumRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    __pyx_t_3 = __Pyx_PyNumber_Divide(__pyx_int_1, __pyx_4); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_t_3); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 740; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_v_movienorm = __pyx_6;

    /* "/home/alex/workspace/flix/src/svd.pyx":743
 * 
 * 			# zero the movie vector
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				movieFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":744
 * 			# zero the movie vector
 * 			for k from 0 <= k < numfeatures:
 * 				movieFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# construct the movie vector from movie vectors
 */
      __pyx_t_9 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_9, __pyx_bstride_0_movieFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":747
 * 
 * 			# construct the movie vector from movie vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":748
 * 			# construct the movie vector from movie vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid= <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					movieFeatureCache[k] += W[uid,k]
 */
      __pyx_t_10 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_10, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":749
 * 			for i from 0 <= i < inumRatings:
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					movieFeatureCache[k] += W[uid,k]
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":750
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					movieFeatureCache[k] += W[uid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on user support
 */
        __pyx_t_11 = __pyx_v_uid;
        __pyx_t_12 = __pyx_v_k;
        __pyx_t_13 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_13, __pyx_bstride_0_movieFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_11, __pyx_bstride_0_W, __pyx_t_12, __pyx_bstride_1_W));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":753
 * 
 * 			# normalize based on user support
 * 			movieFeatureCache *= movienorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_2 = PyFloat_FromDouble(__pyx_v_movienorm); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_movieFeatureCache), __pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_5 = ((PyArrayObject *)__pyx_1);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __pyx_t_14 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_14 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_3, &__pyx_t_15, &__pyx_t_16);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_movieFeatureCache, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_3); Py_XDECREF(__pyx_t_15); Py_XDECREF(__pyx_t_16);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_3, __pyx_t_15, __pyx_t_16);
        }
    }
    __pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
    if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 753; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = 0;
    Py_DECREF(((PyObject *)__pyx_v_movieFeatureCache));
    __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_1);
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":756
 * 
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				M[mid,k] = movieFeatureCache[k]
 * 
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":757
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:
 * 				M[mid,k] = movieFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_18 = __pyx_v_mid;
      __pyx_t_19 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_18, __pyx_bstride_0_M, __pyx_t_19, __pyx_bstride_1_M) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_17, __pyx_bstride_0_movieFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":761
 * 
 * 			# The Engine of NSVD2 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":762
 * 			# The Engine of NSVD2 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_20, __pyx_bstride_0_movieRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L17;
        goto __pyx_L19;
      }
      __pyx_L19:;

      /* "/home/alex/workspace/flix/src/svd.pyx":763
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_21 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_21, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":766
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":767
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":768
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = movieRatings[istart+i] - prediction
 * 
 */
        __pyx_t_22 = __pyx_v_uid;
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_24 = __pyx_v_mid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_22, __pyx_bstride_0_U, __pyx_t_23, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_24, __pyx_bstride_0_M, __pyx_t_25, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":769
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_26 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_26, __pyx_bstride_0_movieRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":772
 * 
 * 				# 2. Update the bias features
 * 				U[uid,u1] += lrateUb*error             # <<<<<<<<<<<<<<
 * 				M[mid,u0] += lrateMb*error
 * 
 */
      __pyx_t_27 = __pyx_v_uid;
      __pyx_t_28 = __pyx_v_u1;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_27, __pyx_bstride_0_U, __pyx_t_28, __pyx_bstride_1_U) += (__pyx_v_lrateUb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":773
 * 				# 2. Update the bias features
 * 				U[uid,u1] += lrateUb*error
 * 				M[mid,u0] += lrateMb*error             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the meat of the features
 */
      __pyx_t_29 = __pyx_v_mid;
      __pyx_t_30 = __pyx_v_u0;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_29, __pyx_bstride_0_M, __pyx_t_30, __pyx_bstride_1_M) += (__pyx_v_lrateMb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":776
 * 
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":777
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
        __pyx_t_31 = __pyx_v_uid;
        __pyx_t_32 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_31, __pyx_bstride_0_U, __pyx_t_32, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":778
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
        __pyx_t_33 = __pyx_v_mid;
        __pyx_t_34 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_33, __pyx_bstride_0_M, __pyx_t_34, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":779
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
        __pyx_t_35 = __pyx_v_uid;
        __pyx_t_36 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_35, __pyx_bstride_0_U, __pyx_t_36, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":780
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_37 = __pyx_v_mid;
        __pyx_t_38 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_37, __pyx_bstride_0_M, __pyx_t_38, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }
      __pyx_L17:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":783
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":784
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					W[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 */
      __pyx_t_39 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_39, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":785
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					W[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":786
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					W[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
        __pyx_t_40 = __pyx_v_mid;
        __pyx_t_41 = __pyx_v_k;
        __pyx_t_42 = __pyx_v_k;
        __pyx_t_43 = __pyx_v_uid;
        __pyx_t_44 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_43, __pyx_bstride_0_W, __pyx_t_44, __pyx_bstride_1_W) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_40, __pyx_bstride_0_M, __pyx_t_41, __pyx_bstride_1_M)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_42, __pyx_bstride_0_movieFeatureCache))) * __pyx_v_movienorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":788
 * 					W[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 	@cython.boundscheck(False)
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.nsvd2");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_W);
  Py_XDECREF(__pyx_v_movieIndex);
  Py_XDECREF(__pyx_v_numRatingsForMovie);
  Py_XDECREF(__pyx_v_movieFeatureCache);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":791
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd3(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_nsvd3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_nsvd3[] = "\n\t\tMovie-oriented version of NSVD0\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_nsvd3 = {"nsvd3", (PyCFunction)__pyx_pf_3svd_3SVD_nsvd3, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_nsvd3};
static PyObject *__pyx_pf_3svd_3SVD_nsvd3(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_movieRatings = 0;
  PyArrayObject *__pyx_v_userIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_movienorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_nummovies;
  PyArrayObject *__pyx_v_movieIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForMovie = 0;
  PyArrayObject *__pyx_v_movieFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_numRatingsForMovie;
  Py_ssize_t __pyx_bstride_0_numRatingsForMovie = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForMovie = 0;
  Py_buffer __pyx_bstruct_userIDs;
  Py_ssize_t __pyx_bstride_0_userIDs = 0;
  Py_ssize_t __pyx_bshape_0_userIDs = 0;
  Py_buffer __pyx_bstruct_movieRatings;
  Py_ssize_t __pyx_bstride_0_movieRatings = 0;
  Py_ssize_t __pyx_bshape_0_movieRatings = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_movieFeatureCache;
  Py_ssize_t __pyx_bstride_0_movieFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_movieFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIndex;
  Py_ssize_t __pyx_bstride_0_movieIndex = 0;
  Py_ssize_t __pyx_bstride_1_movieIndex = 0;
  Py_ssize_t __pyx_bshape_0_movieIndex = 0;
  Py_ssize_t __pyx_bshape_1_movieIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyObject *__pyx_t_2 = NULL;
  PyArrayObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  int __pyx_t_13;
  PyObject *__pyx_t_14 = NULL;
  PyObject *__pyx_t_15 = NULL;
  unsigned int __pyx_t_16;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_movieRatings,&__pyx_kp_userIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd3", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd3", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd3", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("nsvd3", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "nsvd3") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_movieRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_movieRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("nsvd3", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.nsvd3");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_movieIndex.buf = NULL;
  __pyx_bstruct_numRatingsForMovie.buf = NULL;
  __pyx_bstruct_movieFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_movieRatings.buf = NULL;
  __pyx_bstruct_userIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieRatings), __pyx_ptype_5numpy_ndarray, 1, "movieRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDs), __pyx_ptype_5numpy_ndarray, 1, "userIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 792; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_movieRatings, &__pyx_bstruct_movieRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieRatings = __pyx_bstruct_movieRatings.strides[0];
  __pyx_bshape_0_movieRatings = __pyx_bstruct_movieRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDs, &__pyx_bstruct_userIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDs = __pyx_bstruct_userIDs.strides[0];
  __pyx_bshape_0_userIDs = __pyx_bstruct_userIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":798
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":799
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":802
 * 		cdef float error, prediction, uf, mf, biasreg, movienorm
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 802; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":803
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 803; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":804
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_nummovies); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 804; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_nummovies = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":806
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_movieIndex); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_movieIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_movieIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 806; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieIndex = __pyx_bstruct_movieIndex.strides[0]; __pyx_bstride_1_movieIndex = __pyx_bstruct_movieIndex.strides[1];
    __pyx_bshape_0_movieIndex = __pyx_bstruct_movieIndex.shape[0]; __pyx_bshape_1_movieIndex = __pyx_bstruct_movieIndex.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_movieIndex = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":807
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_2);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_1, 1, __pyx_int_1);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_1)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_4)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_2 = PyNumber_Subtract(__pyx_2, __pyx_1); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_2, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_3 = ((PyArrayObject *)__pyx_t_2);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_3, &__pyx_bstruct_numRatingsForMovie, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForMovie = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForMovie.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 807; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.strides[0];
    __pyx_bshape_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.shape[0];
  }
  __pyx_t_3 = 0;
  __pyx_v_numRatingsForMovie = ((PyArrayObject *)__pyx_t_2);
  __pyx_t_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":808
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
  __pyx_1 = 0;
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_1, __pyx_kp_dtype, __pyx_kp_149) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_2, ((PyObject *)__pyx_4), ((PyObject *)__pyx_1)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_movieFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 808; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":810
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 810; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":811
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 811; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":812
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 812; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":813
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 813; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":816
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 816; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":817
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 817; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":818
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 818; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 818; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":819
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 819; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":822
 * 
 * 
 * 		for mid from 0 <= mid < nummovies:             # <<<<<<<<<<<<<<
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 */
  for (__pyx_v_mid = 0; __pyx_v_mid < __pyx_v_nummovies; __pyx_v_mid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":823
 * 
 * 		for mid from 0 <= mid < nummovies:
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 */
    __pyx_7 = ((__pyx_v_mid % 2000) == 0);
    if (__pyx_7) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_4 = PyLong_FromUnsignedLong(__pyx_v_mid); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_2 = PyNumber_Remainder(__pyx_kp_150, __pyx_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_2);
      __pyx_t_2 = 0;
      __pyx_5 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 823; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_5); __pyx_5 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":825
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm = 1/N.sqrt(inumRatings)
 */
    __pyx_t_5 = __pyx_v_mid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForMovie.buf, __pyx_t_5, __pyx_bstride_0_numRatingsForMovie)));

    /* "/home/alex/workspace/flix/src/svd.pyx":826
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]             # <<<<<<<<<<<<<<
 * 			movienorm = 1/N.sqrt(inumRatings)
 * 
 */
    __pyx_t_6 = __pyx_v_mid;
    __pyx_t_7 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_movieIndex.buf, __pyx_t_6, __pyx_bstride_0_movieIndex, __pyx_t_7, __pyx_bstride_1_movieIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":827
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm = 1/N.sqrt(inumRatings)             # <<<<<<<<<<<<<<
 * 
 * 			# zero the movie vector
 */
    __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_4, __pyx_kp_sqrt); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_inumRatings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_5, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_4 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
    __pyx_t_2 = __Pyx_PyNumber_Divide(__pyx_int_1, __pyx_4); if (unlikely(!__pyx_t_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_t_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 827; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_v_movienorm = __pyx_6;

    /* "/home/alex/workspace/flix/src/svd.pyx":830
 * 
 * 			# zero the movie vector
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				movieFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":831
 * 			# zero the movie vector
 * 			for k from 0 <= k < numfeatures:
 * 				movieFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# construct the movie vector from movie vectors
 */
      __pyx_t_8 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_8, __pyx_bstride_0_movieFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":834
 * 
 * 			# construct the movie vector from movie vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":835
 * 			# construct the movie vector from movie vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid= <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					movieFeatureCache[k] += U[uid,k]
 */
      __pyx_t_9 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_9, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":836
 * 			for i from 0 <= i < inumRatings:
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					movieFeatureCache[k] += U[uid,k]
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":837
 * 				uid= <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					movieFeatureCache[k] += U[uid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on user support
 */
        __pyx_t_10 = __pyx_v_uid;
        __pyx_t_11 = __pyx_v_k;
        __pyx_t_12 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_12, __pyx_bstride_0_movieFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_10, __pyx_bstride_0_U, __pyx_t_11, __pyx_bstride_1_U));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":840
 * 
 * 			# normalize based on user support
 * 			movieFeatureCache *= movienorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_2 = PyFloat_FromDouble(__pyx_v_movienorm); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_1 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_movieFeatureCache), __pyx_2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_t_4 = ((PyArrayObject *)__pyx_1);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __pyx_t_13 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_13 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_2, &__pyx_t_14, &__pyx_t_15);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_movieFeatureCache, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_2); Py_XDECREF(__pyx_t_14); Py_XDECREF(__pyx_t_15);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_2, __pyx_t_14, __pyx_t_15);
        }
    }
    __pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
    if (unlikely(__pyx_t_13 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 840; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_4 = 0;
    Py_DECREF(((PyObject *)__pyx_v_movieFeatureCache));
    __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_1);
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":843
 * 
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				M[mid,k] = movieFeatureCache[k]
 * 
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":844
 * 			# put the user vector into the user matrix
 * 			for k from 2 <= k < numfeatures:
 * 				M[mid,k] = movieFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_16 = __pyx_v_k;
      __pyx_t_17 = __pyx_v_mid;
      __pyx_t_18 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_17, __pyx_bstride_0_M, __pyx_t_18, __pyx_bstride_1_M) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_16, __pyx_bstride_0_movieFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":848
 * 
 * 			# The Engine of NSVD2 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":849
 * 			# The Engine of NSVD2 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 
 */
      __pyx_t_19 = (__pyx_v_istart + __pyx_v_i);
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_19, __pyx_bstride_0_movieRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L17;
        goto __pyx_L19;
      }
      __pyx_L19:;

      /* "/home/alex/workspace/flix/src/svd.pyx":850
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_20, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":853
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":854
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":855
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = movieRatings[istart+i] - prediction
 * 
 */
        __pyx_t_21 = __pyx_v_uid;
        __pyx_t_22 = __pyx_v_k;
        __pyx_t_23 = __pyx_v_mid;
        __pyx_t_24 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_21, __pyx_bstride_0_U, __pyx_t_22, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_23, __pyx_bstride_0_M, __pyx_t_24, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":856
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_25 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_25, __pyx_bstride_0_movieRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":859
 * 
 * 				# 2. Update the bias features
 * 				U[uid,u1] += lrateUb*error             # <<<<<<<<<<<<<<
 * 				M[mid,u0] += lrateMb*error
 * 
 */
      __pyx_t_26 = __pyx_v_uid;
      __pyx_t_27 = __pyx_v_u1;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_26, __pyx_bstride_0_U, __pyx_t_27, __pyx_bstride_1_U) += (__pyx_v_lrateUb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":860
 * 				# 2. Update the bias features
 * 				U[uid,u1] += lrateUb*error
 * 				M[mid,u0] += lrateMb*error             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the meat of the features
 */
      __pyx_t_28 = __pyx_v_mid;
      __pyx_t_29 = __pyx_v_u0;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_28, __pyx_bstride_0_M, __pyx_t_29, __pyx_bstride_1_M) += (__pyx_v_lrateMb * __pyx_v_error);

      /* "/home/alex/workspace/flix/src/svd.pyx":863
 * 
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":864
 * 				# 3. Update the meat of the features
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
        __pyx_t_30 = __pyx_v_uid;
        __pyx_t_31 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_30, __pyx_bstride_0_U, __pyx_t_31, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":865
 * 				for k from 2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
        __pyx_t_32 = __pyx_v_mid;
        __pyx_t_33 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_32, __pyx_bstride_0_M, __pyx_t_33, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":866
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
        __pyx_t_34 = __pyx_v_uid;
        __pyx_t_35 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_34, __pyx_bstride_0_U, __pyx_t_35, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":867
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_36 = __pyx_v_mid;
        __pyx_t_37 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_36, __pyx_bstride_0_M, __pyx_t_37, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }
      __pyx_L17:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":870
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":871
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2 <= k < numfeatures:
 * 					U[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 */
      __pyx_t_38 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_38, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":872
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					U[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 * 
 */
      for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":873
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2 <= k < numfeatures:
 * 					U[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
        __pyx_t_39 = __pyx_v_mid;
        __pyx_t_40 = __pyx_v_k;
        __pyx_t_41 = __pyx_v_k;
        __pyx_t_42 = __pyx_v_uid;
        __pyx_t_43 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_42, __pyx_bstride_0_U, __pyx_t_43, __pyx_bstride_1_U) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_39, __pyx_bstride_0_M, __pyx_t_40, __pyx_bstride_1_M)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_41, __pyx_bstride_0_movieFeatureCache))) * __pyx_v_movienorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":875
 * 					U[uid,k] += (M[mid,k] - movieFeatureCache[k])*movienorm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.nsvd3");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_movieIndex);
  Py_XDECREF(__pyx_v_numRatingsForMovie);
  Py_XDECREF(__pyx_v_movieFeatureCache);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":880
 * 
 * 	@cython.boundscheck(False)
 * 	def hybrid(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_hybrid(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_hybrid[] = "\n\t\tHybrid NMF + BRISMF, a la Gravity in \n\t\tTakacs et al., \"A Unified Approach of Factor Models and Neighbor Based Methods for Large Recommender Systems\"\n\t\tself.numfeatures - number of total features\n\t\tself.numfeaturesmf - number of features for just the MF, the rest belong to NSVD1\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_hybrid = {"hybrid", (PyCFunction)__pyx_pf_3svd_3SVD_hybrid, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_hybrid};
static PyObject *__pyx_pf_3svd_3SVD_hybrid(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  PyArrayObject *__pyx_v_W = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  float __pyx_v_usernorm;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_numfeaturesmf;
  unsigned int __pyx_v_numusers;
  PyArrayObject *__pyx_v_userIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForUser = 0;
  PyArrayObject *__pyx_v_userFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_beta;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  float __pyx_v_lrateUn;
  float __pyx_v_lrateMn;
  float __pyx_v_dampfactUn;
  float __pyx_v_dampfactMn;
  Py_buffer __pyx_bstruct_userFeatureCache;
  Py_ssize_t __pyx_bstride_0_userFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_userFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_numRatingsForUser;
  Py_ssize_t __pyx_bstride_0_numRatingsForUser = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForUser = 0;
  Py_buffer __pyx_bstruct_userIndex;
  Py_ssize_t __pyx_bstride_0_userIndex = 0;
  Py_ssize_t __pyx_bstride_1_userIndex = 0;
  Py_ssize_t __pyx_bshape_0_userIndex = 0;
  Py_ssize_t __pyx_bshape_1_userIndex = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_W;
  Py_ssize_t __pyx_bstride_0_W = 0;
  Py_ssize_t __pyx_bstride_1_W = 0;
  Py_ssize_t __pyx_bshape_0_W = 0;
  Py_ssize_t __pyx_bshape_1_W = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  PyArrayObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  PyObject *__pyx_t_16 = NULL;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  unsigned int __pyx_t_45;
  unsigned int __pyx_t_46;
  unsigned int __pyx_t_47;
  unsigned int __pyx_t_48;
  unsigned int __pyx_t_49;
  unsigned int __pyx_t_50;
  unsigned int __pyx_t_51;
  unsigned int __pyx_t_52;
  unsigned int __pyx_t_53;
  unsigned int __pyx_t_54;
  unsigned int __pyx_t_55;
  unsigned int __pyx_t_56;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "hybrid") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("hybrid", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.hybrid");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_W.buf = NULL;
  __pyx_bstruct_userIndex.buf = NULL;
  __pyx_bstruct_numRatingsForUser.buf = NULL;
  __pyx_bstruct_userFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 881; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":889
 * 		"""
 * 				# This is the special, extra item matrix that NSVD1 requires.
 * 		cdef N.ndarray[f32_t, ndim=2] W = self.W             # <<<<<<<<<<<<<<
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_W, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {
    __pyx_v_W = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_W.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 889; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_W = __pyx_bstruct_W.strides[0]; __pyx_bstride_1_W = __pyx_bstruct_W.strides[1];
    __pyx_bshape_0_W = __pyx_bstruct_W.shape[0]; __pyx_bshape_1_W = __pyx_bstruct_W.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_W = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":892
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":893
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":896
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 896; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":897
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 897; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":898
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 898; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numfeaturesmf = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":899
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numusers); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 899; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numusers = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":901
 * 		cdef unsigned int numusers = <unsigned int> self.fd.numusers
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_userIndex); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_2);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_userIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_userIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 901; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userIndex = __pyx_bstruct_userIndex.strides[0]; __pyx_bstride_1_userIndex = __pyx_bstruct_userIndex.strides[1];
    __pyx_bshape_0_userIndex = __pyx_bstruct_userIndex.shape[0]; __pyx_bshape_1_userIndex = __pyx_bstruct_userIndex.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_userIndex = ((PyArrayObject *)__pyx_2);
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":902
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_int_1);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_2)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_userIndex), ((PyObject *)__pyx_4)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_3 = PyNumber_Subtract(__pyx_1, __pyx_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_t_3);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_numRatingsForUser, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForUser = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForUser.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 902; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.strides[0];
    __pyx_bshape_0_numRatingsForUser = __pyx_bstruct_numRatingsForUser.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_numRatingsForUser = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":903
 * 		cdef N.ndarray[i32_t, ndim=2] userIndex = self.fd.userIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForUser = userIndex[:,1] - userIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_2 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
  __pyx_2 = 0;
  __pyx_2 = PyDict_New(); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_2, __pyx_kp_dtype, __pyx_kp_151) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, ((PyObject *)__pyx_4), ((PyObject *)__pyx_2)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_5 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_userFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_userFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 903; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
  }
  __pyx_t_5 = 0;
  __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":905
 * 		cdef N.ndarray[f32_t, ndim=1] userFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 905; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":906
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 906; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":907
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 		cdef float beta = self.beta
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 907; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":908
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 		cdef float beta = self.beta
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 908; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":909
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 * 		cdef float beta = self.beta             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_beta); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 909; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_beta = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":912
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 912; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":913
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 913; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":914
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 914; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":915
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 		# NSVD1 specific parameters
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 915; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":918
 * 
 * 		# NSVD1 specific parameters
 * 		cdef float lrateUn = self.lrateUn             # <<<<<<<<<<<<<<
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUn); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 918; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateUn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":919
 * 		# NSVD1 specific parameters
 * 		cdef float lrateUn = self.lrateUn
 * 		cdef float lrateMn = self.lrateMn             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUn = self.dampfactUn
 * 		cdef float dampfactMn = self.dampfactMn
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMn); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 919; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateMn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":920
 * 		cdef float lrateUn = self.lrateUn
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMn = self.dampfactMn
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUn); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 920; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactUn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":921
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn
 * 		cdef float dampfactMn = self.dampfactMn             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMn); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 921; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":924
 * 
 * 
 * 		for uid from 0 <= uid < numusers:             # <<<<<<<<<<<<<<
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 */
  for (__pyx_v_uid = 0; __pyx_v_uid < __pyx_v_numusers; __pyx_v_uid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":925
 * 
 * 		for uid from 0 <= uid < numusers:
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 */
    __pyx_7 = ((__pyx_v_uid % 20000) == 0);
    if (__pyx_7) {
      __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyLong_FromUnsignedLong(__pyx_v_uid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_3 = PyNumber_Remainder(__pyx_kp_152, __pyx_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_5, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_1 = PyObject_Call(__pyx_4, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 925; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":927
 * 			if uid % 20000 == 0: self.updateLog('\tUpdating user %d' % uid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = inumRatings**-0.5
 */
    __pyx_t_6 = __pyx_v_uid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForUser.buf, __pyx_t_6, __pyx_bstride_0_numRatingsForUser)));

    /* "/home/alex/workspace/flix/src/svd.pyx":928
 * 
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]             # <<<<<<<<<<<<<<
 * 			usernorm = inumRatings**-0.5
 * 
 */
    __pyx_t_7 = __pyx_v_uid;
    __pyx_t_8 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIndex.buf, __pyx_t_7, __pyx_bstride_0_userIndex, __pyx_t_8, __pyx_bstride_1_userIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":929
 * 			inumRatings = <unsigned int>numRatingsForUser[uid]
 * 			istart = <unsigned int>userIndex[uid,u0]
 * 			usernorm = inumRatings**-0.5             # <<<<<<<<<<<<<<
 * 
 * 			# zero the user vector
 */
    __pyx_v_usernorm = pow(__pyx_v_inumRatings, (-0.5));

    /* "/home/alex/workspace/flix/src/svd.pyx":932
 * 
 * 			# zero the user vector
 * 			for k from numfeaturesmf <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				userFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = __pyx_v_numfeaturesmf; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":933
 * 			# zero the user vector
 * 			for k from numfeaturesmf <= k < numfeatures:
 * 				userFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# construct the user vector from movie vectors
 */
      __pyx_t_9 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_9, __pyx_bstride_0_userFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":936
 * 
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":937
 * 			# construct the user vector from movie vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[mid,k]
 */
      __pyx_t_10 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_10, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":938
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					userFeatureCache[k] += W[mid,k]
 * 
 */
      for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":939
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					userFeatureCache[k] += W[mid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on movie support, multiply in (1-beta)
 */
        __pyx_t_11 = __pyx_v_mid;
        __pyx_t_12 = __pyx_v_k;
        __pyx_t_13 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_13, __pyx_bstride_0_userFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_11, __pyx_bstride_0_W, __pyx_t_12, __pyx_bstride_1_W));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":942
 * 
 * 			# normalize based on movie support, multiply in (1-beta)
 * 			userFeatureCache *= usernorm             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_4 = PyFloat_FromDouble(__pyx_v_usernorm); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_userFeatureCache), __pyx_4); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_t_5 = ((PyArrayObject *)__pyx_2);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __pyx_t_14 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_14 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_3, &__pyx_t_15, &__pyx_t_16);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_userFeatureCache, &__pyx_bstruct_userFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_3); Py_XDECREF(__pyx_t_15); Py_XDECREF(__pyx_t_16);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_3, __pyx_t_15, __pyx_t_16);
        }
    }
    __pyx_bstride_0_userFeatureCache = __pyx_bstruct_userFeatureCache.strides[0];
    __pyx_bshape_0_userFeatureCache = __pyx_bstruct_userFeatureCache.shape[0];
    if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 942; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = 0;
    Py_DECREF(((PyObject *)__pyx_v_userFeatureCache));
    __pyx_v_userFeatureCache = ((PyArrayObject *)__pyx_2);
    __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":945
 * 
 * 			# put the user vector into the user matrix
 * 			for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				U[uid,k] = userFeatureCache[k]
 * 
 */
    for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":946
 * 			# put the user vector into the user matrix
 * 			for k from numfeaturesmf+2 <= k < numfeatures:
 * 				U[uid,k] = userFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 			# The Engine of NSVD1 begins here----
 */
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_18 = __pyx_v_uid;
      __pyx_t_19 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_18, __pyx_bstride_0_U, __pyx_t_19, __pyx_bstride_1_U) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_17, __pyx_bstride_0_userFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":949
 * 
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":950
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_20, __pyx_bstride_0_userRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L17;
        goto __pyx_L19;
      }
      __pyx_L19:;

      /* "/home/alex/workspace/flix/src/svd.pyx":951
 * 			for i from 0 <= i < inumRatings:
 * 				if userRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_21 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_21, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":954
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":955
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":956
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = userRatings[istart+i] - prediction
 * 
 */
        __pyx_t_22 = __pyx_v_uid;
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_24 = __pyx_v_mid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_22, __pyx_bstride_0_U, __pyx_t_23, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_24, __pyx_bstride_0_M, __pyx_t_25, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":957
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = userRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_26 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_26, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":960
 * 
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]             # <<<<<<<<<<<<<<
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error*beta - dampfactUb*biasreg)
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error*beta - dampfactMb*biasreg)
 */
      __pyx_t_27 = __pyx_v_uid;
      __pyx_t_28 = (__pyx_v_u1 + __pyx_v_numfeaturesmf);
      __pyx_t_29 = __pyx_v_mid;
      __pyx_t_30 = (__pyx_v_u0 + __pyx_v_numfeaturesmf);
      __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_27, __pyx_bstride_0_U, __pyx_t_28, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_29, __pyx_bstride_0_M, __pyx_t_30, __pyx_bstride_1_M)));

      /* "/home/alex/workspace/flix/src/svd.pyx":961
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error*beta - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error*beta - dampfactMb*biasreg)
 * 
 */
      __pyx_t_31 = __pyx_v_uid;
      __pyx_t_32 = (__pyx_v_u1 + __pyx_v_numfeaturesmf);
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_31, __pyx_bstride_0_U, __pyx_t_32, __pyx_bstride_1_U) += (__pyx_v_lrateUb * ((__pyx_v_error * __pyx_v_beta) - (__pyx_v_dampfactUb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":962
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error*beta - dampfactUb*biasreg)
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error*beta - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 
 * 				# 3. Update the bulk of the features
 */
      __pyx_t_33 = __pyx_v_mid;
      __pyx_t_34 = (__pyx_v_u0 + __pyx_v_numfeaturesmf);
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_33, __pyx_bstride_0_M, __pyx_t_34, __pyx_bstride_1_M) += (__pyx_v_lrateMb * ((__pyx_v_error * __pyx_v_beta) - (__pyx_v_dampfactMb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":966
 * 				# 3. Update the bulk of the features
 * 				# 	for the MF
 * 				for k from 0 <= k < numfeaturesmf:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeaturesmf; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":967
 * 				# 	for the MF
 * 				for k from 0 <= k < numfeaturesmf:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*beta*mf - dampfactU*uf)
 */
        __pyx_t_35 = __pyx_v_uid;
        __pyx_t_36 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_35, __pyx_bstride_0_U, __pyx_t_36, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":968
 * 				for k from 0 <= k < numfeaturesmf:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(error*beta*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*beta*uf - dampfactM*mf)
 */
        __pyx_t_37 = __pyx_v_mid;
        __pyx_t_38 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_37, __pyx_bstride_0_M, __pyx_t_38, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":969
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*beta*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(error*beta*uf - dampfactM*mf)
 * 
 */
        __pyx_t_39 = __pyx_v_uid;
        __pyx_t_40 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_39, __pyx_bstride_0_U, __pyx_t_40, __pyx_bstride_1_U) += (__pyx_v_lrateU * (((__pyx_v_error * __pyx_v_beta) * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":970
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(error*beta*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(error*beta*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 				# 	for NSVD1
 */
        __pyx_t_41 = __pyx_v_mid;
        __pyx_t_42 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_41, __pyx_bstride_0_M, __pyx_t_42, __pyx_bstride_1_M) += (__pyx_v_lrateM * (((__pyx_v_error * __pyx_v_beta) * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":973
 * 
 * 				# 	for NSVD1
 * 				for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":974
 * 				# 	for NSVD1
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 */
        __pyx_t_43 = __pyx_v_uid;
        __pyx_t_44 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_43, __pyx_bstride_0_U, __pyx_t_44, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":975
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)
 */
        __pyx_t_45 = __pyx_v_mid;
        __pyx_t_46 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_45, __pyx_bstride_0_M, __pyx_t_46, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":976
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)
 * 
 */
        __pyx_t_47 = __pyx_v_uid;
        __pyx_t_48 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_47, __pyx_bstride_0_U, __pyx_t_48, __pyx_bstride_1_U) += (__pyx_v_lrateUn * (((__pyx_v_error * (1 - __pyx_v_beta)) * __pyx_v_mf) - (__pyx_v_dampfactUn * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":977
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_49 = __pyx_v_mid;
        __pyx_t_50 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_49, __pyx_bstride_0_M, __pyx_t_50, __pyx_bstride_1_M) += (__pyx_v_lrateMn * (((__pyx_v_error * (1 - __pyx_v_beta)) * __pyx_v_uf) - (__pyx_v_dampfactMn * __pyx_v_mf)));
      }
      __pyx_L17:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":980
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":981
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 */
      __pyx_t_51 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_51, __pyx_bstride_0_movieIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":982
 * 			for i from 0 <= i < inumRatings:
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm
 * 
 */
      for (__pyx_v_k = (2 + __pyx_v_numfeaturesmf); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":983
 * 				mid = <unsigned int>movieIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 * 					W[mid,k] += (U[uid,k] - userFeatureCache[k])*usernorm             # <<<<<<<<<<<<<<
 * 
 * 
 */
        __pyx_t_52 = __pyx_v_uid;
        __pyx_t_53 = __pyx_v_k;
        __pyx_t_54 = __pyx_v_k;
        __pyx_t_55 = __pyx_v_mid;
        __pyx_t_56 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_55, __pyx_bstride_0_W, __pyx_t_56, __pyx_bstride_1_W) += (((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_52, __pyx_bstride_0_U, __pyx_t_53, __pyx_bstride_1_U)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_userFeatureCache.buf, __pyx_t_54, __pyx_bstride_0_userFeatureCache))) * __pyx_v_usernorm);
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":986
 * 
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 	@cython.boundscheck(False)
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.hybrid");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForUser);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIndex);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_W);
  Py_XDECREF(__pyx_v_userIndex);
  Py_XDECREF(__pyx_v_numRatingsForUser);
  Py_XDECREF(__pyx_v_userFeatureCache);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":989
 * 
 * 	@cython.boundscheck(False)
 * 	def hybrid2(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_hybrid2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_hybrid2[] = "\n\t\tHybrid NMF + BRISMF, a la Gravity in \n\t\tTakacs et al., \"A Unified Approach of Factor Models and Neighbor Based Methods for Large Recommender Systems\"\n\t\tself.numfeatures - number of total features\n\t\tself.numfeaturesmf - number of features for just the MF, the rest belong to NSVD1\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_hybrid2 = {"hybrid2", (PyCFunction)__pyx_pf_3svd_3SVD_hybrid2, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_hybrid2};
static PyObject *__pyx_pf_3svd_3SVD_hybrid2(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_movieRatings = 0;
  PyArrayObject *__pyx_v_userIDs = 0;
  PyArrayObject *__pyx_v_W = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  unsigned int __pyx_v_inumRatings;
  unsigned int __pyx_v_istart;
  unsigned int __pyx_v_u0;
  unsigned int __pyx_v_u1;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  unsigned int __pyx_v_numfeaturesmf;
  unsigned int __pyx_v_nummovies;
  PyArrayObject *__pyx_v_movieIndex = 0;
  PyArrayObject *__pyx_v_numRatingsForMovie = 0;
  PyArrayObject *__pyx_v_movieFeatureCache = 0;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_beta;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  float __pyx_v_lrateUn;
  float __pyx_v_lrateMn;
  float __pyx_v_dampfactUn;
  float __pyx_v_dampfactMn;
  PyObject *__pyx_v_movienorm;
  Py_buffer __pyx_bstruct_numRatingsForMovie;
  Py_ssize_t __pyx_bstride_0_numRatingsForMovie = 0;
  Py_ssize_t __pyx_bshape_0_numRatingsForMovie = 0;
  Py_buffer __pyx_bstruct_userIDs;
  Py_ssize_t __pyx_bstride_0_userIDs = 0;
  Py_ssize_t __pyx_bshape_0_userIDs = 0;
  Py_buffer __pyx_bstruct_movieRatings;
  Py_ssize_t __pyx_bstride_0_movieRatings = 0;
  Py_ssize_t __pyx_bshape_0_movieRatings = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  Py_buffer __pyx_bstruct_W;
  Py_ssize_t __pyx_bstride_0_W = 0;
  Py_ssize_t __pyx_bstride_1_W = 0;
  Py_ssize_t __pyx_bshape_0_W = 0;
  Py_ssize_t __pyx_bshape_1_W = 0;
  Py_buffer __pyx_bstruct_movieFeatureCache;
  Py_ssize_t __pyx_bstride_0_movieFeatureCache = 0;
  Py_ssize_t __pyx_bshape_0_movieFeatureCache = 0;
  Py_buffer __pyx_bstruct_movieIndex;
  Py_ssize_t __pyx_bstride_0_movieIndex = 0;
  Py_ssize_t __pyx_bstride_1_movieIndex = 0;
  Py_ssize_t __pyx_bshape_0_movieIndex = 0;
  Py_ssize_t __pyx_bshape_1_movieIndex = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  float __pyx_6;
  int __pyx_7;
  __pyx_t_3svd_f32_t __pyx_8;
  PyArrayObject *__pyx_t_1 = NULL;
  PyArrayObject *__pyx_t_2 = NULL;
  PyObject *__pyx_t_3 = NULL;
  PyArrayObject *__pyx_t_4 = NULL;
  PyArrayObject *__pyx_t_5 = NULL;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  int __pyx_t_14;
  PyObject *__pyx_t_15 = NULL;
  PyObject *__pyx_t_16 = NULL;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  unsigned int __pyx_t_33;
  unsigned int __pyx_t_34;
  unsigned int __pyx_t_35;
  unsigned int __pyx_t_36;
  unsigned int __pyx_t_37;
  unsigned int __pyx_t_38;
  unsigned int __pyx_t_39;
  unsigned int __pyx_t_40;
  unsigned int __pyx_t_41;
  unsigned int __pyx_t_42;
  unsigned int __pyx_t_43;
  unsigned int __pyx_t_44;
  unsigned int __pyx_t_45;
  unsigned int __pyx_t_46;
  unsigned int __pyx_t_47;
  unsigned int __pyx_t_48;
  unsigned int __pyx_t_49;
  unsigned int __pyx_t_50;
  unsigned int __pyx_t_51;
  unsigned int __pyx_t_52;
  unsigned int __pyx_t_53;
  unsigned int __pyx_t_54;
  unsigned int __pyx_t_55;
  unsigned int __pyx_t_56;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_movieRatings,&__pyx_kp_userIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[5] = {0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid2", 1, 5, 5, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid2", 1, 5, 5, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid2", 1, 5, 5, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDs);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("hybrid2", 1, 5, 5, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "hybrid2") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_movieRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDs = ((PyArrayObject *)values[4]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 5) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_movieRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("hybrid2", 1, 5, 5, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.hybrid2");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_movienorm = Py_None; Py_INCREF(Py_None);
  __pyx_bstruct_W.buf = NULL;
  __pyx_bstruct_movieIndex.buf = NULL;
  __pyx_bstruct_numRatingsForMovie.buf = NULL;
  __pyx_bstruct_movieFeatureCache.buf = NULL;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_movieRatings.buf = NULL;
  __pyx_bstruct_userIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieRatings), __pyx_ptype_5numpy_ndarray, 1, "movieRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDs), __pyx_ptype_5numpy_ndarray, 1, "userIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 990; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_movieRatings, &__pyx_bstruct_movieRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieRatings = __pyx_bstruct_movieRatings.strides[0];
  __pyx_bshape_0_movieRatings = __pyx_bstruct_movieRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDs, &__pyx_bstruct_userIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDs = __pyx_bstruct_userIDs.strides[0];
  __pyx_bshape_0_userIDs = __pyx_bstruct_userIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":998
 * 		"""
 * 		# This is the special, extra user matrix that NSVD1 requires.
 * 		cdef N.ndarray[f32_t, ndim=2] W = self.W             # <<<<<<<<<<<<<<
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_W); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (!(__Pyx_TypeTest(__pyx_1, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = ((PyArrayObject *)__pyx_1);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_1, &__pyx_bstruct_W, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {
    __pyx_v_W = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_W.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 998; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_W = __pyx_bstruct_W.strides[0]; __pyx_bstride_1_W = __pyx_bstruct_W.strides[1];
    __pyx_bshape_0_W = __pyx_bstruct_W.shape[0]; __pyx_bshape_1_W = __pyx_bstruct_W.shape[1];
  }
  __pyx_t_1 = 0;
  __pyx_v_W = ((PyArrayObject *)__pyx_1);
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1001
 * 
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.             # <<<<<<<<<<<<<<
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 */
  __pyx_v_u0 = ((unsigned int)0);

  /* "/home/alex/workspace/flix/src/svd.pyx":1002
 * 		cdef unsigned int i, k, uid, mid, inumRatings, istart
 * 		cdef unsigned int u0 = <unsigned int>0 # to speed up access of bias features.
 * 		cdef unsigned int u1 = <unsigned int>1 # Cython wants to check bounds otherwise...             # <<<<<<<<<<<<<<
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 * 
 */
  __pyx_v_u1 = ((unsigned int)1);

  /* "/home/alex/workspace/flix/src/svd.pyx":1005
 * 		cdef float error, prediction, uf, mf, biasreg, usernorm, ubupdate, mbupdate
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1005; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1006
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1006; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1007
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf             # <<<<<<<<<<<<<<
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeaturesmf); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1007; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numfeaturesmf = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1008
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 		cdef unsigned int numfeaturesmf = <unsigned int>self.numfeaturesmf
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies             # <<<<<<<<<<<<<<
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_nummovies); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1008; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_nummovies = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1010
 * 		cdef unsigned int nummovies = <unsigned int> self.fd.nummovies
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_movieIndex); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (!(__Pyx_TypeTest(__pyx_2, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_2 = ((PyArrayObject *)__pyx_2);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_2, &__pyx_bstruct_movieIndex, PyBUF_FORMAT| PyBUF_STRIDES, 2, 0) == -1)) {
    __pyx_v_movieIndex = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieIndex.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1010; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieIndex = __pyx_bstruct_movieIndex.strides[0]; __pyx_bstride_1_movieIndex = __pyx_bstruct_movieIndex.strides[1];
    __pyx_bshape_0_movieIndex = __pyx_bstruct_movieIndex.shape[0]; __pyx_bshape_1_movieIndex = __pyx_bstruct_movieIndex.shape[1];
  }
  __pyx_t_2 = 0;
  __pyx_v_movieIndex = ((PyArrayObject *)__pyx_2);
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1011
 * 
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]             # <<<<<<<<<<<<<<
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 */
  __pyx_1 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_1);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_int_1);
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_2)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  __pyx_2 = PySlice_New(Py_None, Py_None, Py_None); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(2); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
  Py_INCREF(__pyx_int_0);
  PyTuple_SET_ITEM(__pyx_4, 1, __pyx_int_0);
  __pyx_2 = 0;
  __pyx_2 = PyObject_GetItem(((PyObject *)__pyx_v_movieIndex), ((PyObject *)__pyx_4)); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  __pyx_t_3 = PyNumber_Subtract(__pyx_1, __pyx_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_t_3, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_4 = ((PyArrayObject *)__pyx_t_3);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_t_4, &__pyx_bstruct_numRatingsForMovie, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {
    __pyx_v_numRatingsForMovie = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_numRatingsForMovie.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1011; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.strides[0];
    __pyx_bshape_0_numRatingsForMovie = __pyx_bstruct_numRatingsForMovie.shape[0];
  }
  __pyx_t_4 = 0;
  __pyx_v_numRatingsForMovie = ((PyArrayObject *)__pyx_t_3);
  __pyx_t_3 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1012
 * 		cdef N.ndarray[i32_t, ndim=2] movieIndex = self.fd.movieIndex
 * 		cdef N.ndarray[i32_t, ndim=1] numRatingsForMovie = movieIndex[:,1] - movieIndex[:,0]
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_4 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_4, __pyx_kp_zeros); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_2 = PyLong_FromUnsignedLong(__pyx_v_numfeatures); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_4, 0, __pyx_2);
  __pyx_2 = 0;
  __pyx_2 = PyDict_New(); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyDict_SetItem(__pyx_2, __pyx_kp_dtype, __pyx_kp_153) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyEval_CallObjectWithKeywords(__pyx_1, ((PyObject *)__pyx_4), ((PyObject *)__pyx_2)); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  if (!(__Pyx_TypeTest(__pyx_5, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_5 = ((PyArrayObject *)__pyx_5);
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
    __pyx_v_movieFeatureCache = ((PyArrayObject *)Py_None); Py_INCREF(Py_None); __pyx_bstruct_movieFeatureCache.buf = NULL;
    {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1012; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  } else {__pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
  }
  __pyx_t_5 = 0;
  __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_5);
  __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1014
 * 		cdef N.ndarray[f32_t, ndim=1] movieFeatureCache = N.zeros(numfeatures, dtype='float32')
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1014; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1015
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1015; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1016
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 		cdef float beta = self.beta
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1016; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1017
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 		cdef float beta = self.beta
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1017; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactM = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1018
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 * 		cdef float beta = self.beta             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_beta); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1018; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_beta = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1021
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1021; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1022
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1022; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1023
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1023; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactUb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1024
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 		# NSVD1 specific parameters
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1024; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMb = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1027
 * 
 * 		# NSVD1 specific parameters
 * 		cdef float lrateUn = self.lrateUn             # <<<<<<<<<<<<<<
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn
 */
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUn); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_4); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1027; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  __pyx_v_lrateUn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1028
 * 		# NSVD1 specific parameters
 * 		cdef float lrateUn = self.lrateUn
 * 		cdef float lrateMn = self.lrateMn             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUn = self.dampfactUn
 * 		cdef float dampfactMn = self.dampfactMn
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMn); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1028; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateMn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1029
 * 		cdef float lrateUn = self.lrateUn
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMn = self.dampfactMn
 * 
 */
  __pyx_5 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUn); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_5); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1029; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  __pyx_v_dampfactUn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1030
 * 		cdef float lrateMn = self.lrateMn
 * 		cdef float dampfactUn = self.dampfactUn
 * 		cdef float dampfactMn = self.dampfactMn             # <<<<<<<<<<<<<<
 * 
 * 		for mid from 0 <= mid < nummovies:
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMn); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1030; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMn = __pyx_6;

  /* "/home/alex/workspace/flix/src/svd.pyx":1032
 * 		cdef float dampfactMn = self.dampfactMn
 * 
 * 		for mid from 0 <= mid < nummovies:             # <<<<<<<<<<<<<<
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 */
  for (__pyx_v_mid = 0; __pyx_v_mid < __pyx_v_nummovies; __pyx_v_mid++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":1033
 * 
 * 		for mid from 0 <= mid < nummovies:
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)             # <<<<<<<<<<<<<<
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 */
    __pyx_7 = ((__pyx_v_mid % 2000) == 0);
    if (__pyx_7) {
      __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_2 = PyLong_FromUnsignedLong(__pyx_v_mid); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_3 = PyNumber_Remainder(__pyx_kp_154, __pyx_2); if (unlikely(!__pyx_t_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_5 = PyTuple_New(1); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_5, 0, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_1 = PyObject_Call(__pyx_4, ((PyObject *)__pyx_5), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1033; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_4); __pyx_4 = 0;
      Py_DECREF(((PyObject *)__pyx_5)); __pyx_5 = 0;
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1035
 * 			if mid % 2000 == 0: self.updateLog('\tUpdating movie %d' % mid)
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]             # <<<<<<<<<<<<<<
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm= inumRatings**-0.5
 */
    __pyx_t_6 = __pyx_v_mid;
    __pyx_v_inumRatings = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_numRatingsForMovie.buf, __pyx_t_6, __pyx_bstride_0_numRatingsForMovie)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1036
 * 
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]             # <<<<<<<<<<<<<<
 * 			movienorm= inumRatings**-0.5
 * 
 */
    __pyx_t_7 = __pyx_v_mid;
    __pyx_t_8 = __pyx_v_u0;
    __pyx_v_istart = ((unsigned int)(*__Pyx_BufPtrStrided2d(__pyx_t_3svd_i32_t *, __pyx_bstruct_movieIndex.buf, __pyx_t_7, __pyx_bstride_0_movieIndex, __pyx_t_8, __pyx_bstride_1_movieIndex)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1037
 * 			inumRatings = <unsigned int>numRatingsForMovie[mid]
 * 			istart = <unsigned int>movieIndex[mid,u0]
 * 			movienorm= inumRatings**-0.5             # <<<<<<<<<<<<<<
 * 
 * 			# zero the movie vector
 */
    __pyx_2 = PyFloat_FromDouble(pow(__pyx_v_inumRatings, (-0.5))); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1037; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_v_movienorm);
    __pyx_v_movienorm = __pyx_2;
    __pyx_2 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1040
 * 
 * 			# zero the movie vector
 * 			for k from numfeaturesmf <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				movieFeatureCache[k] = 0.0
 * 
 */
    for (__pyx_v_k = __pyx_v_numfeaturesmf; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1041
 * 			# zero the movie vector
 * 			for k from numfeaturesmf <= k < numfeatures:
 * 				movieFeatureCache[k] = 0.0             # <<<<<<<<<<<<<<
 * 
 * 			# construct the movie vector from user vectors
 */
      __pyx_t_9 = __pyx_v_k;
      *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_9, __pyx_bstride_0_movieFeatureCache) = 0.0;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1044
 * 
 * 			# construct the movie vector from user vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1045
 * 			# construct the movie vector from user vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					movieFeatureCache[k] += W[uid,k]
 */
      __pyx_t_10 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_10, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1046
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					movieFeatureCache[k] += W[uid,k]
 * 
 */
      for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":1047
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					movieFeatureCache[k] += W[uid,k]             # <<<<<<<<<<<<<<
 * 
 * 			# normalize based on movie support, multiply in (1-beta)
 */
        __pyx_t_11 = __pyx_v_uid;
        __pyx_t_12 = __pyx_v_k;
        __pyx_t_13 = __pyx_v_k;
        *__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_13, __pyx_bstride_0_movieFeatureCache) += (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_11, __pyx_bstride_0_W, __pyx_t_12, __pyx_bstride_1_W));
      }
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1050
 * 
 * 			# normalize based on movie support, multiply in (1-beta)
 * 			movieFeatureCache *= movienorm#*(1-beta)             # <<<<<<<<<<<<<<
 * 
 * 			# put the user vector into the user matrix
 */
    __pyx_4 = PyNumber_InPlaceMultiply(((PyObject *)__pyx_v_movieFeatureCache), __pyx_v_movienorm); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    if (!(__Pyx_TypeTest(__pyx_4, __pyx_ptype_5numpy_ndarray))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = ((PyArrayObject *)__pyx_4);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __pyx_t_14 = __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_t_5, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0);
    if (unlikely(__pyx_t_14 < 0)) 
    {
        PyErr_Fetch(&__pyx_t_3, &__pyx_t_15, &__pyx_t_16);
        if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_movieFeatureCache, &__pyx_bstruct_movieFeatureCache, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 1, 0) == -1)) {
            Py_XDECREF(__pyx_t_3); Py_XDECREF(__pyx_t_15); Py_XDECREF(__pyx_t_16);
            __Pyx_RaiseBufferFallbackError();
          } else {
            PyErr_Restore(__pyx_t_3, __pyx_t_15, __pyx_t_16);
        }
    }
    __pyx_bstride_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.strides[0];
    __pyx_bshape_0_movieFeatureCache = __pyx_bstruct_movieFeatureCache.shape[0];
    if (unlikely(__pyx_t_14 < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1050; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_t_5 = 0;
    Py_DECREF(((PyObject *)__pyx_v_movieFeatureCache));
    __pyx_v_movieFeatureCache = ((PyArrayObject *)__pyx_4);
    __pyx_4 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1053
 * 
 * 			# put the user vector into the user matrix
 * 			for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				M[mid,k] = movieFeatureCache[k]
 * 
 */
    for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1054
 * 			# put the user vector into the user matrix
 * 			for k from numfeaturesmf+2 <= k < numfeatures:
 * 				M[mid,k] = movieFeatureCache[k]             # <<<<<<<<<<<<<<
 * 
 * 			# The Engine of NSVD1 begins here----
 */
      __pyx_t_17 = __pyx_v_k;
      __pyx_t_18 = __pyx_v_mid;
      __pyx_t_19 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_18, __pyx_bstride_0_M, __pyx_t_19, __pyx_bstride_1_M) = (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_17, __pyx_bstride_0_movieFeatureCache));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1057
 * 
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1058
 * 			# The Engine of NSVD1 begins here----
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 
 */
      __pyx_t_20 = (__pyx_v_istart + __pyx_v_i);
      __pyx_7 = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_20, __pyx_bstride_0_movieRatings)) == 0);
      if (__pyx_7) {
        goto __pyx_L17;
        goto __pyx_L19;
      }
      __pyx_L19:;

      /* "/home/alex/workspace/flix/src/svd.pyx":1059
 * 			for i from 0 <= i < inumRatings:
 * 				if movieRatings[istart+i] == 0: continue # the (uid, mid) pair was from the quiz, no real rating
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 
 * 				# 1. Compute error
 */
      __pyx_t_21 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_21, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1062
 * 
 * 				# 1. Compute error
 * 				prediction = 0.0             # <<<<<<<<<<<<<<
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 */
      __pyx_v_prediction = 0.0;

      /* "/home/alex/workspace/flix/src/svd.pyx":1063
 * 				# 1. Compute error
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":1064
 * 				prediction = 0.0
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 				error = movieRatings[istart+i] - prediction
 * 
 */
        __pyx_t_22 = __pyx_v_uid;
        __pyx_t_23 = __pyx_v_k;
        __pyx_t_24 = __pyx_v_mid;
        __pyx_t_25 = __pyx_v_k;
        __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_22, __pyx_bstride_0_U, __pyx_t_23, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_24, __pyx_bstride_0_M, __pyx_t_25, __pyx_bstride_1_M)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":1065
 * 				for k from 0 <= k < numfeatures:
 * 					prediction += U[uid,k]*M[mid,k]
 * 				error = movieRatings[istart+i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 				# 2. Update the bias features
 */
      __pyx_t_26 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_movieRatings.buf, __pyx_t_26, __pyx_bstride_0_movieRatings)) - __pyx_v_prediction);

      /* "/home/alex/workspace/flix/src/svd.pyx":1068
 * 
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]             # <<<<<<<<<<<<<<
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error - dampfactMb*biasreg)
 */
      __pyx_t_27 = __pyx_v_uid;
      __pyx_t_28 = (__pyx_v_u1 + __pyx_v_numfeaturesmf);
      __pyx_t_29 = __pyx_v_mid;
      __pyx_t_30 = (__pyx_v_u0 + __pyx_v_numfeaturesmf);
      __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_27, __pyx_bstride_0_U, __pyx_t_28, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_29, __pyx_bstride_0_M, __pyx_t_30, __pyx_bstride_1_M)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1069
 * 				# 2. Update the bias features
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error - dampfactMb*biasreg)
 * 
 */
      __pyx_t_31 = __pyx_v_uid;
      __pyx_t_32 = (__pyx_v_u1 + __pyx_v_numfeaturesmf);
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_31, __pyx_bstride_0_U, __pyx_t_32, __pyx_bstride_1_U) += (__pyx_v_lrateUb * (__pyx_v_error - (__pyx_v_dampfactUb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1070
 * 				biasreg = U[uid,u1+numfeaturesmf] + M[mid,u0+numfeaturesmf]
 * 				U[uid,u1+numfeaturesmf] += lrateUb*(error - dampfactUb*biasreg)
 * 				M[mid,u0+numfeaturesmf] +=  lrateMb*(error - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_t_33 = __pyx_v_mid;
      __pyx_t_34 = (__pyx_v_u0 + __pyx_v_numfeaturesmf);
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_33, __pyx_bstride_0_M, __pyx_t_34, __pyx_bstride_1_M) += (__pyx_v_lrateMb * (__pyx_v_error - (__pyx_v_dampfactMb * __pyx_v_biasreg)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1075
 * 				# 3. Update the bulk of the features
 * 				# 	for the MF
 * 				for k from 0 <= k < numfeaturesmf:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeaturesmf; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":1076
 * 				# 	for the MF
 * 				for k from 0 <= k < numfeaturesmf:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(beta*error*mf - dampfactU*uf)
 */
        __pyx_t_35 = __pyx_v_uid;
        __pyx_t_36 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_35, __pyx_bstride_0_U, __pyx_t_36, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":1077
 * 				for k from 0 <= k < numfeaturesmf:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateU*(beta*error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(beta*error*uf - dampfactM*mf)
 */
        __pyx_t_37 = __pyx_v_mid;
        __pyx_t_38 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_37, __pyx_bstride_0_M, __pyx_t_38, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":1078
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(beta*error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateM*(beta*error*uf - dampfactM*mf)
 * 				# 	for NSVD1
 */
        __pyx_t_39 = __pyx_v_uid;
        __pyx_t_40 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_39, __pyx_bstride_0_U, __pyx_t_40, __pyx_bstride_1_U) += (__pyx_v_lrateU * (((__pyx_v_beta * __pyx_v_error) * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":1079
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateU*(beta*error*mf - dampfactU*uf)
 * 					M[mid,k] += lrateM*(beta*error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 				# 	for NSVD1
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 */
        __pyx_t_41 = __pyx_v_mid;
        __pyx_t_42 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_41, __pyx_bstride_0_M, __pyx_t_42, __pyx_bstride_1_M) += (__pyx_v_lrateM * (((__pyx_v_beta * __pyx_v_error) * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
      }

      /* "/home/alex/workspace/flix/src/svd.pyx":1081
 * 					M[mid,k] += lrateM*(beta*error*uf - dampfactM*mf)
 * 				# 	for NSVD1
 * 				for k from numfeaturesmf+2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 */
      for (__pyx_v_k = (__pyx_v_numfeaturesmf + 2); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":1082
 * 				# 	for NSVD1
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 */
        __pyx_t_43 = __pyx_v_uid;
        __pyx_t_44 = __pyx_v_k;
        __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_43, __pyx_bstride_0_U, __pyx_t_44, __pyx_bstride_1_U));

        /* "/home/alex/workspace/flix/src/svd.pyx":1083
 * 				for k from numfeaturesmf+2 <= k < numfeatures:
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)
 */
        __pyx_t_45 = __pyx_v_mid;
        __pyx_t_46 = __pyx_v_k;
        __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_45, __pyx_bstride_0_M, __pyx_t_46, __pyx_bstride_1_M));

        /* "/home/alex/workspace/flix/src/svd.pyx":1084
 * 					uf = U[uid,k]
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)             # <<<<<<<<<<<<<<
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)
 * 
 */
        __pyx_t_47 = __pyx_v_uid;
        __pyx_t_48 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_47, __pyx_bstride_0_U, __pyx_t_48, __pyx_bstride_1_U) += (__pyx_v_lrateUn * (((__pyx_v_error * (1 - __pyx_v_beta)) * __pyx_v_mf) - (__pyx_v_dampfactUn * __pyx_v_uf)));

        /* "/home/alex/workspace/flix/src/svd.pyx":1085
 * 					mf = M[mid,k]
 * 					U[uid,k] += lrateUn*(error*(1-beta)*mf - dampfactUn*uf)
 * 					M[mid,k] += lrateMn*(error*(1-beta)*uf - dampfactMn*mf)             # <<<<<<<<<<<<<<
 * 
 * 			# 4. Update the movie feature vectors
 */
        __pyx_t_49 = __pyx_v_mid;
        __pyx_t_50 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_49, __pyx_bstride_0_M, __pyx_t_50, __pyx_bstride_1_M) += (__pyx_v_lrateMn * (((__pyx_v_error * (1 - __pyx_v_beta)) * __pyx_v_uf) - (__pyx_v_dampfactMn * __pyx_v_mf)));
      }
      __pyx_L17:;
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1088
 * 
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:             # <<<<<<<<<<<<<<
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_inumRatings; __pyx_v_i++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1089
 * 			# 4. Update the movie feature vectors
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]             # <<<<<<<<<<<<<<
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 * 					W[uid,k] += (U[mid,k] - movieFeatureCache[k])*movienorm
 */
      __pyx_t_51 = (__pyx_v_istart + __pyx_v_i);
      __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDs.buf, __pyx_t_51, __pyx_bstride_0_userIDs)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1090
 * 			for i from 0 <= i < inumRatings:
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 					W[uid,k] += (U[mid,k] - movieFeatureCache[k])*movienorm
 * 
 */
      for (__pyx_v_k = (2 + __pyx_v_numfeaturesmf); __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

        /* "/home/alex/workspace/flix/src/svd.pyx":1091
 * 				uid = <unsigned int>userIDs[istart+i]
 * 				for k from 2+numfeaturesmf <= k < numfeatures:
 * 					W[uid,k] += (U[mid,k] - movieFeatureCache[k])*movienorm             # <<<<<<<<<<<<<<
 * 
 * 
 */
        __pyx_t_52 = __pyx_v_mid;
        __pyx_t_53 = __pyx_v_k;
        __pyx_t_54 = __pyx_v_k;
        __pyx_5 = PyFloat_FromDouble(((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_52, __pyx_bstride_0_U, __pyx_t_53, __pyx_bstride_1_U)) - (*__Pyx_BufPtrStrided1d(__pyx_t_3svd_f32_t *, __pyx_bstruct_movieFeatureCache.buf, __pyx_t_54, __pyx_bstride_0_movieFeatureCache)))); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_t_16 = PyNumber_Multiply(__pyx_5, __pyx_v_movienorm); if (unlikely(!__pyx_t_16)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_5); __pyx_5 = 0;
        __pyx_8 = __pyx_PyFloat_AsDouble(__pyx_t_16); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1091; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_t_16); __pyx_t_16 = 0;
        __pyx_t_55 = __pyx_v_uid;
        __pyx_t_56 = __pyx_v_k;
        *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_W.buf, __pyx_t_55, __pyx_bstride_0_W, __pyx_t_56, __pyx_bstride_1_W) += __pyx_8;
      }
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1094
 * 
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.hybrid2");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_numRatingsForMovie);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_W);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieFeatureCache);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIndex);
  __pyx_L2:;
  Py_XDECREF(__pyx_v_W);
  Py_XDECREF(__pyx_v_movieIndex);
  Py_XDECREF(__pyx_v_numRatingsForMovie);
  Py_XDECREF(__pyx_v_movieFeatureCache);
  Py_DECREF(__pyx_v_movienorm);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1098
 * 
 * 	@cython.boundscheck(False)
 * 	def rmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Regularized Matrix Factorization.
 */

static PyObject *__pyx_pf_3svd_3SVD_rmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_rmf[] = "Regularized Matrix Factorization.\n\t\tAdds a damping constant to keep feature values low.";
static PyMethodDef __pyx_mdef_3svd_3SVD_rmf = {"rmf", (PyCFunction)__pyx_pf_3svd_3SVD_rmf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_rmf};
static PyObject *__pyx_pf_3svd_3SVD_rmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  float __pyx_4;
  int __pyx_5;
  PyObject *__pyx_6 = 0;
  PyObject *__pyx_t_1 = NULL;
  unsigned int __pyx_t_2;
  unsigned int __pyx_t_3;
  unsigned int __pyx_t_4;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  unsigned int __pyx_t_14;
  unsigned int __pyx_t_15;
  unsigned int __pyx_t_16;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[6] = {0,0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  5:
      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[5])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "rmf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[4]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[5]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("rmf", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.rmf");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1099; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":1105
 * 		cdef float error, prediction, uf, mf
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1106
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1106; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1108
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1108; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1109
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1109; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateM = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1110
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1110; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1111
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < numratings:
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1111; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactM = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1113
 * 		cdef float dampfactM = self.dampfactM
 * 
 * 		for i from 0 <= i < numratings:             # <<<<<<<<<<<<<<
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":1114
 * 
 * 		for i from 0 <= i < numratings:
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)             # <<<<<<<<<<<<<<
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]
 */
    __pyx_5 = ((__pyx_v_i % 10000000) == 0);
    if (__pyx_5) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_i); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_155, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_6 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1114; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1115
 * 		for i from 0 <= i < numratings:
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_2, __pyx_bstride_0_userIDsForUsers)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1116
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]             # <<<<<<<<<<<<<<
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 */
    __pyx_t_3 = __pyx_v_i;
    __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_3, __pyx_bstride_0_movieIDs)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1118
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1119
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1120
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 			error = userRatings[i] - prediction
 * 
 */
      __pyx_t_4 = __pyx_v_uid;
      __pyx_t_5 = __pyx_v_k;
      __pyx_t_6 = __pyx_v_mid;
      __pyx_t_7 = __pyx_v_k;
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_4, __pyx_bstride_0_U, __pyx_t_5, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_6, __pyx_bstride_0_M, __pyx_t_7, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1121
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 			# Update non-bias features
 */
    __pyx_t_8 = __pyx_v_i;
    __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_8, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

    /* "/home/alex/workspace/flix/src/svd.pyx":1124
 * 
 * 			# Update non-bias features
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1125
 * 			# Update non-bias features
 * 			for k from 0 <= k < numfeatures:
 * 				uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
      __pyx_t_9 = __pyx_v_uid;
      __pyx_t_10 = __pyx_v_k;
      __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_9, __pyx_bstride_0_U, __pyx_t_10, __pyx_bstride_1_U));

      /* "/home/alex/workspace/flix/src/svd.pyx":1126
 * 			for k from 0 <= k < numfeatures:
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
      __pyx_t_11 = __pyx_v_mid;
      __pyx_t_12 = __pyx_v_k;
      __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_11, __pyx_bstride_0_M, __pyx_t_12, __pyx_bstride_1_M));

      /* "/home/alex/workspace/flix/src/svd.pyx":1127
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
      __pyx_t_13 = __pyx_v_uid;
      __pyx_t_14 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_13, __pyx_bstride_0_U, __pyx_t_14, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1128
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
      __pyx_t_15 = __pyx_v_mid;
      __pyx_t_16 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_15, __pyx_bstride_0_M, __pyx_t_16, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1130
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_6);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.rmf");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1134
 * 
 * 	@cython.boundscheck(False)
 * 	def brismf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Biased Regularized Incremental Simultaneous Matrix Factorization, a la
 */

static PyObject *__pyx_pf_3svd_3SVD_brismf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_brismf[] = "Biased Regularized Incremental Simultaneous Matrix Factorization, a la\n\t\t\"Investigation of Various Matrix Factorization Methods for \n\t\tLarge Recommender Systems\", as seen in KDD 2008";
static PyMethodDef __pyx_mdef_3svd_3SVD_brismf = {"brismf", (PyCFunction)__pyx_pf_3svd_3SVD_brismf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_brismf};
static PyObject *__pyx_pf_3svd_3SVD_brismf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  float __pyx_4;
  int __pyx_5;
  PyObject *__pyx_6 = 0;
  PyObject *__pyx_t_1 = NULL;
  unsigned int __pyx_t_2;
  unsigned int __pyx_t_3;
  unsigned int __pyx_t_4;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  long __pyx_t_10;
  unsigned int __pyx_t_11;
  long __pyx_t_12;
  unsigned int __pyx_t_13;
  long __pyx_t_14;
  unsigned int __pyx_t_15;
  long __pyx_t_16;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[6] = {0,0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  5:
      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[5])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "brismf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[4]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[5]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("brismf", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.brismf");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":1142
 * 		cdef float error, prediction, uf, mf, biasreg
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1142; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1143
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1143; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1145
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1145; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1146
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1146; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateM = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1147
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1147; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1148
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1148; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactM = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1151
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1151; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1152
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1152; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateMb = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1153
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1153; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactUb = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1154
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < (numratings):
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1154; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMb = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1156
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 * 		for i from 0 <= i < (numratings):             # <<<<<<<<<<<<<<
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":1157
 * 
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)             # <<<<<<<<<<<<<<
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]
 */
    __pyx_5 = ((__pyx_v_i % 10000000) == 0);
    if (__pyx_5) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_i); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_156, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_6 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1157; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_6); __pyx_6 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1158
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_2, __pyx_bstride_0_userIDsForUsers)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1159
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]             # <<<<<<<<<<<<<<
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 */
    __pyx_t_3 = __pyx_v_i;
    __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_3, __pyx_bstride_0_movieIDs)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1161
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1162
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1163
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 			error = userRatings[i] - prediction
 * 
 */
      __pyx_t_4 = __pyx_v_uid;
      __pyx_t_5 = __pyx_v_k;
      __pyx_t_6 = __pyx_v_mid;
      __pyx_t_7 = __pyx_v_k;
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_4, __pyx_bstride_0_U, __pyx_t_5, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_6, __pyx_bstride_0_M, __pyx_t_7, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1164
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 			# Update bias features
 */
    __pyx_t_8 = __pyx_v_i;
    __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_8, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

    /* "/home/alex/workspace/flix/src/svd.pyx":1167
 * 
 * 			# Update bias features
 * 			biasreg = U[uid,1] + M[mid,0]             # <<<<<<<<<<<<<<
 * 			U[uid,1] += lrateUb*(error - dampfactUb*biasreg)
 * 			M[mid,0] += lrateMb*(error - dampfactMb*biasreg)
 */
    __pyx_t_9 = __pyx_v_uid;
    __pyx_t_10 = 1;
    if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_bshape_1_U;
    __pyx_t_11 = __pyx_v_mid;
    __pyx_t_12 = 0;
    if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_bshape_1_M;
    __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_9, __pyx_bstride_0_U, __pyx_t_10, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_11, __pyx_bstride_0_M, __pyx_t_12, __pyx_bstride_1_M)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1168
 * 			# Update bias features
 * 			biasreg = U[uid,1] + M[mid,0]
 * 			U[uid,1] += lrateUb*(error - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 			M[mid,0] += lrateMb*(error - dampfactMb*biasreg)
 * 
 */
    __pyx_t_13 = __pyx_v_uid;
    __pyx_t_14 = 1;
    if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_bshape_1_U;
    *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_13, __pyx_bstride_0_U, __pyx_t_14, __pyx_bstride_1_U) += (__pyx_v_lrateUb * (__pyx_v_error - (__pyx_v_dampfactUb * __pyx_v_biasreg)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1169
 * 			biasreg = U[uid,1] + M[mid,0]
 * 			U[uid,1] += lrateUb*(error - dampfactUb*biasreg)
 * 			M[mid,0] += lrateMb*(error - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 
 * 			# Update non-bias features
 */
    __pyx_t_15 = __pyx_v_mid;
    __pyx_t_16 = 0;
    if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_bshape_1_M;
    *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_15, __pyx_bstride_0_M, __pyx_t_16, __pyx_bstride_1_M) += (__pyx_v_lrateMb * (__pyx_v_error - (__pyx_v_dampfactMb * __pyx_v_biasreg)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1172
 * 
 * 			# Update non-bias features
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1173
 * 			# Update non-bias features
 * 			for k from 2 <= k < numfeatures:
 * 				uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 */
      __pyx_t_17 = __pyx_v_uid;
      __pyx_t_18 = __pyx_v_k;
      __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_17, __pyx_bstride_0_U, __pyx_t_18, __pyx_bstride_1_U));

      /* "/home/alex/workspace/flix/src/svd.pyx":1174
 * 			for k from 2 <= k < numfeatures:
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 */
      __pyx_t_19 = __pyx_v_mid;
      __pyx_t_20 = __pyx_v_k;
      __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_19, __pyx_bstride_0_M, __pyx_t_20, __pyx_bstride_1_M));

      /* "/home/alex/workspace/flix/src/svd.pyx":1175
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 */
      __pyx_t_21 = __pyx_v_uid;
      __pyx_t_22 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_21, __pyx_bstride_0_U, __pyx_t_22, __pyx_bstride_1_U) += (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf)));

      /* "/home/alex/workspace/flix/src/svd.pyx":1176
 * 				mf = M[mid,k]
 * 				U[uid,k] += lrateU*(error*mf - dampfactU*uf)
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
      __pyx_t_23 = __pyx_v_mid;
      __pyx_t_24 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_23, __pyx_bstride_0_M, __pyx_t_24, __pyx_bstride_1_M) += (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf)));
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1178
 * 				M[mid,k] += lrateM*(error*uf - dampfactM*mf)
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_6);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.brismf");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1182
 * 
 * 	@cython.boundscheck(False)
 * 	def bpmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */

static PyObject *__pyx_pf_3svd_3SVD_bpmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_bpmf[] = "\n\t\tBiased Positive matrix factorization.\n\t\tKeep either user and movie features positive, depending on if\n\t\tkeepUpositive and keepMpositive are 1 or 0.\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_bpmf = {"bpmf", (PyCFunction)__pyx_pf_3svd_3SVD_bpmf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_bpmf};
static PyObject *__pyx_pf_3svd_3SVD_bpmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_biasreg;
  float __pyx_v_tmpm;
  float __pyx_v_tmpu;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  int __pyx_v_keepUpositive;
  int __pyx_v_keepMpositive;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  float __pyx_v_lrateUb;
  float __pyx_v_lrateMb;
  float __pyx_v_dampfactUb;
  float __pyx_v_dampfactMb;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  int __pyx_4;
  float __pyx_5;
  int __pyx_6;
  PyObject *__pyx_7 = 0;
  PyObject *__pyx_t_1 = NULL;
  unsigned int __pyx_t_2;
  unsigned int __pyx_t_3;
  unsigned int __pyx_t_4;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  long __pyx_t_10;
  unsigned int __pyx_t_11;
  long __pyx_t_12;
  unsigned int __pyx_t_13;
  long __pyx_t_14;
  unsigned int __pyx_t_15;
  long __pyx_t_16;
  unsigned int __pyx_t_17;
  long __pyx_t_18;
  unsigned int __pyx_t_19;
  long __pyx_t_20;
  unsigned int __pyx_t_21;
  unsigned int __pyx_t_22;
  unsigned int __pyx_t_23;
  unsigned int __pyx_t_24;
  unsigned int __pyx_t_25;
  unsigned int __pyx_t_26;
  unsigned int __pyx_t_27;
  unsigned int __pyx_t_28;
  unsigned int __pyx_t_29;
  unsigned int __pyx_t_30;
  unsigned int __pyx_t_31;
  unsigned int __pyx_t_32;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[6] = {0,0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  5:
      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[5])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "bpmf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[4]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[5]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("bpmf", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.bpmf");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1183; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":1192
 * 		cdef float error, prediction, uf, mf, biasreg, tmpm, tmpu
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1192; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1193
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 
 * 		cdef int keepUpositive = self.keepUpositive
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1193; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1195
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 * 		cdef int keepUpositive = self.keepUpositive             # <<<<<<<<<<<<<<
 * 		cdef int keepMpositive = self.keepMpositive
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_keepUpositive); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyInt_int(__pyx_2); if (unlikely((__pyx_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1195; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_keepUpositive = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1196
 * 
 * 		cdef int keepUpositive = self.keepUpositive
 * 		cdef int keepMpositive = self.keepMpositive             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_keepMpositive); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyInt_int(__pyx_1); if (unlikely((__pyx_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1196; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_keepMpositive = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1198
 * 		cdef int keepMpositive = self.keepMpositive
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1198; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1199
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1199; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateM = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1200
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1200; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1201
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		# special bias features
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1201; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactM = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1204
 * 
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb             # <<<<<<<<<<<<<<
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1204; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateUb = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1205
 * 		# special bias features
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1205; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateMb = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1206
 * 		cdef float lrateUb = self.lrateUb
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb             # <<<<<<<<<<<<<<
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactUb); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1206; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactUb = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1207
 * 		cdef float lrateMb = self.lrateMb
 * 		cdef float dampfactUb = self.dampfactUb
 * 		cdef float dampfactMb = self.dampfactMb             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < (numratings):
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactMb); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1207; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactMb = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1209
 * 		cdef float dampfactMb = self.dampfactMb
 * 
 * 		for i from 0 <= i < (numratings):             # <<<<<<<<<<<<<<
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":1210
 * 
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)             # <<<<<<<<<<<<<<
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]
 */
    __pyx_6 = ((__pyx_v_i % 10000000) == 0);
    if (__pyx_6) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_i); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_157, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_7 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1210; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_7); __pyx_7 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1211
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_2, __pyx_bstride_0_userIDsForUsers)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1212
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]             # <<<<<<<<<<<<<<
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 */
    __pyx_t_3 = __pyx_v_i;
    __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_3, __pyx_bstride_0_movieIDs)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1214
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1215
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1216
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 			error = userRatings[i] - prediction
 * 
 */
      __pyx_t_4 = __pyx_v_uid;
      __pyx_t_5 = __pyx_v_k;
      __pyx_t_6 = __pyx_v_mid;
      __pyx_t_7 = __pyx_v_k;
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_4, __pyx_bstride_0_U, __pyx_t_5, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_6, __pyx_bstride_0_M, __pyx_t_7, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1217
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 			# Update bias features
 */
    __pyx_t_8 = __pyx_v_i;
    __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_8, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

    /* "/home/alex/workspace/flix/src/svd.pyx":1220
 * 
 * 			# Update bias features
 * 			biasreg = U[uid,1] + M[mid,0]             # <<<<<<<<<<<<<<
 * 			tmpu = U[uid,1] + lrateUb*(error - dampfactUb*biasreg)
 * 			tmpm = M[mid,0] + lrateMb*(error - dampfactMb*biasreg)
 */
    __pyx_t_9 = __pyx_v_uid;
    __pyx_t_10 = 1;
    if (__pyx_t_10 < 0) __pyx_t_10 += __pyx_bshape_1_U;
    __pyx_t_11 = __pyx_v_mid;
    __pyx_t_12 = 0;
    if (__pyx_t_12 < 0) __pyx_t_12 += __pyx_bshape_1_M;
    __pyx_v_biasreg = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_9, __pyx_bstride_0_U, __pyx_t_10, __pyx_bstride_1_U)) + (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_11, __pyx_bstride_0_M, __pyx_t_12, __pyx_bstride_1_M)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1221
 * 			# Update bias features
 * 			biasreg = U[uid,1] + M[mid,0]
 * 			tmpu = U[uid,1] + lrateUb*(error - dampfactUb*biasreg)             # <<<<<<<<<<<<<<
 * 			tmpm = M[mid,0] + lrateMb*(error - dampfactMb*biasreg)
 * 			if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 */
    __pyx_t_13 = __pyx_v_uid;
    __pyx_t_14 = 1;
    if (__pyx_t_14 < 0) __pyx_t_14 += __pyx_bshape_1_U;
    __pyx_v_tmpu = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_13, __pyx_bstride_0_U, __pyx_t_14, __pyx_bstride_1_U)) + (__pyx_v_lrateUb * (__pyx_v_error - (__pyx_v_dampfactUb * __pyx_v_biasreg))));

    /* "/home/alex/workspace/flix/src/svd.pyx":1222
 * 			biasreg = U[uid,1] + M[mid,0]
 * 			tmpu = U[uid,1] + lrateUb*(error - dampfactUb*biasreg)
 * 			tmpm = M[mid,0] + lrateMb*(error - dampfactMb*biasreg)             # <<<<<<<<<<<<<<
 * 			if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 			if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 */
    __pyx_t_15 = __pyx_v_mid;
    __pyx_t_16 = 0;
    if (__pyx_t_16 < 0) __pyx_t_16 += __pyx_bshape_1_M;
    __pyx_v_tmpm = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_15, __pyx_bstride_0_M, __pyx_t_16, __pyx_bstride_1_M)) + (__pyx_v_lrateMb * (__pyx_v_error - (__pyx_v_dampfactMb * __pyx_v_biasreg))));

    /* "/home/alex/workspace/flix/src/svd.pyx":1223
 * 			tmpu = U[uid,1] + lrateUb*(error - dampfactUb*biasreg)
 * 			tmpm = M[mid,0] + lrateMb*(error - dampfactMb*biasreg)
 * 			if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0             # <<<<<<<<<<<<<<
 * 			if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 			U[uid,1] = tmpu
 */
    __pyx_6 = (__pyx_v_keepUpositive == 1);
    if (__pyx_6) {
      __pyx_6 = (__pyx_v_tmpu < 0.0);
    }
    if (__pyx_6) {
      __pyx_v_tmpu = 0.0;
      goto __pyx_L11;
    }
    __pyx_L11:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1224
 * 			tmpm = M[mid,0] + lrateMb*(error - dampfactMb*biasreg)
 * 			if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 			if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0             # <<<<<<<<<<<<<<
 * 			U[uid,1] = tmpu
 * 			M[mid,0] = tmpm
 */
    __pyx_6 = (__pyx_v_keepMpositive == 1);
    if (__pyx_6) {
      __pyx_6 = (__pyx_v_tmpm < 0.0);
    }
    if (__pyx_6) {
      __pyx_v_tmpm = 0.0;
      goto __pyx_L12;
    }
    __pyx_L12:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1225
 * 			if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 			if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 			U[uid,1] = tmpu             # <<<<<<<<<<<<<<
 * 			M[mid,0] = tmpm
 * 
 */
    __pyx_t_17 = __pyx_v_uid;
    __pyx_t_18 = 1;
    if (__pyx_t_18 < 0) __pyx_t_18 += __pyx_bshape_1_U;
    *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_17, __pyx_bstride_0_U, __pyx_t_18, __pyx_bstride_1_U) = __pyx_v_tmpu;

    /* "/home/alex/workspace/flix/src/svd.pyx":1226
 * 			if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 			U[uid,1] = tmpu
 * 			M[mid,0] = tmpm             # <<<<<<<<<<<<<<
 * 
 * 			# Update non-bias features
 */
    __pyx_t_19 = __pyx_v_mid;
    __pyx_t_20 = 0;
    if (__pyx_t_20 < 0) __pyx_t_20 += __pyx_bshape_1_M;
    *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_19, __pyx_bstride_0_M, __pyx_t_20, __pyx_bstride_1_M) = __pyx_v_tmpm;

    /* "/home/alex/workspace/flix/src/svd.pyx":1229
 * 
 * 			# Update non-bias features
 * 			for k from 2 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 */
    for (__pyx_v_k = 2; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1230
 * 			# Update non-bias features
 * 			for k from 2 <= k < numfeatures:
 * 				uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 */
      __pyx_t_21 = __pyx_v_uid;
      __pyx_t_22 = __pyx_v_k;
      __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_21, __pyx_bstride_0_U, __pyx_t_22, __pyx_bstride_1_U));

      /* "/home/alex/workspace/flix/src/svd.pyx":1231
 * 			for k from 2 <= k < numfeatures:
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 */
      __pyx_t_23 = __pyx_v_mid;
      __pyx_t_24 = __pyx_v_k;
      __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_23, __pyx_bstride_0_M, __pyx_t_24, __pyx_bstride_1_M));

      /* "/home/alex/workspace/flix/src/svd.pyx":1232
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 */
      __pyx_t_25 = __pyx_v_uid;
      __pyx_t_26 = __pyx_v_k;
      __pyx_v_tmpu = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_25, __pyx_bstride_0_U, __pyx_t_26, __pyx_bstride_1_U)) + (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf))));

      /* "/home/alex/workspace/flix/src/svd.pyx":1233
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 */
      __pyx_t_27 = __pyx_v_mid;
      __pyx_t_28 = __pyx_v_k;
      __pyx_v_tmpm = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_27, __pyx_bstride_0_M, __pyx_t_28, __pyx_bstride_1_M)) + (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf))));

      /* "/home/alex/workspace/flix/src/svd.pyx":1234
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0             # <<<<<<<<<<<<<<
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu
 */
      __pyx_6 = (__pyx_v_keepUpositive == 1);
      if (__pyx_6) {
        __pyx_6 = (__pyx_v_tmpu < 0.0);
      }
      if (__pyx_6) {
        __pyx_v_tmpu = 0.0;
        goto __pyx_L15;
      }
      __pyx_L15:;

      /* "/home/alex/workspace/flix/src/svd.pyx":1235
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0             # <<<<<<<<<<<<<<
 * 				U[uid,k] = tmpu
 * 				M[mid,k] = tmpm
 */
      __pyx_6 = (__pyx_v_keepMpositive == 1);
      if (__pyx_6) {
        __pyx_6 = (__pyx_v_tmpm < 0.0);
      }
      if (__pyx_6) {
        __pyx_v_tmpm = 0.0;
        goto __pyx_L16;
      }
      __pyx_L16:;

      /* "/home/alex/workspace/flix/src/svd.pyx":1236
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu             # <<<<<<<<<<<<<<
 * 				M[mid,k] = tmpm
 * 
 */
      __pyx_t_29 = __pyx_v_uid;
      __pyx_t_30 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_29, __pyx_bstride_0_U, __pyx_t_30, __pyx_bstride_1_U) = __pyx_v_tmpu;

      /* "/home/alex/workspace/flix/src/svd.pyx":1237
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu
 * 				M[mid,k] = tmpm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
      __pyx_t_31 = __pyx_v_mid;
      __pyx_t_32 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_31, __pyx_bstride_0_M, __pyx_t_32, __pyx_bstride_1_M) = __pyx_v_tmpm;
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1239
 * 				M[mid,k] = tmpm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 	@cython.boundscheck(False)
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_7);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.bpmf");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1242
 * 
 * 	@cython.boundscheck(False)
 * 	def pmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Positive matrix factorization.
 */

static PyObject *__pyx_pf_3svd_3SVD_pmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_pmf[] = "Positive matrix factorization.\n\t\tKeep either user and movie features positive, depending on if\n\t\tkeepUpositive and keepMpositive are 1 or 0.";
static PyMethodDef __pyx_mdef_3svd_3SVD_pmf = {"pmf", (PyCFunction)__pyx_pf_3svd_3SVD_pmf, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_pmf};
static PyObject *__pyx_pf_3svd_3SVD_pmf(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyArrayObject *__pyx_v_U = 0;
  PyArrayObject *__pyx_v_M = 0;
  PyArrayObject *__pyx_v_userRatings = 0;
  PyArrayObject *__pyx_v_userIDsForUsers = 0;
  PyArrayObject *__pyx_v_movieIDs = 0;
  unsigned int __pyx_v_i;
  unsigned int __pyx_v_k;
  unsigned int __pyx_v_uid;
  unsigned int __pyx_v_mid;
  float __pyx_v_error;
  float __pyx_v_prediction;
  float __pyx_v_uf;
  float __pyx_v_mf;
  float __pyx_v_tmpm;
  float __pyx_v_tmpu;
  unsigned int __pyx_v_numratings;
  unsigned int __pyx_v_numfeatures;
  int __pyx_v_keepUpositive;
  int __pyx_v_keepMpositive;
  float __pyx_v_lrateU;
  float __pyx_v_lrateM;
  float __pyx_v_dampfactU;
  float __pyx_v_dampfactM;
  Py_buffer __pyx_bstruct_movieIDs;
  Py_ssize_t __pyx_bstride_0_movieIDs = 0;
  Py_ssize_t __pyx_bshape_0_movieIDs = 0;
  Py_buffer __pyx_bstruct_userRatings;
  Py_ssize_t __pyx_bstride_0_userRatings = 0;
  Py_ssize_t __pyx_bshape_0_userRatings = 0;
  Py_buffer __pyx_bstruct_userIDsForUsers;
  Py_ssize_t __pyx_bstride_0_userIDsForUsers = 0;
  Py_ssize_t __pyx_bshape_0_userIDsForUsers = 0;
  Py_buffer __pyx_bstruct_M;
  Py_ssize_t __pyx_bstride_0_M = 0;
  Py_ssize_t __pyx_bstride_1_M = 0;
  Py_ssize_t __pyx_bshape_0_M = 0;
  Py_ssize_t __pyx_bshape_1_M = 0;
  Py_buffer __pyx_bstruct_U;
  Py_ssize_t __pyx_bstride_0_U = 0;
  Py_ssize_t __pyx_bstride_1_U = 0;
  Py_ssize_t __pyx_bshape_0_U = 0;
  Py_ssize_t __pyx_bshape_1_U = 0;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  unsigned int __pyx_3;
  int __pyx_4;
  float __pyx_5;
  int __pyx_6;
  PyObject *__pyx_7 = 0;
  PyObject *__pyx_t_1 = NULL;
  unsigned int __pyx_t_2;
  unsigned int __pyx_t_3;
  unsigned int __pyx_t_4;
  unsigned int __pyx_t_5;
  unsigned int __pyx_t_6;
  unsigned int __pyx_t_7;
  unsigned int __pyx_t_8;
  unsigned int __pyx_t_9;
  unsigned int __pyx_t_10;
  unsigned int __pyx_t_11;
  unsigned int __pyx_t_12;
  unsigned int __pyx_t_13;
  unsigned int __pyx_t_14;
  unsigned int __pyx_t_15;
  unsigned int __pyx_t_16;
  unsigned int __pyx_t_17;
  unsigned int __pyx_t_18;
  unsigned int __pyx_t_19;
  unsigned int __pyx_t_20;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_U,&__pyx_kp_M,&__pyx_kp_userRatings,&__pyx_kp_userIDsForUsers,&__pyx_kp_movieIDs,0};
  __pyx_self = __pyx_self;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[6] = {0,0,0,0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
      case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
      case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
      case  1:
      values[1] = PyDict_GetItem(__pyx_kwds, __pyx_kp_U);
      if (likely(values[1])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, 1); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  2:
      values[2] = PyDict_GetItem(__pyx_kwds, __pyx_kp_M);
      if (likely(values[2])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, 2); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  3:
      values[3] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userRatings);
      if (likely(values[3])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, 3); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  4:
      values[4] = PyDict_GetItem(__pyx_kwds, __pyx_kp_userIDsForUsers);
      if (likely(values[4])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, 4); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
      case  5:
      values[5] = PyDict_GetItem(__pyx_kwds, __pyx_kp_movieIDs);
      if (likely(values[5])) kw_args--;
      else {
        __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, 5); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
      }
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "pmf") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    __pyx_v_U = ((PyArrayObject *)values[1]);
    __pyx_v_M = ((PyArrayObject *)values[2]);
    __pyx_v_userRatings = ((PyArrayObject *)values[3]);
    __pyx_v_userIDsForUsers = ((PyArrayObject *)values[4]);
    __pyx_v_movieIDs = ((PyArrayObject *)values[5]);
  } else if (PyTuple_GET_SIZE(__pyx_args) != 6) {
    goto __pyx_L5_argtuple_error;
  } else {
    __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
    __pyx_v_U = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 1));
    __pyx_v_M = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 2));
    __pyx_v_userRatings = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 3));
    __pyx_v_userIDsForUsers = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 4));
    __pyx_v_movieIDs = ((PyArrayObject *)PyTuple_GET_ITEM(__pyx_args, 5));
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("pmf", 1, 6, 6, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.pmf");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_bstruct_U.buf = NULL;
  __pyx_bstruct_M.buf = NULL;
  __pyx_bstruct_userRatings.buf = NULL;
  __pyx_bstruct_userIDsForUsers.buf = NULL;
  __pyx_bstruct_movieIDs.buf = NULL;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_U), __pyx_ptype_5numpy_ndarray, 1, "U", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_M), __pyx_ptype_5numpy_ndarray, 1, "M", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userRatings), __pyx_ptype_5numpy_ndarray, 1, "userRatings", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_userIDsForUsers), __pyx_ptype_5numpy_ndarray, 1, "userIDsForUsers", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_movieIDs), __pyx_ptype_5numpy_ndarray, 1, "movieIDs", 0))) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1243; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_U, &__pyx_bstruct_U, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_U = __pyx_bstruct_U.strides[0]; __pyx_bstride_1_U = __pyx_bstruct_U.strides[1];
  __pyx_bshape_0_U = __pyx_bstruct_U.shape[0]; __pyx_bshape_1_U = __pyx_bstruct_U.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_f32_t((PyObject*)__pyx_v_M, &__pyx_bstruct_M, PyBUF_FORMAT| PyBUF_STRIDES| PyBUF_WRITABLE, 2, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_M = __pyx_bstruct_M.strides[0]; __pyx_bstride_1_M = __pyx_bstruct_M.strides[1];
  __pyx_bshape_0_M = __pyx_bstruct_M.shape[0]; __pyx_bshape_1_M = __pyx_bstruct_M.shape[1];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i8_t((PyObject*)__pyx_v_userRatings, &__pyx_bstruct_userRatings, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userRatings = __pyx_bstruct_userRatings.strides[0];
  __pyx_bshape_0_userRatings = __pyx_bstruct_userRatings.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i32_t((PyObject*)__pyx_v_userIDsForUsers, &__pyx_bstruct_userIDsForUsers, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.strides[0];
  __pyx_bshape_0_userIDsForUsers = __pyx_bstruct_userIDsForUsers.shape[0];
  if (unlikely(__Pyx_GetBuffer_nn___pyx_t_3svd_i16_t((PyObject*)__pyx_v_movieIDs, &__pyx_bstruct_movieIDs, PyBUF_FORMAT| PyBUF_STRIDES, 1, 0) == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_bstride_0_movieIDs = __pyx_bstruct_movieIDs.strides[0];
  __pyx_bshape_0_movieIDs = __pyx_bstruct_movieIDs.shape[0];

  /* "/home/alex/workspace/flix/src/svd.pyx":1250
 * 		cdef float error, prediction, uf, mf, biasreg, tmpm, tmpu
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings             # <<<<<<<<<<<<<<
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_2); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1250; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_numratings = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1251
 * 
 * 		cdef unsigned int numratings = <unsigned int>self.fd.numratings
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures             # <<<<<<<<<<<<<<
 * 
 * 		cdef int keepUpositive = self.keepUpositive
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numfeatures); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = PyInt_AsUnsignedLongMask(__pyx_1); if (unlikely((__pyx_3 == (unsigned int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1251; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_numfeatures = ((unsigned int)__pyx_3);

  /* "/home/alex/workspace/flix/src/svd.pyx":1253
 * 		cdef unsigned int numfeatures = <unsigned int>self.numfeatures
 * 
 * 		cdef int keepUpositive = self.keepUpositive             # <<<<<<<<<<<<<<
 * 		cdef int keepMpositive = self.keepMpositive
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_keepUpositive); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyInt_int(__pyx_2); if (unlikely((__pyx_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1253; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_keepUpositive = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1254
 * 
 * 		cdef int keepUpositive = self.keepUpositive
 * 		cdef int keepMpositive = self.keepMpositive             # <<<<<<<<<<<<<<
 * 
 * 		cdef float lrateU = self.lrateU
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_keepMpositive); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __pyx_PyInt_int(__pyx_1); if (unlikely((__pyx_4 == (int)-1) && PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1254; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_keepMpositive = __pyx_4;

  /* "/home/alex/workspace/flix/src/svd.pyx":1256
 * 		cdef int keepMpositive = self.keepMpositive
 * 
 * 		cdef float lrateU = self.lrateU             # <<<<<<<<<<<<<<
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1256; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_lrateU = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1257
 * 
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM             # <<<<<<<<<<<<<<
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_lrateM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1257; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_lrateM = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1258
 * 		cdef float lrateU = self.lrateU
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU             # <<<<<<<<<<<<<<
 * 		cdef float dampfactM = self.dampfactM
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactU); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_2); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1258; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_v_dampfactU = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1259
 * 		cdef float lrateM = self.lrateM
 * 		cdef float dampfactU = self.dampfactU
 * 		cdef float dampfactM = self.dampfactM             # <<<<<<<<<<<<<<
 * 
 * 		for i from 0 <= i < (numratings):
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_dampfactM); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = __pyx_PyFloat_AsDouble(__pyx_1); if (unlikely(PyErr_Occurred())) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1259; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_v_dampfactM = __pyx_5;

  /* "/home/alex/workspace/flix/src/svd.pyx":1261
 * 		cdef float dampfactM = self.dampfactM
 * 
 * 		for i from 0 <= i < (numratings):             # <<<<<<<<<<<<<<
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 */
  for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_numratings; __pyx_v_i++) {

    /* "/home/alex/workspace/flix/src/svd.pyx":1262
 * 
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)             # <<<<<<<<<<<<<<
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]
 */
    __pyx_6 = ((__pyx_v_i % 10000000) == 0);
    if (__pyx_6) {
      __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_updateLog); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_1 = PyLong_FromUnsignedLong(__pyx_v_i); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_158, __pyx_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_1); __pyx_1 = 0;
      __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_7 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1262; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
      Py_DECREF(__pyx_7); __pyx_7 = 0;
      goto __pyx_L8;
    }
    __pyx_L8:;

    /* "/home/alex/workspace/flix/src/svd.pyx":1263
 * 		for i from 0 <= i < (numratings):
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]             # <<<<<<<<<<<<<<
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 */
    __pyx_t_2 = __pyx_v_i;
    __pyx_v_uid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i32_t *, __pyx_bstruct_userIDsForUsers.buf, __pyx_t_2, __pyx_bstride_0_userIDsForUsers)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1264
 * 			if i % 10000000 == 0: self.updateLog('\tTraining rating %d' % i)
 * 			uid = <unsigned int>userIDsForUsers[i]
 * 			mid = <unsigned int>movieIDs[i]             # <<<<<<<<<<<<<<
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 */
    __pyx_t_3 = __pyx_v_i;
    __pyx_v_mid = ((unsigned int)(*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i16_t *, __pyx_bstruct_movieIDs.buf, __pyx_t_3, __pyx_bstride_0_movieIDs)));

    /* "/home/alex/workspace/flix/src/svd.pyx":1266
 * 			mid = <unsigned int>movieIDs[i]
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0             # <<<<<<<<<<<<<<
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 */
    __pyx_v_prediction = 0.0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1267
 * 			# Find errors and predictions, before we do any updates
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1268
 * 			prediction = 0.0
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]             # <<<<<<<<<<<<<<
 * 			error = userRatings[i] - prediction
 * 
 */
      __pyx_t_4 = __pyx_v_uid;
      __pyx_t_5 = __pyx_v_k;
      __pyx_t_6 = __pyx_v_mid;
      __pyx_t_7 = __pyx_v_k;
      __pyx_v_prediction += ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_4, __pyx_bstride_0_U, __pyx_t_5, __pyx_bstride_1_U)) * (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_6, __pyx_bstride_0_M, __pyx_t_7, __pyx_bstride_1_M)));
    }

    /* "/home/alex/workspace/flix/src/svd.pyx":1269
 * 			for k from 0 <= k < numfeatures:
 * 				prediction += U[uid,k]*M[mid,k]
 * 			error = userRatings[i] - prediction             # <<<<<<<<<<<<<<
 * 
 * 			# Update non-bias features
 */
    __pyx_t_8 = __pyx_v_i;
    __pyx_v_error = ((*__Pyx_BufPtrStrided1d(__pyx_t_3svd_i8_t *, __pyx_bstruct_userRatings.buf, __pyx_t_8, __pyx_bstride_0_userRatings)) - __pyx_v_prediction);

    /* "/home/alex/workspace/flix/src/svd.pyx":1272
 * 
 * 			# Update non-bias features
 * 			for k from 0  <= k < numfeatures:             # <<<<<<<<<<<<<<
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 */
    for (__pyx_v_k = 0; __pyx_v_k < __pyx_v_numfeatures; __pyx_v_k++) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1273
 * 			# Update non-bias features
 * 			for k from 0  <= k < numfeatures:
 * 				uf = U[uid,k]             # <<<<<<<<<<<<<<
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 */
      __pyx_t_9 = __pyx_v_uid;
      __pyx_t_10 = __pyx_v_k;
      __pyx_v_uf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_9, __pyx_bstride_0_U, __pyx_t_10, __pyx_bstride_1_U));

      /* "/home/alex/workspace/flix/src/svd.pyx":1274
 * 			for k from 0  <= k < numfeatures:
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]             # <<<<<<<<<<<<<<
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 */
      __pyx_t_11 = __pyx_v_mid;
      __pyx_t_12 = __pyx_v_k;
      __pyx_v_mf = (*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_11, __pyx_bstride_0_M, __pyx_t_12, __pyx_bstride_1_M));

      /* "/home/alex/workspace/flix/src/svd.pyx":1275
 * 				uf = U[uid,k]
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)             # <<<<<<<<<<<<<<
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 */
      __pyx_t_13 = __pyx_v_uid;
      __pyx_t_14 = __pyx_v_k;
      __pyx_v_tmpu = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_13, __pyx_bstride_0_U, __pyx_t_14, __pyx_bstride_1_U)) + (__pyx_v_lrateU * ((__pyx_v_error * __pyx_v_mf) - (__pyx_v_dampfactU * __pyx_v_uf))));

      /* "/home/alex/workspace/flix/src/svd.pyx":1276
 * 				mf = M[mid,k]
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)             # <<<<<<<<<<<<<<
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 */
      __pyx_t_15 = __pyx_v_mid;
      __pyx_t_16 = __pyx_v_k;
      __pyx_v_tmpm = ((*__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_15, __pyx_bstride_0_M, __pyx_t_16, __pyx_bstride_1_M)) + (__pyx_v_lrateM * ((__pyx_v_error * __pyx_v_uf) - (__pyx_v_dampfactM * __pyx_v_mf))));

      /* "/home/alex/workspace/flix/src/svd.pyx":1277
 * 				tmpu = U[uid,k] + lrateU*(error*mf - dampfactU*uf)
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0             # <<<<<<<<<<<<<<
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu
 */
      __pyx_6 = (__pyx_v_keepUpositive == 1);
      if (__pyx_6) {
        __pyx_6 = (__pyx_v_tmpu < 0.0);
      }
      if (__pyx_6) {
        __pyx_v_tmpu = 0.0;
        goto __pyx_L13;
      }
      __pyx_L13:;

      /* "/home/alex/workspace/flix/src/svd.pyx":1278
 * 				tmpm = M[mid,k] + lrateM*(error*uf - dampfactM*mf)
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0             # <<<<<<<<<<<<<<
 * 				U[uid,k] = tmpu
 * 				M[mid,k] = tmpm
 */
      __pyx_6 = (__pyx_v_keepMpositive == 1);
      if (__pyx_6) {
        __pyx_6 = (__pyx_v_tmpm < 0.0);
      }
      if (__pyx_6) {
        __pyx_v_tmpm = 0.0;
        goto __pyx_L14;
      }
      __pyx_L14:;

      /* "/home/alex/workspace/flix/src/svd.pyx":1279
 * 				if keepUpositive == 1 and tmpu < 0.0: tmpu = 0.0
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu             # <<<<<<<<<<<<<<
 * 				M[mid,k] = tmpm
 * 
 */
      __pyx_t_17 = __pyx_v_uid;
      __pyx_t_18 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_U.buf, __pyx_t_17, __pyx_bstride_0_U, __pyx_t_18, __pyx_bstride_1_U) = __pyx_v_tmpu;

      /* "/home/alex/workspace/flix/src/svd.pyx":1280
 * 				if keepMpositive == 1 and tmpm < 0.0: tmpm = 0.0
 * 				U[uid,k] = tmpu
 * 				M[mid,k] = tmpm             # <<<<<<<<<<<<<<
 * 
 * 		return
 */
      __pyx_t_19 = __pyx_v_mid;
      __pyx_t_20 = __pyx_v_k;
      *__Pyx_BufPtrStrided2d(__pyx_t_3svd_f32_t *, __pyx_bstruct_M.buf, __pyx_t_19, __pyx_bstride_0_M, __pyx_t_20, __pyx_bstride_1_M) = __pyx_v_tmpm;
    }
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1282
 * 				M[mid,k] = tmpm
 * 
 * 		return             # <<<<<<<<<<<<<<
 * 
 * 	def subsampleUsers(self, fraction=0.3):
 */
  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_7);
  { PyObject *__pyx_type, *__pyx_value, *__pyx_tb;
    __Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
    __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}
  __Pyx_AddTraceback("svd.SVD.pmf");
  __pyx_r = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_movieIDs);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userRatings);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_userIDsForUsers);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_M);
  __Pyx_SafeReleaseBuffer(&__pyx_bstruct_U);
  __pyx_L2:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1284
 * 		return
 * 
 * 	def subsampleUsers(self, fraction=0.3):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Update the svd model to use only a subsample of users
 */

static PyObject *__pyx_pf_3svd_3SVD_subsampleUsers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_3SVD_subsampleUsers[] = "\n\t\tUpdate the svd model to use only a subsample of users\n\t\t\n\t\tCAUSES A SEGMENTATION FAULT AFTER THE ALLOTED NUMBER\n\t\t";
static PyMethodDef __pyx_mdef_3svd_3SVD_subsampleUsers = {"subsampleUsers", (PyCFunction)__pyx_pf_3svd_3SVD_subsampleUsers, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_3SVD_subsampleUsers};
static PyObject *__pyx_pf_3svd_3SVD_subsampleUsers(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_self = 0;
  PyObject *__pyx_v_fraction = 0;
  PyObject *__pyx_v_newnumusers;
  PyObject *__pyx_v_done;
  PyObject *__pyx_v_numproberatings;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  int __pyx_3;
  PyObject *__pyx_4 = 0;
  Py_ssize_t __pyx_5 = 0;
  PyObject *__pyx_t_1 = NULL;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_self,&__pyx_kp_fraction,0};
  __pyx_self = __pyx_self;
  __pyx_v_fraction = __pyx_k_33;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[2] = {0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_self);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "subsampleUsers") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_self = values[0];
    if (values[1]) {
      __pyx_v_fraction = values[1];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  2: __pyx_v_fraction = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: __pyx_v_self = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("subsampleUsers", 0, 1, 2, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.SVD.subsampleUsers");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_newnumusers = Py_None; Py_INCREF(Py_None);
  __pyx_v_done = Py_None; Py_INCREF(Py_None);
  __pyx_v_numproberatings = Py_None; Py_INCREF(Py_None);

  /* "/home/alex/workspace/flix/src/svd.pyx":1290
 * 		CAUSES A SEGMENTATION FAULT AFTER THE ALLOTED NUMBER
 * 		"""
 * 		newnumusers = int(480189*fraction)             # <<<<<<<<<<<<<<
 * 
 * 		# Make sure that the last user is in the probe set.
 */
  __pyx_t_1 = PyNumber_Multiply(__pyx_int_480189, __pyx_v_fraction); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyTuple_New(1); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_1, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_2 = PyObject_Call(((PyObject *)((PyObject*)&PyInt_Type)), ((PyObject *)__pyx_1), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1290; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  Py_DECREF(__pyx_v_newnumusers);
  __pyx_v_newnumusers = __pyx_2;
  __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1293
 * 
 * 		# Make sure that the last user is in the probe set.
 * 		done = False             # <<<<<<<<<<<<<<
 * 		while done is False:
 * 			numproberatings = N.argwhere(self.td.userIDsForUsers==newnumusers)
 */
  __pyx_1 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1293; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_done);
  __pyx_v_done = __pyx_1;
  __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1294
 * 		# Make sure that the last user is in the probe set.
 * 		done = False
 * 		while done is False:             # <<<<<<<<<<<<<<
 * 			numproberatings = N.argwhere(self.td.userIDsForUsers==newnumusers)
 * 			if len(numproberatings) == 0:
 */
  while (1) {
    __pyx_2 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1294; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = (__pyx_v_done == __pyx_2);
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    if (!__pyx_3) break;

    /* "/home/alex/workspace/flix/src/svd.pyx":1295
 * 		done = False
 * 		while done is False:
 * 			numproberatings = N.argwhere(self.td.userIDsForUsers==newnumusers)             # <<<<<<<<<<<<<<
 * 			if len(numproberatings) == 0:
 * 				newnumusers += 1
 */
    __pyx_1 = __Pyx_GetName(__pyx_m, __pyx_kp_N); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_argwhere); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_4 = PyObject_GetAttr(__pyx_1, __pyx_kp_userIDsForUsers); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_1); __pyx_1 = 0;
    __pyx_1 = PyObject_RichCompare(__pyx_4, __pyx_v_newnumusers, Py_EQ); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_4); __pyx_4 = 0;
    __pyx_4 = PyTuple_New(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyTuple_SET_ITEM(__pyx_4, 0, __pyx_1);
    __pyx_1 = 0;
    __pyx_1 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_4), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1295; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    Py_DECREF(((PyObject *)__pyx_4)); __pyx_4 = 0;
    Py_DECREF(__pyx_v_numproberatings);
    __pyx_v_numproberatings = __pyx_1;
    __pyx_1 = 0;

    /* "/home/alex/workspace/flix/src/svd.pyx":1296
 * 		while done is False:
 * 			numproberatings = N.argwhere(self.td.userIDsForUsers==newnumusers)
 * 			if len(numproberatings) == 0:             # <<<<<<<<<<<<<<
 * 				newnumusers += 1
 * 			else:
 */
    __pyx_5 = PyObject_Length(__pyx_v_numproberatings); if (unlikely(__pyx_5 == -1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1296; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_3 = (__pyx_5 == 0);
    if (__pyx_3) {

      /* "/home/alex/workspace/flix/src/svd.pyx":1297
 * 			numproberatings = N.argwhere(self.td.userIDsForUsers==newnumusers)
 * 			if len(numproberatings) == 0:
 * 				newnumusers += 1             # <<<<<<<<<<<<<<
 * 			else:
 * 				done = True
 */
      __pyx_2 = PyNumber_InPlaceAdd(__pyx_v_newnumusers, __pyx_int_1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_v_newnumusers);
      __pyx_v_newnumusers = __pyx_2;
      __pyx_2 = 0;
      goto __pyx_L8;
    }
    /*else*/ {

      /* "/home/alex/workspace/flix/src/svd.pyx":1299
 * 				newnumusers += 1
 * 			else:
 * 				done = True             # <<<<<<<<<<<<<<
 * 
 * 
 */
      __pyx_4 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1299; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_v_done);
      __pyx_v_done = __pyx_4;
      __pyx_4 = 0;
    }
    __pyx_L8:;
  }

  /* "/home/alex/workspace/flix/src/svd.pyx":1302
 * 
 * 
 * 		self.numusers = newnumusers             # <<<<<<<<<<<<<<
 * 		self.fd.numusers = newnumusers
 * 		numproberatings = numproberatings[0][0] # make it just an integer
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numusers, __pyx_v_newnumusers) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1302; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":1303
 * 
 * 		self.numusers = newnumusers
 * 		self.fd.numusers = newnumusers             # <<<<<<<<<<<<<<
 * 		numproberatings = numproberatings[0][0] # make it just an integer
 * 		self.td.numratings = numproberatings
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_1, __pyx_kp_numusers, __pyx_v_newnumusers) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1303; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1304
 * 		self.numusers = newnumusers
 * 		self.fd.numusers = newnumusers
 * 		numproberatings = numproberatings[0][0] # make it just an integer             # <<<<<<<<<<<<<<
 * 		self.td.numratings = numproberatings
 * 		self.fd.numratings = self.fd.userIndex[self.numusers-1,1]
 */
  __pyx_2 = __Pyx_GetItemInt(__pyx_v_numproberatings, 0, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = __Pyx_GetItemInt(__pyx_2, 0, 0); if (!__pyx_4) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1304; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  Py_DECREF(__pyx_v_numproberatings);
  __pyx_v_numproberatings = __pyx_4;
  __pyx_4 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1305
 * 		self.fd.numusers = newnumusers
 * 		numproberatings = numproberatings[0][0] # make it just an integer
 * 		self.td.numratings = numproberatings             # <<<<<<<<<<<<<<
 * 		self.fd.numratings = self.fd.userIndex[self.numusers-1,1]
 * 		self.numratings = self.fd.numratings
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_1, __pyx_kp_numratings, __pyx_v_numproberatings) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1305; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1306
 * 		numproberatings = numproberatings[0][0] # make it just an integer
 * 		self.td.numratings = numproberatings
 * 		self.fd.numratings = self.fd.userIndex[self.numusers-1,1]             # <<<<<<<<<<<<<<
 * 		self.numratings = self.fd.numratings
 * 
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyObject_GetAttr(__pyx_2, __pyx_kp_userIndex); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_numusers); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_t_1 = PyNumber_Subtract(__pyx_1, __pyx_int_1); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_t_1);
  Py_INCREF(__pyx_int_1);
  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_int_1);
  __pyx_t_1 = 0;
  __pyx_1 = PyObject_GetItem(__pyx_4, ((PyObject *)__pyx_2)); if (!__pyx_1) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  __pyx_4 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_4, __pyx_kp_numratings, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1306; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_4); __pyx_4 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1307
 * 		self.td.numratings = numproberatings
 * 		self.fd.numratings = self.fd.userIndex[self.numusers-1,1]
 * 		self.numratings = self.fd.numratings             # <<<<<<<<<<<<<<
 * 
 * 	def restoreFromSubsample(self):
 */
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_numratings); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numratings, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1307; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_4);
  __Pyx_AddTraceback("svd.SVD.subsampleUsers");
  __pyx_r = NULL;
  __pyx_L0:;
  Py_DECREF(__pyx_v_newnumusers);
  Py_DECREF(__pyx_v_done);
  Py_DECREF(__pyx_v_numproberatings);
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1309
 * 		self.numratings = self.fd.numratings
 * 
 * 	def restoreFromSubsample(self):             # <<<<<<<<<<<<<<
 * 		self.numusers = 480189
 * 		self.fd.numusers = 480189
 */

static PyObject *__pyx_pf_3svd_3SVD_restoreFromSubsample(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
static PyMethodDef __pyx_mdef_3svd_3SVD_restoreFromSubsample = {"restoreFromSubsample", (PyCFunction)__pyx_pf_3svd_3SVD_restoreFromSubsample, METH_O, 0};
static PyObject *__pyx_pf_3svd_3SVD_restoreFromSubsample(PyObject *__pyx_self, PyObject *__pyx_v_self) {
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  __pyx_self = __pyx_self;

  /* "/home/alex/workspace/flix/src/svd.pyx":1310
 * 
 * 	def restoreFromSubsample(self):
 * 		self.numusers = 480189             # <<<<<<<<<<<<<<
 * 		self.fd.numusers = 480189
 * 		self.td.numratings = self.td.userRatings.size
 */
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numusers, __pyx_int_480189) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1310; __pyx_clineno = __LINE__; goto __pyx_L1_error;}

  /* "/home/alex/workspace/flix/src/svd.pyx":1311
 * 	def restoreFromSubsample(self):
 * 		self.numusers = 480189
 * 		self.fd.numusers = 480189             # <<<<<<<<<<<<<<
 * 		self.td.numratings = self.td.userRatings.size
 * 		self.fd.numratings = self.fd.userRatings.size
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_1, __pyx_kp_numusers, __pyx_int_480189) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1311; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1312
 * 		self.numusers = 480189
 * 		self.fd.numusers = 480189
 * 		self.td.numratings = self.td.userRatings.size             # <<<<<<<<<<<<<<
 * 		self.fd.numratings = self.fd.userRatings.size
 * 		self.numratings = self.fd.numratings
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_userRatings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_size); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_td); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_2, __pyx_kp_numratings, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1312; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1313
 * 		self.fd.numusers = 480189
 * 		self.td.numratings = self.td.userRatings.size
 * 		self.fd.numratings = self.fd.userRatings.size             # <<<<<<<<<<<<<<
 * 		self.numratings = self.fd.numratings
 * 
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_userRatings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_size); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  __pyx_2 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_2, __pyx_kp_numratings, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1313; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1314
 * 		self.td.numratings = self.td.userRatings.size
 * 		self.fd.numratings = self.fd.userRatings.size
 * 		self.numratings = self.fd.numratings             # <<<<<<<<<<<<<<
 * 
 * 	# cdef inline the update equations--
 */
  __pyx_1 = PyObject_GetAttr(__pyx_v_self, __pyx_kp_fd); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyObject_GetAttr(__pyx_1, __pyx_kp_numratings); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;
  if (PyObject_SetAttr(__pyx_v_self, __pyx_kp_numratings, __pyx_2) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1314; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  __Pyx_AddTraceback("svd.SVD.restoreFromSubsample");
  __pyx_r = NULL;
  __pyx_L0:;
  return __pyx_r;
}

/* "/home/alex/workspace/flix/src/svd.pyx":1321
 * # END OF SVD CLASS
 * 
 * def loadModel(modelname, loadarrays=False, resultdir='/home/alex/workspace/flix/results/'):             # <<<<<<<<<<<<<<
 * 	"""
 * 	Make an instance of the SVD class using information from the logfile
 */

static PyObject *__pyx_pf_3svd_loadModel(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_3svd_loadModel[] = "\n\tMake an instance of the SVD class using information from the logfile\n\t\n\tNOT DONE\n\t";
static PyObject *__pyx_pf_3svd_loadModel(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_modelname = 0;
  PyObject *__pyx_v_loadarrays = 0;
  PyObject *__pyx_v_resultdir = 0;
  PyObject *__pyx_v_join;
  PyObject *__pyx_v_chdir;
  PyObject *__pyx_v_modeldir;
  PyObject *__pyx_r;
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  static PyObject **__pyx_pyargnames[] = {&__pyx_kp_modelname,&__pyx_kp_loadarrays,&__pyx_kp_resultdir,0};
  __pyx_self = __pyx_self;
  __pyx_v_loadarrays = __pyx_k_35;
  __pyx_v_resultdir = __pyx_kp_36;
  if (unlikely(__pyx_kwds)) {
    PyObject* values[3] = {0,0,0};
    Py_ssize_t kw_args = PyDict_Size(__pyx_kwds);
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      case  0: break;
      default: goto __pyx_L5_argtuple_error;
    }
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  0:
      values[0] = PyDict_GetItem(__pyx_kwds, __pyx_kp_modelname);
      if (likely(values[0])) kw_args--;
      else goto __pyx_L5_argtuple_error;
    }
    if (unlikely(kw_args > 0)) {
      if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, PyTuple_GET_SIZE(__pyx_args), "loadModel") < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
    }
    __pyx_v_modelname = values[0];
    if (values[1]) {
      __pyx_v_loadarrays = values[1];
    }
    if (values[2]) {
      __pyx_v_resultdir = values[2];
    }
  } else {
    switch (PyTuple_GET_SIZE(__pyx_args)) {
      case  3: __pyx_v_resultdir = PyTuple_GET_ITEM(__pyx_args, 2);
      case  2: __pyx_v_loadarrays = PyTuple_GET_ITEM(__pyx_args, 1);
      case  1: __pyx_v_modelname = PyTuple_GET_ITEM(__pyx_args, 0);
      break;
      default: goto __pyx_L5_argtuple_error;
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("loadModel", 0, 1, 3, PyTuple_GET_SIZE(__pyx_args)); {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1321; __pyx_clineno = __LINE__; goto __pyx_L3_error;}
  __pyx_L3_error:;
  __Pyx_AddTraceback("svd.loadModel");
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_v_join = Py_None; Py_INCREF(Py_None);
  __pyx_v_chdir = Py_None; Py_INCREF(Py_None);
  __pyx_v_modeldir = Py_None; Py_INCREF(Py_None);

  /* "/home/alex/workspace/flix/src/svd.pyx":1327
 * 	NOT DONE
 * 	"""
 * 	from os import join, chdir             # <<<<<<<<<<<<<<
 * 	modeldir = join(resultdir, modelname)
 * 	pass
 */
  __pyx_1 = PyList_New(2); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_kp_join);
  PyList_SET_ITEM(__pyx_1, 0, __pyx_kp_join);
  Py_INCREF(__pyx_kp_chdir);
  PyList_SET_ITEM(__pyx_1, 1, __pyx_kp_chdir);
  __pyx_2 = __Pyx_Import(__pyx_kp_os, ((PyObject *)__pyx_1)); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_join); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_join);
  __pyx_v_join = __pyx_1;
  __pyx_1 = 0;
  __pyx_1 = PyObject_GetAttr(__pyx_2, __pyx_kp_chdir); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1327; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_v_chdir);
  __pyx_v_chdir = __pyx_1;
  __pyx_1 = 0;
  Py_DECREF(__pyx_2); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1328
 * 	"""
 * 	from os import join, chdir
 * 	modeldir = join(resultdir, modelname)             # <<<<<<<<<<<<<<
 * 	pass
 * 
 */
  __pyx_2 = PyTuple_New(2); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_v_resultdir);
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_v_resultdir);
  Py_INCREF(__pyx_v_modelname);
  PyTuple_SET_ITEM(__pyx_2, 1, __pyx_v_modelname);
  __pyx_1 = PyObject_Call(__pyx_v_join, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1328; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
  Py_DECREF(__pyx_v_modeldir);
  __pyx_v_modeldir = __pyx_1;
  __pyx_1 = 0;

  __pyx_r = Py_None; Py_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  __Pyx_AddTraceback("svd.loadModel");
  __pyx_r = NULL;
  __pyx_L0:;
  Py_DECREF(__pyx_v_join);
  Py_DECREF(__pyx_v_chdir);
  Py_DECREF(__pyx_v_modeldir);
  return __pyx_r;
}

/* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":50
 *         # experimental exception made for __getbuffer__ and __releasebuffer__
 *         # -- the details of this may change.
 *         def __getbuffer__(ndarray self, Py_buffer* info, int flags):             # <<<<<<<<<<<<<<
 *             # This implementation of getbuffer is geared towards Cython
 *             # requirements, and does not yet fullfill the PEP.
 */

static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags); /*proto*/
static int __pyx_pf_5numpy_7ndarray___getbuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info, int __pyx_v_flags) {
  int __pyx_v_copy_shape;
  int __pyx_v_i;
  int __pyx_v_ndim;
  int __pyx_v_t;
  char *__pyx_v_f;
  PyArray_Descr *__pyx_v_descr = 0;
  PyObject *__pyx_v_stack;
  int __pyx_v_hasfields;
  PyObject *__pyx_v_iterator;
  int __pyx_r;
  int __pyx_1;
  PyObject *__pyx_2 = 0;
  PyObject *__pyx_3 = 0;
  int __pyx_4;
  PyObject *__pyx_5 = 0;
  PyObject *__pyx_6 = 0;
  PyObject *__pyx_7 = 0;
  Py_ssize_t __pyx_8 = 0;
  PyObject *__pyx_t_1 = NULL;
  if (__pyx_v_info == NULL) return 0;
  __pyx_v_info->obj = Py_None; Py_INCREF(Py_None);
  __pyx_v_stack = ((PyObject *)Py_None); Py_INCREF(Py_None);
  __pyx_v_iterator = Py_None; Py_INCREF(Py_None);

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":56
 *             # of flags
 *             cdef int copy_shape, i, ndim
 *             ndim = PyArray_NDIM(self)             # <<<<<<<<<<<<<<
 * 
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
 */
  __pyx_v_ndim = PyArray_NDIM(((PyArrayObject *)__pyx_v_self));

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":58
 *             ndim = PyArray_NDIM(self)
 * 
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
 *                 copy_shape = 1
 *             else:
 */
  __pyx_1 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":59
 * 
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
 *                 copy_shape = 1             # <<<<<<<<<<<<<<
 *             else:
 *                 copy_shape = 0
 */
    __pyx_v_copy_shape = 1;
    goto __pyx_L5;
  }
  /*else*/ {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":61
 *                 copy_shape = 1
 *             else:
 *                 copy_shape = 0             # <<<<<<<<<<<<<<
 * 
 *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
 */
    __pyx_v_copy_shape = 0;
  }
  __pyx_L5:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":63
 *                 copy_shape = 0
 * 
 *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)             # <<<<<<<<<<<<<<
 *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
 *                 raise ValueError("ndarray is not C contiguous")
 */
  __pyx_1 = ((__pyx_v_flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS);
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":64
 * 
 *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
 *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):             # <<<<<<<<<<<<<<
 *                 raise ValueError("ndarray is not C contiguous")
 * 
 */
    __pyx_1 = (!PyArray_CHKFLAGS(((PyArrayObject *)__pyx_v_self), NPY_C_CONTIGUOUS));
  }
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":65
 *             if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
 *                 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
 *                 raise ValueError("ndarray is not C contiguous")             # <<<<<<<<<<<<<<
 * 
 *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
 */
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_1);
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_1);
    __pyx_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    __Pyx_Raise(__pyx_3, 0, 0);
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 65; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    goto __pyx_L6;
  }
  __pyx_L6:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":67
 *                 raise ValueError("ndarray is not C contiguous")
 * 
 *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)             # <<<<<<<<<<<<<<
 *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
 *                 raise ValueError("ndarray is not Fortran contiguous")
 */
  __pyx_1 = ((__pyx_v_flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS);
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":68
 * 
 *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
 *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):             # <<<<<<<<<<<<<<
 *                 raise ValueError("ndarray is not Fortran contiguous")
 * 
 */
    __pyx_1 = (!PyArray_CHKFLAGS(((PyArrayObject *)__pyx_v_self), NPY_F_CONTIGUOUS));
  }
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":69
 *             if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
 *                 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
 *                 raise ValueError("ndarray is not Fortran contiguous")             # <<<<<<<<<<<<<<
 * 
 *             info.buf = PyArray_DATA(self)
 */
    __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_INCREF(__pyx_kp_2);
    PyTuple_SET_ITEM(__pyx_2, 0, __pyx_kp_2);
    __pyx_3 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_2), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;
    __Pyx_Raise(__pyx_3, 0, 0);
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    {__pyx_filename = __pyx_f[1]; __pyx_lineno = 69; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    goto __pyx_L7;
  }
  __pyx_L7:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":71
 *                 raise ValueError("ndarray is not Fortran contiguous")
 * 
 *             info.buf = PyArray_DATA(self)             # <<<<<<<<<<<<<<
 *             info.ndim = ndim
 *             if copy_shape:
 */
  __pyx_v_info->buf = PyArray_DATA(((PyArrayObject *)__pyx_v_self));

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":72
 * 
 *             info.buf = PyArray_DATA(self)
 *             info.ndim = ndim             # <<<<<<<<<<<<<<
 *             if copy_shape:
 *                 # Allocate new buffer for strides and shape info. This is allocated
 */
  __pyx_v_info->ndim = __pyx_v_ndim;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":73
 *             info.buf = PyArray_DATA(self)
 *             info.ndim = ndim
 *             if copy_shape:             # <<<<<<<<<<<<<<
 *                 # Allocate new buffer for strides and shape info. This is allocated
 *                 # as one block, strides first.
 */
  __pyx_4 = __pyx_v_copy_shape;
  if (__pyx_4) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":76
 *                 # Allocate new buffer for strides and shape info. This is allocated
 *                 # as one block, strides first.
 *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2)             # <<<<<<<<<<<<<<
 *                 info.shape = info.strides + ndim
 *                 for i in range(ndim):
 */
    __pyx_v_info->strides = ((Py_ssize_t *)malloc((((sizeof(Py_ssize_t)) * __pyx_v_ndim) * 2)));

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":77
 *                 # as one block, strides first.
 *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2)
 *                 info.shape = info.strides + ndim             # <<<<<<<<<<<<<<
 *                 for i in range(ndim):
 *                     info.strides[i] = PyArray_STRIDES(self)[i]
 */
    __pyx_v_info->shape = (__pyx_v_info->strides + __pyx_v_ndim);

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":78
 *                 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2)
 *                 info.shape = info.strides + ndim
 *                 for i in range(ndim):             # <<<<<<<<<<<<<<
 *                     info.strides[i] = PyArray_STRIDES(self)[i]
 *                     info.shape[i] = PyArray_DIMS(self)[i]
 */
    for (__pyx_v_i = 0; __pyx_v_i < __pyx_v_ndim; __pyx_v_i+=1) {

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":79
 *                 info.shape = info.strides + ndim
 *                 for i in range(ndim):
 *                     info.strides[i] = PyArray_STRIDES(self)[i]             # <<<<<<<<<<<<<<
 *                     info.shape[i] = PyArray_DIMS(self)[i]
 *             else:
 */
      (__pyx_v_info->strides[__pyx_v_i]) = (PyArray_STRIDES(((PyArrayObject *)__pyx_v_self))[__pyx_v_i]);

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":80
 *                 for i in range(ndim):
 *                     info.strides[i] = PyArray_STRIDES(self)[i]
 *                     info.shape[i] = PyArray_DIMS(self)[i]             # <<<<<<<<<<<<<<
 *             else:
 *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
 */
      (__pyx_v_info->shape[__pyx_v_i]) = (PyArray_DIMS(((PyArrayObject *)__pyx_v_self))[__pyx_v_i]);
    }
    goto __pyx_L8;
  }
  /*else*/ {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":82
 *                     info.shape[i] = PyArray_DIMS(self)[i]
 *             else:
 *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)             # <<<<<<<<<<<<<<
 *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
 *             info.suboffsets = NULL
 */
    __pyx_v_info->strides = ((Py_ssize_t *)PyArray_STRIDES(((PyArrayObject *)__pyx_v_self)));

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":83
 *             else:
 *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
 *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)             # <<<<<<<<<<<<<<
 *             info.suboffsets = NULL
 *             info.itemsize = PyArray_ITEMSIZE(self)
 */
    __pyx_v_info->shape = ((Py_ssize_t *)PyArray_DIMS(((PyArrayObject *)__pyx_v_self)));
  }
  __pyx_L8:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":84
 *                 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
 *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
 *             info.suboffsets = NULL             # <<<<<<<<<<<<<<
 *             info.itemsize = PyArray_ITEMSIZE(self)
 *             info.readonly = not PyArray_ISWRITEABLE(self)
 */
  __pyx_v_info->suboffsets = NULL;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":85
 *                 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
 *             info.suboffsets = NULL
 *             info.itemsize = PyArray_ITEMSIZE(self)             # <<<<<<<<<<<<<<
 *             info.readonly = not PyArray_ISWRITEABLE(self)
 * 
 */
  __pyx_v_info->itemsize = PyArray_ITEMSIZE(((PyArrayObject *)__pyx_v_self));

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":86
 *             info.suboffsets = NULL
 *             info.itemsize = PyArray_ITEMSIZE(self)
 *             info.readonly = not PyArray_ISWRITEABLE(self)             # <<<<<<<<<<<<<<
 * 
 *             cdef int t
 */
  __pyx_v_info->readonly = (!PyArray_ISWRITEABLE(((PyArrayObject *)__pyx_v_self)));

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":89
 * 
 *             cdef int t
 *             cdef char* f = NULL             # <<<<<<<<<<<<<<
 *             cdef dtype descr = self.descr
 *             cdef list stack
 */
  __pyx_v_f = NULL;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":90
 *             cdef int t
 *             cdef char* f = NULL
 *             cdef dtype descr = self.descr             # <<<<<<<<<<<<<<
 *             cdef list stack
 * 
 */
  Py_INCREF(((PyObject *)((PyArrayObject *)__pyx_v_self)->descr));
  __pyx_v_descr = ((PyArrayObject *)__pyx_v_self)->descr;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":93
 *             cdef list stack
 * 
 *             cdef bint hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
 * 
 *             # Ugly hack warning:
 */
  __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":103
 *             # functions).
 * 
 *             if not hasfields and not copy_shape:             # <<<<<<<<<<<<<<
 *                 # do not call releasebuffer
 *                 info.obj = None
 */
  __pyx_1 = (!__pyx_v_hasfields);
  if (__pyx_1) {
    __pyx_1 = (!__pyx_v_copy_shape);
  }
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":105
 *             if not hasfields and not copy_shape:
 *                 # do not call releasebuffer
 *                 info.obj = None             # <<<<<<<<<<<<<<
 *             else:
 *                 # need to call releasebuffer
 */
    Py_INCREF(Py_None);
    Py_DECREF(__pyx_v_info->obj);
    __pyx_v_info->obj = Py_None;
    goto __pyx_L11;
  }
  /*else*/ {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":108
 *             else:
 *                 # need to call releasebuffer
 *                 info.obj = self             # <<<<<<<<<<<<<<
 * 
 *             if not hasfields:
 */
    Py_INCREF(__pyx_v_self);
    Py_DECREF(__pyx_v_info->obj);
    __pyx_v_info->obj = __pyx_v_self;
  }
  __pyx_L11:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":110
 *                 info.obj = self
 * 
 *             if not hasfields:             # <<<<<<<<<<<<<<
 *                 t = descr.type_num
 *                 if   t == NPY_BYTE:        f = "b"
 */
  __pyx_1 = (!__pyx_v_hasfields);
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":111
 * 
 *             if not hasfields:
 *                 t = descr.type_num             # <<<<<<<<<<<<<<
 *                 if   t == NPY_BYTE:        f = "b"
 *                 elif t == NPY_UBYTE:       f = "B"
 */
    __pyx_v_t = __pyx_v_descr->type_num;

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":112
 *             if not hasfields:
 *                 t = descr.type_num
 *                 if   t == NPY_BYTE:        f = "b"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_UBYTE:       f = "B"
 *                 elif t == NPY_SHORT:       f = "h"
 */
    switch (__pyx_v_t) {
      case NPY_BYTE:
      __pyx_v_f = __pyx_k_3;
      break;
      case NPY_UBYTE:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":113
 *                 t = descr.type_num
 *                 if   t == NPY_BYTE:        f = "b"
 *                 elif t == NPY_UBYTE:       f = "B"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_SHORT:       f = "h"
 *                 elif t == NPY_USHORT:      f = "H"
 */
      __pyx_v_f = __pyx_k_4;
      break;
      case NPY_SHORT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":114
 *                 if   t == NPY_BYTE:        f = "b"
 *                 elif t == NPY_UBYTE:       f = "B"
 *                 elif t == NPY_SHORT:       f = "h"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_USHORT:      f = "H"
 *                 elif t == NPY_INT:         f = "i"
 */
      __pyx_v_f = __pyx_k_5;
      break;
      case NPY_USHORT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":115
 *                 elif t == NPY_UBYTE:       f = "B"
 *                 elif t == NPY_SHORT:       f = "h"
 *                 elif t == NPY_USHORT:      f = "H"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_INT:         f = "i"
 *                 elif t == NPY_UINT:        f = "I"
 */
      __pyx_v_f = __pyx_k_6;
      break;
      case NPY_INT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":116
 *                 elif t == NPY_SHORT:       f = "h"
 *                 elif t == NPY_USHORT:      f = "H"
 *                 elif t == NPY_INT:         f = "i"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_UINT:        f = "I"
 *                 elif t == NPY_LONG:        f = "l"
 */
      __pyx_v_f = __pyx_k_7;
      break;
      case NPY_UINT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":117
 *                 elif t == NPY_USHORT:      f = "H"
 *                 elif t == NPY_INT:         f = "i"
 *                 elif t == NPY_UINT:        f = "I"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_LONG:        f = "l"
 *                 elif t == NPY_ULONG:       f = "L"
 */
      __pyx_v_f = __pyx_k_8;
      break;
      case NPY_LONG:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":118
 *                 elif t == NPY_INT:         f = "i"
 *                 elif t == NPY_UINT:        f = "I"
 *                 elif t == NPY_LONG:        f = "l"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_ULONG:       f = "L"
 *                 elif t == NPY_LONGLONG:    f = "q"
 */
      __pyx_v_f = __pyx_k_9;
      break;
      case NPY_ULONG:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":119
 *                 elif t == NPY_UINT:        f = "I"
 *                 elif t == NPY_LONG:        f = "l"
 *                 elif t == NPY_ULONG:       f = "L"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_LONGLONG:    f = "q"
 *                 elif t == NPY_ULONGLONG:   f = "Q"
 */
      __pyx_v_f = __pyx_k_10;
      break;
      case NPY_LONGLONG:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":120
 *                 elif t == NPY_LONG:        f = "l"
 *                 elif t == NPY_ULONG:       f = "L"
 *                 elif t == NPY_LONGLONG:    f = "q"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_ULONGLONG:   f = "Q"
 *                 elif t == NPY_FLOAT:       f = "f"
 */
      __pyx_v_f = __pyx_k_11;
      break;
      case NPY_ULONGLONG:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":121
 *                 elif t == NPY_ULONG:       f = "L"
 *                 elif t == NPY_LONGLONG:    f = "q"
 *                 elif t == NPY_ULONGLONG:   f = "Q"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_FLOAT:       f = "f"
 *                 elif t == NPY_DOUBLE:      f = "d"
 */
      __pyx_v_f = __pyx_k_12;
      break;
      case NPY_FLOAT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":122
 *                 elif t == NPY_LONGLONG:    f = "q"
 *                 elif t == NPY_ULONGLONG:   f = "Q"
 *                 elif t == NPY_FLOAT:       f = "f"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_DOUBLE:      f = "d"
 *                 elif t == NPY_LONGDOUBLE:  f = "g"
 */
      __pyx_v_f = __pyx_k_13;
      break;
      case NPY_DOUBLE:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":123
 *                 elif t == NPY_ULONGLONG:   f = "Q"
 *                 elif t == NPY_FLOAT:       f = "f"
 *                 elif t == NPY_DOUBLE:      f = "d"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_LONGDOUBLE:  f = "g"
 *                 elif t == NPY_CFLOAT:      f = "Zf"
 */
      __pyx_v_f = __pyx_k_14;
      break;
      case NPY_LONGDOUBLE:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":124
 *                 elif t == NPY_FLOAT:       f = "f"
 *                 elif t == NPY_DOUBLE:      f = "d"
 *                 elif t == NPY_LONGDOUBLE:  f = "g"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_CFLOAT:      f = "Zf"
 *                 elif t == NPY_CDOUBLE:     f = "Zd"
 */
      __pyx_v_f = __pyx_k_15;
      break;
      case NPY_CFLOAT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":125
 *                 elif t == NPY_DOUBLE:      f = "d"
 *                 elif t == NPY_LONGDOUBLE:  f = "g"
 *                 elif t == NPY_CFLOAT:      f = "Zf"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_CDOUBLE:     f = "Zd"
 *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
 */
      __pyx_v_f = __pyx_k_16;
      break;
      case NPY_CDOUBLE:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":126
 *                 elif t == NPY_LONGDOUBLE:  f = "g"
 *                 elif t == NPY_CFLOAT:      f = "Zf"
 *                 elif t == NPY_CDOUBLE:     f = "Zd"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
 *                 elif t == NPY_OBJECT:      f = "O"
 */
      __pyx_v_f = __pyx_k_17;
      break;
      case NPY_CLONGDOUBLE:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":127
 *                 elif t == NPY_CFLOAT:      f = "Zf"
 *                 elif t == NPY_CDOUBLE:     f = "Zd"
 *                 elif t == NPY_CLONGDOUBLE: f = "Zg"             # <<<<<<<<<<<<<<
 *                 elif t == NPY_OBJECT:      f = "O"
 *                 else:
 */
      __pyx_v_f = __pyx_k_18;
      break;
      case NPY_OBJECT:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":128
 *                 elif t == NPY_CDOUBLE:     f = "Zd"
 *                 elif t == NPY_CLONGDOUBLE: f = "Zg"
 *                 elif t == NPY_OBJECT:      f = "O"             # <<<<<<<<<<<<<<
 *                 else:
 *                     raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
 */
      __pyx_v_f = __pyx_k_19;
      break;
      default:

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":130
 *                 elif t == NPY_OBJECT:      f = "O"
 *                 else:
 *                     raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
 *                 info.format = f
 *                 return
 */
      __pyx_2 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      __pyx_t_1 = PyNumber_Remainder(__pyx_kp_20, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_1);
      __pyx_t_1 = 0;
      __pyx_2 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
      __Pyx_Raise(__pyx_2, 0, 0);
      Py_DECREF(__pyx_2); __pyx_2 = 0;
      {__pyx_filename = __pyx_f[1]; __pyx_lineno = 130; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      break;
    }

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":131
 *                 else:
 *                     raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
 *                 info.format = f             # <<<<<<<<<<<<<<
 *                 return
 *             else:
 */
    __pyx_v_info->format = __pyx_v_f;

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":132
 *                     raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
 *                 info.format = f
 *                 return             # <<<<<<<<<<<<<<
 *             else:
 *                 info.format = <char*>stdlib.malloc(255) # static size
 */
    __pyx_r = 0;
    goto __pyx_L0;
    goto __pyx_L12;
  }
  /*else*/ {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":134
 *                 return
 *             else:
 *                 info.format = <char*>stdlib.malloc(255) # static size             # <<<<<<<<<<<<<<
 *                 f = info.format
 *                 stack = [iter(descr.fields.iteritems())]
 */
    __pyx_v_info->format = ((char *)malloc(255));

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":135
 *             else:
 *                 info.format = <char*>stdlib.malloc(255) # static size
 *                 f = info.format             # <<<<<<<<<<<<<<
 *                 stack = [iter(descr.fields.iteritems())]
 * 
 */
    __pyx_v_f = __pyx_v_info->format;

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":136
 *                 info.format = <char*>stdlib.malloc(255) # static size
 *                 f = info.format
 *                 stack = [iter(descr.fields.iteritems())]             # <<<<<<<<<<<<<<
 * 
 *                 while True:
 */
    __pyx_3 = PyObject_GetAttr(__pyx_v_descr->fields, __pyx_kp_iteritems); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    __pyx_2 = PyObject_Call(__pyx_3, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_3); __pyx_3 = 0;
    __pyx_3 = PyObject_GetIter(__pyx_2); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    Py_DECREF(__pyx_2); __pyx_2 = 0;
    __pyx_2 = PyList_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 136; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
    PyList_SET_ITEM(__pyx_2, 0, __pyx_3);
    __pyx_3 = 0;
    Py_DECREF(((PyObject *)__pyx_v_stack));
    __pyx_v_stack = __pyx_2;
    __pyx_2 = 0;

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":138
 *                 stack = [iter(descr.fields.iteritems())]
 * 
 *                 while True:             # <<<<<<<<<<<<<<
 *                     iterator = stack[-1]
 *                     descr = None
 */
    while (1) {
      __pyx_1 = 1;
      if (!__pyx_1) break;

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":139
 * 
 *                 while True:
 *                     iterator = stack[-1]             # <<<<<<<<<<<<<<
 *                     descr = None
 *                     while descr is None:
 */
      __pyx_3 = __Pyx_GetItemInt(((PyObject *)__pyx_v_stack), -1, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 139; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
      Py_DECREF(__pyx_v_iterator);
      __pyx_v_iterator = __pyx_3;
      __pyx_3 = 0;

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":140
 *                 while True:
 *                     iterator = stack[-1]
 *                     descr = None             # <<<<<<<<<<<<<<
 *                     while descr is None:
 *                         try:
 */
      Py_INCREF(Py_None);
      Py_DECREF(((PyObject *)__pyx_v_descr));
      __pyx_v_descr = ((PyArray_Descr *)Py_None);

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":141
 *                     iterator = stack[-1]
 *                     descr = None
 *                     while descr is None:             # <<<<<<<<<<<<<<
 *                         try:
 *                             descr = iterator.next()[1][0]
 */
      while (1) {
        __pyx_1 = (((PyObject *)__pyx_v_descr) == Py_None);
        if (!__pyx_1) break;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":142
 *                     descr = None
 *                     while descr is None:
 *                         try:             # <<<<<<<<<<<<<<
 *                             descr = iterator.next()[1][0]
 *                         except StopIteration:
 */
        {
          PyObject *__pyx_save_exc_type, *__pyx_save_exc_value, *__pyx_save_exc_tb;
          __Pyx_ExceptionSave(&__pyx_save_exc_type, &__pyx_save_exc_value, &__pyx_save_exc_tb);
          /*try:*/ {

            /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":143
 *                     while descr is None:
 *                         try:
 *                             descr = iterator.next()[1][0]             # <<<<<<<<<<<<<<
 *                         except StopIteration:
 *                             stack.pop()
 */
            __pyx_2 = PyObject_GetAttr(__pyx_v_iterator, __pyx_kp_next); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
            __pyx_3 = PyObject_Call(__pyx_2, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
            Py_DECREF(__pyx_2); __pyx_2 = 0;
            __pyx_2 = __Pyx_GetItemInt(__pyx_3, 1, 0); if (!__pyx_2) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
            Py_DECREF(__pyx_3); __pyx_3 = 0;
            __pyx_3 = __Pyx_GetItemInt(__pyx_2, 0, 0); if (!__pyx_3) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
            Py_DECREF(__pyx_2); __pyx_2 = 0;
            if (!(__Pyx_TypeTest(__pyx_3, __pyx_ptype_5numpy_dtype))) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 143; __pyx_clineno = __LINE__; goto __pyx_L17_error;}
            Py_DECREF(((PyObject *)__pyx_v_descr));
            __pyx_v_descr = ((PyArray_Descr *)__pyx_3);
            __pyx_3 = 0;
          }
          Py_XDECREF(__pyx_save_exc_type); __pyx_save_exc_type = 0;
          Py_XDECREF(__pyx_save_exc_value); __pyx_save_exc_value = 0;
          Py_XDECREF(__pyx_save_exc_tb); __pyx_save_exc_tb = 0;
          goto __pyx_L21_try;
          __pyx_L17_error:;
          Py_XDECREF(__pyx_2); __pyx_2 = 0;
          Py_XDECREF(__pyx_3); __pyx_3 = 0;

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":144
 *                         try:
 *                             descr = iterator.next()[1][0]
 *                         except StopIteration:             # <<<<<<<<<<<<<<
 *                             stack.pop()
 *                             if len(stack) > 0:
 */
          __pyx_4 = PyErr_ExceptionMatches(__pyx_builtin_StopIteration);
          if (__pyx_4) {
            __Pyx_AddTraceback("numpy.__getbuffer__");
            if (__Pyx_GetException(&__pyx_2, &__pyx_3, &__pyx_5) < 0) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}

            /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":145
 *                             descr = iterator.next()[1][0]
 *                         except StopIteration:
 *                             stack.pop()             # <<<<<<<<<<<<<<
 *                             if len(stack) > 0:
 *                                 f[0] = 125 #"}"
 */
            __pyx_6 = PyObject_GetAttr(((PyObject *)__pyx_v_stack), __pyx_kp_pop); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
            __pyx_7 = PyObject_Call(__pyx_6, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 145; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
            Py_DECREF(__pyx_6); __pyx_6 = 0;
            Py_DECREF(__pyx_7); __pyx_7 = 0;

            /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":146
 *                         except StopIteration:
 *                             stack.pop()
 *                             if len(stack) > 0:             # <<<<<<<<<<<<<<
 *                                 f[0] = 125 #"}"
 *                                 f += 1
 */
            __pyx_8 = PyObject_Length(((PyObject *)__pyx_v_stack)); if (unlikely(__pyx_8 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 146; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
            __pyx_1 = (__pyx_8 > 0);
            if (__pyx_1) {

              /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":147
 *                             stack.pop()
 *                             if len(stack) > 0:
 *                                 f[0] = 125 #"}"             # <<<<<<<<<<<<<<
 *                                 f += 1
 *                                 iterator = stack[-1]
 */
              (__pyx_v_f[0]) = 125;

              /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":148
 *                             if len(stack) > 0:
 *                                 f[0] = 125 #"}"
 *                                 f += 1             # <<<<<<<<<<<<<<
 *                                 iterator = stack[-1]
 *                             else:
 */
              __pyx_v_f += 1;

              /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":149
 *                                 f[0] = 125 #"}"
 *                                 f += 1
 *                                 iterator = stack[-1]             # <<<<<<<<<<<<<<
 *                             else:
 *                                 f[0] = 0 # Terminate string!
 */
              __pyx_6 = __Pyx_GetItemInt(((PyObject *)__pyx_v_stack), -1, 0); if (!__pyx_6) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 149; __pyx_clineno = __LINE__; goto __pyx_L19_except_error;}
              Py_DECREF(__pyx_v_iterator);
              __pyx_v_iterator = __pyx_6;
              __pyx_6 = 0;
              goto __pyx_L22;
            }
            /*else*/ {

              /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":151
 *                                 iterator = stack[-1]
 *                             else:
 *                                 f[0] = 0 # Terminate string!             # <<<<<<<<<<<<<<
 *                                 return
 * 
 */
              (__pyx_v_f[0]) = 0;

              /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":152
 *                             else:
 *                                 f[0] = 0 # Terminate string!
 *                                 return             # <<<<<<<<<<<<<<
 * 
 *                     hasfields = PyDataType_HASFIELDS(descr)
 */
              __pyx_r = 0;
              Py_DECREF(__pyx_2); __pyx_2 = 0;
              Py_DECREF(__pyx_3); __pyx_3 = 0;
              Py_DECREF(__pyx_5); __pyx_5 = 0;
              goto __pyx_L20_except_return;
            }
            __pyx_L22:;
            Py_DECREF(__pyx_2); __pyx_2 = 0;
            Py_DECREF(__pyx_3); __pyx_3 = 0;
            Py_DECREF(__pyx_5); __pyx_5 = 0;
            goto __pyx_L18_exception_handled;
          }
          __pyx_L19_except_error:;
          Py_XDECREF(__pyx_save_exc_type);
          Py_XDECREF(__pyx_save_exc_value);
          Py_XDECREF(__pyx_save_exc_tb);
          goto __pyx_L1_error;
          __pyx_L20_except_return:;
          __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
          goto __pyx_L0;
          __pyx_L18_exception_handled:;
          __Pyx_ExceptionReset(__pyx_save_exc_type, __pyx_save_exc_value, __pyx_save_exc_tb);
          __pyx_L21_try:;
        }
      }

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":154
 *                                 return
 * 
 *                     hasfields = PyDataType_HASFIELDS(descr)             # <<<<<<<<<<<<<<
 *                     if not hasfields:
 *                         t = descr.type_num
 */
      __pyx_v_hasfields = PyDataType_HASFIELDS(__pyx_v_descr);

      /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":155
 * 
 *                     hasfields = PyDataType_HASFIELDS(descr)
 *                     if not hasfields:             # <<<<<<<<<<<<<<
 *                         t = descr.type_num
 *                         if f - info.format > 240: # this should leave room for "T{" and "}" as well
 */
      __pyx_1 = (!__pyx_v_hasfields);
      if (__pyx_1) {

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":156
 *                     hasfields = PyDataType_HASFIELDS(descr)
 *                     if not hasfields:
 *                         t = descr.type_num             # <<<<<<<<<<<<<<
 *                         if f - info.format > 240: # this should leave room for "T{" and "}" as well
 *                             raise RuntimeError("Format string allocated too short.")
 */
        __pyx_v_t = __pyx_v_descr->type_num;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":157
 *                     if not hasfields:
 *                         t = descr.type_num
 *                         if f - info.format > 240: # this should leave room for "T{" and "}" as well             # <<<<<<<<<<<<<<
 *                             raise RuntimeError("Format string allocated too short.")
 * 
 */
        __pyx_1 = ((__pyx_v_f - __pyx_v_info->format) > 240);
        if (__pyx_1) {

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":158
 *                         t = descr.type_num
 *                         if f - info.format > 240: # this should leave room for "T{" and "}" as well
 *                             raise RuntimeError("Format string allocated too short.")             # <<<<<<<<<<<<<<
 * 
 *                         # Until ticket #99 is fixed, use integers to avoid warnings
 */
          __pyx_7 = PyTuple_New(1); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_INCREF(__pyx_kp_21);
          PyTuple_SET_ITEM(__pyx_7, 0, __pyx_kp_21);
          __pyx_6 = PyObject_Call(__pyx_builtin_RuntimeError, ((PyObject *)__pyx_7), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(((PyObject *)__pyx_7)); __pyx_7 = 0;
          __Pyx_Raise(__pyx_6, 0, 0);
          Py_DECREF(__pyx_6); __pyx_6 = 0;
          {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          goto __pyx_L24;
        }
        __pyx_L24:;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":161
 * 
 *                         # Until ticket #99 is fixed, use integers to avoid warnings
 *                         if   t == NPY_BYTE:        f[0] =  98 #"b"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_UBYTE:       f[0] =  66 #"B"
 *                         elif t == NPY_SHORT:       f[0] = 104 #"h"
 */
        switch (__pyx_v_t) {
          case NPY_BYTE:
          (__pyx_v_f[0]) = 98;
          break;
          case NPY_UBYTE:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":162
 *                         # Until ticket #99 is fixed, use integers to avoid warnings
 *                         if   t == NPY_BYTE:        f[0] =  98 #"b"
 *                         elif t == NPY_UBYTE:       f[0] =  66 #"B"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_SHORT:       f[0] = 104 #"h"
 *                         elif t == NPY_USHORT:      f[0] =  72 #"H"
 */
          (__pyx_v_f[0]) = 66;
          break;
          case NPY_SHORT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":163
 *                         if   t == NPY_BYTE:        f[0] =  98 #"b"
 *                         elif t == NPY_UBYTE:       f[0] =  66 #"B"
 *                         elif t == NPY_SHORT:       f[0] = 104 #"h"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_USHORT:      f[0] =  72 #"H"
 *                         elif t == NPY_INT:         f[0] = 105 #"i"
 */
          (__pyx_v_f[0]) = 104;
          break;
          case NPY_USHORT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":164
 *                         elif t == NPY_UBYTE:       f[0] =  66 #"B"
 *                         elif t == NPY_SHORT:       f[0] = 104 #"h"
 *                         elif t == NPY_USHORT:      f[0] =  72 #"H"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_INT:         f[0] = 105 #"i"
 *                         elif t == NPY_UINT:        f[0] =  73 #"I"
 */
          (__pyx_v_f[0]) = 72;
          break;
          case NPY_INT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":165
 *                         elif t == NPY_SHORT:       f[0] = 104 #"h"
 *                         elif t == NPY_USHORT:      f[0] =  72 #"H"
 *                         elif t == NPY_INT:         f[0] = 105 #"i"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_UINT:        f[0] =  73 #"I"
 *                         elif t == NPY_LONG:        f[0] = 108 #"l"
 */
          (__pyx_v_f[0]) = 105;
          break;
          case NPY_UINT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":166
 *                         elif t == NPY_USHORT:      f[0] =  72 #"H"
 *                         elif t == NPY_INT:         f[0] = 105 #"i"
 *                         elif t == NPY_UINT:        f[0] =  73 #"I"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_LONG:        f[0] = 108 #"l"
 *                         elif t == NPY_ULONG:       f[0] = 76  #"L"
 */
          (__pyx_v_f[0]) = 73;
          break;
          case NPY_LONG:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":167
 *                         elif t == NPY_INT:         f[0] = 105 #"i"
 *                         elif t == NPY_UINT:        f[0] =  73 #"I"
 *                         elif t == NPY_LONG:        f[0] = 108 #"l"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_ULONG:       f[0] = 76  #"L"
 *                         elif t == NPY_LONGLONG:    f[0] = 113 #"q"
 */
          (__pyx_v_f[0]) = 108;
          break;
          case NPY_ULONG:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":168
 *                         elif t == NPY_UINT:        f[0] =  73 #"I"
 *                         elif t == NPY_LONG:        f[0] = 108 #"l"
 *                         elif t == NPY_ULONG:       f[0] = 76  #"L"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_LONGLONG:    f[0] = 113 #"q"
 *                         elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
 */
          (__pyx_v_f[0]) = 76;
          break;
          case NPY_LONGLONG:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":169
 *                         elif t == NPY_LONG:        f[0] = 108 #"l"
 *                         elif t == NPY_ULONG:       f[0] = 76  #"L"
 *                         elif t == NPY_LONGLONG:    f[0] = 113 #"q"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
 *                         elif t == NPY_FLOAT:       f[0] = 102 #"f"
 */
          (__pyx_v_f[0]) = 113;
          break;
          case NPY_ULONGLONG:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":170
 *                         elif t == NPY_ULONG:       f[0] = 76  #"L"
 *                         elif t == NPY_LONGLONG:    f[0] = 113 #"q"
 *                         elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_FLOAT:       f[0] = 102 #"f"
 *                         elif t == NPY_DOUBLE:      f[0] = 100 #"d"
 */
          (__pyx_v_f[0]) = 81;
          break;
          case NPY_FLOAT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":171
 *                         elif t == NPY_LONGLONG:    f[0] = 113 #"q"
 *                         elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
 *                         elif t == NPY_FLOAT:       f[0] = 102 #"f"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_DOUBLE:      f[0] = 100 #"d"
 *                         elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
 */
          (__pyx_v_f[0]) = 102;
          break;
          case NPY_DOUBLE:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":172
 *                         elif t == NPY_ULONGLONG:   f[0] = 81  #"Q"
 *                         elif t == NPY_FLOAT:       f[0] = 102 #"f"
 *                         elif t == NPY_DOUBLE:      f[0] = 100 #"d"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
 *                         elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1
 */
          (__pyx_v_f[0]) = 100;
          break;
          case NPY_LONGDOUBLE:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":173
 *                         elif t == NPY_FLOAT:       f[0] = 102 #"f"
 *                         elif t == NPY_DOUBLE:      f[0] = 100 #"d"
 *                         elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"             # <<<<<<<<<<<<<<
 *                         elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1
 *                         elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1
 */
          (__pyx_v_f[0]) = 103;
          break;
          case NPY_CFLOAT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":174
 *                         elif t == NPY_DOUBLE:      f[0] = 100 #"d"
 *                         elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
 *                         elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1             # <<<<<<<<<<<<<<
 *                         elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1
 *                         elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1
 */
          (__pyx_v_f[0]) = 90;
          (__pyx_v_f[1]) = 102;
          __pyx_v_f += 1;
          break;
          case NPY_CDOUBLE:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":175
 *                         elif t == NPY_LONGDOUBLE:  f[0] = 103 #"g"
 *                         elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1
 *                         elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1             # <<<<<<<<<<<<<<
 *                         elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1
 *                         elif t == NPY_OBJECT:      f[0] = 79 #"O"
 */
          (__pyx_v_f[0]) = 90;
          (__pyx_v_f[1]) = 100;
          __pyx_v_f += 1;
          break;
          case NPY_CLONGDOUBLE:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":176
 *                         elif t == NPY_CFLOAT:      f[0] = 90; f[1] = 102; f += 1
 *                         elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1
 *                         elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1             # <<<<<<<<<<<<<<
 *                         elif t == NPY_OBJECT:      f[0] = 79 #"O"
 *                         else:
 */
          (__pyx_v_f[0]) = 90;
          (__pyx_v_f[1]) = 103;
          __pyx_v_f += 1;
          break;
          case NPY_OBJECT:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":177
 *                         elif t == NPY_CDOUBLE:     f[0] = 90; f[1] = 100; f += 1
 *                         elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1
 *                         elif t == NPY_OBJECT:      f[0] = 79 #"O"             # <<<<<<<<<<<<<<
 *                         else:
 *                             raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
 */
          (__pyx_v_f[0]) = 79;
          break;
          default:

          /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":179
 *                         elif t == NPY_OBJECT:      f[0] = 79 #"O"
 *                         else:
 *                             raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)             # <<<<<<<<<<<<<<
 *                         f += 1
 *                     else:
 */
          __pyx_2 = PyInt_FromLong(__pyx_v_t); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          __pyx_t_1 = PyNumber_Remainder(__pyx_kp_22, __pyx_2); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(__pyx_2); __pyx_2 = 0;
          __pyx_3 = PyTuple_New(1); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          PyTuple_SET_ITEM(__pyx_3, 0, __pyx_t_1);
          __pyx_t_1 = 0;
          __pyx_5 = PyObject_Call(__pyx_builtin_ValueError, ((PyObject *)__pyx_3), NULL); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          Py_DECREF(((PyObject *)__pyx_3)); __pyx_3 = 0;
          __Pyx_Raise(__pyx_5, 0, 0);
          Py_DECREF(__pyx_5); __pyx_5 = 0;
          {__pyx_filename = __pyx_f[1]; __pyx_lineno = 179; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
          break;
        }

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":180
 *                         else:
 *                             raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
 *                         f += 1             # <<<<<<<<<<<<<<
 *                     else:
 *                         f[0] = 84 #"T"
 */
        __pyx_v_f += 1;
        goto __pyx_L23;
      }
      /*else*/ {

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":182
 *                         f += 1
 *                     else:
 *                         f[0] = 84 #"T"             # <<<<<<<<<<<<<<
 *                         f[1] = 123 #"{"
 *                         f += 2
 */
        (__pyx_v_f[0]) = 84;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":183
 *                     else:
 *                         f[0] = 84 #"T"
 *                         f[1] = 123 #"{"             # <<<<<<<<<<<<<<
 *                         f += 2
 *                         stack.append(iter(descr.fields.iteritems()))
 */
        (__pyx_v_f[1]) = 123;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":184
 *                         f[0] = 84 #"T"
 *                         f[1] = 123 #"{"
 *                         f += 2             # <<<<<<<<<<<<<<
 *                         stack.append(iter(descr.fields.iteritems()))
 * 
 */
        __pyx_v_f += 2;

        /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":185
 *                         f[1] = 123 #"{"
 *                         f += 2
 *                         stack.append(iter(descr.fields.iteritems()))             # <<<<<<<<<<<<<<
 * 
 *         def __releasebuffer__(ndarray self, Py_buffer* info):
 */
        __pyx_7 = PyObject_GetAttr(__pyx_v_descr->fields, __pyx_kp_iteritems); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        __pyx_6 = PyObject_Call(__pyx_7, ((PyObject *)__pyx_empty_tuple), NULL); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_7); __pyx_7 = 0;
        __pyx_2 = PyObject_GetIter(__pyx_6); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_6); __pyx_6 = 0;
        __pyx_4 = PyList_Append(((PyObject *)__pyx_v_stack), __pyx_2); if (unlikely(__pyx_4 == -1)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 185; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
        Py_DECREF(__pyx_2); __pyx_2 = 0;
      }
      __pyx_L23:;
    }
  }
  __pyx_L12:;

  __pyx_r = 0;
  goto __pyx_L0;
  __pyx_L1_error:;
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_3);
  Py_XDECREF(__pyx_5);
  Py_XDECREF(__pyx_6);
  Py_XDECREF(__pyx_7);
  __Pyx_AddTraceback("numpy.ndarray.__getbuffer__");
  __pyx_r = -1;
  Py_DECREF(__pyx_v_info->obj); __pyx_v_info->obj = NULL;
  goto __pyx_L2;
  __pyx_L0:;
  if (__pyx_v_info->obj == Py_None) { Py_DECREF(Py_None); __pyx_v_info->obj = NULL; }
  __pyx_L2:;
  Py_XDECREF(__pyx_v_descr);
  Py_DECREF(__pyx_v_stack);
  Py_DECREF(__pyx_v_iterator);
  return __pyx_r;
}

/* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":187
 *                         stack.append(iter(descr.fields.iteritems()))
 * 
 *         def __releasebuffer__(ndarray self, Py_buffer* info):             # <<<<<<<<<<<<<<
 *             if PyArray_HASFIELDS(self):
 *                 stdlib.free(info.format)
 */

static void __pyx_pf_5numpy_7ndarray___releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info); /*proto*/
static void __pyx_pf_5numpy_7ndarray___releasebuffer__(PyObject *__pyx_v_self, Py_buffer *__pyx_v_info) {
  int __pyx_1;
  int __pyx_2;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":188
 * 
 *         def __releasebuffer__(ndarray self, Py_buffer* info):
 *             if PyArray_HASFIELDS(self):             # <<<<<<<<<<<<<<
 *                 stdlib.free(info.format)
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
 */
  __pyx_1 = PyArray_HASFIELDS(((PyArrayObject *)__pyx_v_self));
  if (__pyx_1) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":189
 *         def __releasebuffer__(ndarray self, Py_buffer* info):
 *             if PyArray_HASFIELDS(self):
 *                 stdlib.free(info.format)             # <<<<<<<<<<<<<<
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
 *                 stdlib.free(info.strides)
 */
    free(__pyx_v_info->format);
    goto __pyx_L5;
  }
  __pyx_L5:;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":190
 *             if PyArray_HASFIELDS(self):
 *                 stdlib.free(info.format)
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):             # <<<<<<<<<<<<<<
 *                 stdlib.free(info.strides)
 *                 # info.shape was stored after info.strides in the same block
 */
  __pyx_2 = ((sizeof(npy_intp)) != (sizeof(Py_ssize_t)));
  if (__pyx_2) {

    /* "/usr/lib/python2.5/site-packages/Cython/Includes/numpy.pxd":191
 *                 stdlib.free(info.format)
 *             if sizeof(npy_intp) != sizeof(Py_ssize_t):
 *                 stdlib.free(info.strides)             # <<<<<<<<<<<<<<
 *                 # info.shape was stored after info.strides in the same block
 * 
 */
    free(__pyx_v_info->strides);
    goto __pyx_L6;
  }
  __pyx_L6:;

}

static struct PyMethodDef __pyx_methods[] = {
  {"loadModel", (PyCFunction)__pyx_pf_3svd_loadModel, METH_VARARGS|METH_KEYWORDS, __pyx_doc_3svd_loadModel},
  {0, 0, 0, 0}
};

static void __pyx_init_filenames(void); /*proto*/

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef __pyx_moduledef = {
    PyModuleDef_HEAD_INIT,
    "svd",
    0, /* m_doc */
    -1, /* m_size */
    __pyx_methods /* m_methods */,
    NULL, /* m_reload */
    NULL, /* m_traverse */
    NULL, /* m_clear */
    NULL /* m_free */
};
#endif

static __Pyx_StringTabEntry __pyx_string_tab[] = {
  {&__pyx_kp_self, __pyx_k_self, sizeof(__pyx_k_self), 1, 1, 1},
  {&__pyx_kp_fd, __pyx_k_fd, sizeof(__pyx_k_fd), 1, 1, 1},
  {&__pyx_kp_td, __pyx_k_td, sizeof(__pyx_k_td), 1, 1, 1},
  {&__pyx_kp_qd, __pyx_k_qd, sizeof(__pyx_k_qd), 1, 1, 1},
  {&__pyx_kp_modelname, __pyx_k_modelname, sizeof(__pyx_k_modelname), 1, 1, 1},
  {&__pyx_kp_overwrite, __pyx_k_overwrite, sizeof(__pyx_k_overwrite), 1, 1, 1},
  {&__pyx_kp_message, __pyx_k_message, sizeof(__pyx_k_message), 1, 1, 1},
  {&__pyx_kp_displaytext, __pyx_k_displaytext, sizeof(__pyx_k_displaytext), 1, 1, 1},
  {&__pyx_kp_havemats, __pyx_k_havemats, sizeof(__pyx_k_havemats), 1, 1, 1},
  {&__pyx_kp_userIDsForUsers, __pyx_k_userIDsForUsers, sizeof(__pyx_k_userIDsForUsers), 1, 1, 1},
  {&__pyx_kp_movieIDs, __pyx_k_movieIDs, sizeof(__pyx_k_movieIDs), 1, 1, 1},
  {&__pyx_kp_predicttype, __pyx_k_predicttype, sizeof(__pyx_k_predicttype), 1, 1, 1},
  {&__pyx_kp_U, __pyx_k_U, sizeof(__pyx_k_U), 1, 1, 1},
  {&__pyx_kp_M, __pyx_k_M, sizeof(__pyx_k_M), 1, 1, 1},
  {&__pyx_kp_userRatings, __pyx_k_userRatings, sizeof(__pyx_k_userRatings), 1, 1, 1},
  {&__pyx_kp_movieRatings, __pyx_k_movieRatings, sizeof(__pyx_k_movieRatings), 1, 1, 1},
  {&__pyx_kp_userIDs, __pyx_k_userIDs, sizeof(__pyx_k_userIDs), 1, 1, 1},
  {&__pyx_kp_fraction, __pyx_k_fraction, sizeof(__pyx_k_fraction), 1, 1, 1},
  {&__pyx_kp_loadarrays, __pyx_k_loadarrays, sizeof(__pyx_k_loadarrays), 1, 1, 1},
  {&__pyx_kp_resultdir, __pyx_k_resultdir, sizeof(__pyx_k_resultdir), 1, 1, 1},
  {&__pyx_kp_numpy, __pyx_k_numpy, sizeof(__pyx_k_numpy), 1, 1, 1},
  {&__pyx_kp_N, __pyx_k_N, sizeof(__pyx_k_N), 0, 1, 1},
  {&__pyx_kp_SVD, __pyx_k_SVD, sizeof(__pyx_k_SVD), 0, 1, 1},
  {&__pyx_kp_object, __pyx_k_object, sizeof(__pyx_k_object), 1, 1, 1},
  {&__pyx_kp_24, __pyx_k_24, sizeof(__pyx_k_24), 0, 1, 0},
  {&__pyx_kp___init__, __pyx_k___init__, sizeof(__pyx_k___init__), 1, 1, 1},
  {&__pyx_kp_startSVDLog, __pyx_k_startSVDLog, sizeof(__pyx_k_startSVDLog), 1, 1, 1},
  {&__pyx_kp_updateLog, __pyx_k_updateLog, sizeof(__pyx_k_updateLog), 1, 1, 1},
  {&__pyx_kp_svd, __pyx_k_svd, sizeof(__pyx_k_svd), 1, 1, 1},
  {&__pyx_kp_28, __pyx_k_28, sizeof(__pyx_k_28), 0, 1, 0},
  {&__pyx_kp_makeProbePrediction, __pyx_k_makeProbePrediction, sizeof(__pyx_k_makeProbePrediction), 1, 1, 1},
  {&__pyx_kp_checkError, __pyx_k_checkError, sizeof(__pyx_k_checkError), 1, 1, 1},
  {&__pyx_kp_snmf, __pyx_k_snmf, sizeof(__pyx_k_snmf), 1, 1, 1},
  {&__pyx_kp_nsvd0, __pyx_k_nsvd0, sizeof(__pyx_k_nsvd0), 1, 1, 1},
  {&__pyx_kp_29, __pyx_k_29, sizeof(__pyx_k_29), 1, 1, 1},
  {&__pyx_kp_30, __pyx_k_30, sizeof(__pyx_k_30), 1, 1, 1},
  {&__pyx_kp_31, __pyx_k_31, sizeof(__pyx_k_31), 1, 1, 1},
  {&__pyx_kp_hybrid, __pyx_k_hybrid, sizeof(__pyx_k_hybrid), 1, 1, 1},
  {&__pyx_kp_32, __pyx_k_32, sizeof(__pyx_k_32), 1, 1, 1},
  {&__pyx_kp_rmf, __pyx_k_rmf, sizeof(__pyx_k_rmf), 1, 1, 1},
  {&__pyx_kp_brismf, __pyx_k_brismf, sizeof(__pyx_k_brismf), 1, 1, 1},
  {&__pyx_kp_bpmf, __pyx_k_bpmf, sizeof(__pyx_k_bpmf), 1, 1, 1},
  {&__pyx_kp_pmf, __pyx_k_pmf, sizeof(__pyx_k_pmf), 1, 1, 1},
  {&__pyx_kp_subsampleUsers, __pyx_k_subsampleUsers, sizeof(__pyx_k_subsampleUsers), 1, 1, 1},
  {&__pyx_kp_34, __pyx_k_34, sizeof(__pyx_k_34), 1, 1, 1},
  {&__pyx_kp_numratings, __pyx_k_numratings, sizeof(__pyx_k_numratings), 1, 1, 1},
  {&__pyx_kp_nummovies, __pyx_k_nummovies, sizeof(__pyx_k_nummovies), 1, 1, 1},
  {&__pyx_kp_numusers, __pyx_k_numusers, sizeof(__pyx_k_numusers), 1, 1, 1},
  {&__pyx_kp_37, __pyx_k_37, sizeof(__pyx_k_37), 0, 1, 0},
  {&__pyx_kp_38, __pyx_k_38, sizeof(__pyx_k_38), 0, 1, 0},
  {&__pyx_kp_39, __pyx_k_39, sizeof(__pyx_k_39), 0, 1, 0},
  {&__pyx_kp_40, __pyx_k_40, sizeof(__pyx_k_40), 0, 1, 0},
  {&__pyx_kp_41, __pyx_k_41, sizeof(__pyx_k_41), 0, 1, 0},
  {&__pyx_kp_42, __pyx_k_42, sizeof(__pyx_k_42), 0, 1, 0},
  {&__pyx_kp_43, __pyx_k_43, sizeof(__pyx_k_43), 0, 1, 0},
  {&__pyx_kp_44, __pyx_k_44, sizeof(__pyx_k_44), 0, 1, 0},
  {&__pyx_kp_45, __pyx_k_45, sizeof(__pyx_k_45), 0, 1, 0},
  {&__pyx_kp_46, __pyx_k_46, sizeof(__pyx_k_46), 0, 1, 0},
  {&__pyx_kp_47, __pyx_k_47, sizeof(__pyx_k_47), 0, 1, 0},
  {&__pyx_kp_48, __pyx_k_48, sizeof(__pyx_k_48), 0, 1, 0},
  {&__pyx_kp_parameters, __pyx_k_parameters, sizeof(__pyx_k_parameters), 1, 1, 1},
  {&__pyx_kp_lrateU, __pyx_k_lrateU, sizeof(__pyx_k_lrateU), 1, 1, 1},
  {&__pyx_kp_lrateM, __pyx_k_lrateM, sizeof(__pyx_k_lrateM), 1, 1, 1},
  {&__pyx_kp_dampfactU, __pyx_k_dampfactU, sizeof(__pyx_k_dampfactU), 1, 1, 1},
  {&__pyx_kp_dampfactM, __pyx_k_dampfactM, sizeof(__pyx_k_dampfactM), 1, 1, 1},
  {&__pyx_kp_lrateUb, __pyx_k_lrateUb, sizeof(__pyx_k_lrateUb), 1, 1, 1},
  {&__pyx_kp_lrateMb, __pyx_k_lrateMb, sizeof(__pyx_k_lrateMb), 1, 1, 1},
  {&__pyx_kp_dampfactUb, __pyx_k_dampfactUb, sizeof(__pyx_k_dampfactUb), 1, 1, 1},
  {&__pyx_kp_dampfactMb, __pyx_k_dampfactMb, sizeof(__pyx_k_dampfactMb), 1, 1, 1},
  {&__pyx_kp_umin, __pyx_k_umin, sizeof(__pyx_k_umin), 1, 1, 1},
  {&__pyx_kp_umax, __pyx_k_umax, sizeof(__pyx_k_umax), 1, 1, 1},
  {&__pyx_kp_mmin, __pyx_k_mmin, sizeof(__pyx_k_mmin), 1, 1, 1},
  {&__pyx_kp_mmax, __pyx_k_mmax, sizeof(__pyx_k_mmax), 1, 1, 1},
  {&__pyx_kp_49, __pyx_k_49, sizeof(__pyx_k_49), 0, 1, 0},
  {&__pyx_kp_50, __pyx_k_50, sizeof(__pyx_k_50), 0, 1, 0},
  {&__pyx_kp_51, __pyx_k_51, sizeof(__pyx_k_51), 0, 1, 0},
  {&__pyx_kp_52, __pyx_k_52, sizeof(__pyx_k_52), 0, 1, 0},
  {&__pyx_kp_53, __pyx_k_53, sizeof(__pyx_k_53), 0, 1, 0},
  {&__pyx_kp_54, __pyx_k_54, sizeof(__pyx_k_54), 0, 1, 0},
  {&__pyx_kp_55, __pyx_k_55, sizeof(__pyx_k_55), 0, 1, 0},
  {&__pyx_kp_56, __pyx_k_56, sizeof(__pyx_k_56), 0, 1, 0},
  {&__pyx_kp_properties, __pyx_k_properties, sizeof(__pyx_k_properties), 1, 1, 1},
  {&__pyx_kp_numfeatures, __pyx_k_numfeatures, sizeof(__pyx_k_numfeatures), 1, 1, 1},
  {&__pyx_kp_miniters, __pyx_k_miniters, sizeof(__pyx_k_miniters), 1, 1, 1},
  {&__pyx_kp_maxepochs, __pyx_k_maxepochs, sizeof(__pyx_k_maxepochs), 1, 1, 1},
  {&__pyx_kp_seed, __pyx_k_seed, sizeof(__pyx_k_seed), 1, 1, 1},
  {&__pyx_kp_algorithm, __pyx_k_algorithm, sizeof(__pyx_k_algorithm), 1, 1, 1},
  {&__pyx_kp_57, __pyx_k_57, sizeof(__pyx_k_57), 0, 1, 0},
  {&__pyx_kp_keepUpositive, __pyx_k_keepUpositive, sizeof(__pyx_k_keepUpositive), 1, 1, 1},
  {&__pyx_kp_keepMpositive, __pyx_k_keepMpositive, sizeof(__pyx_k_keepMpositive), 1, 1, 1},
  {&__pyx_kp_itersForConvergence, __pyx_k_itersForConvergence, sizeof(__pyx_k_itersForConvergence), 1, 1, 1},
  {&__pyx_kp_minimprovement, __pyx_k_minimprovement, sizeof(__pyx_k_minimprovement), 1, 1, 1},
  {&__pyx_kp_os, __pyx_k_os, sizeof(__pyx_k_os), 1, 1, 1},
  {&__pyx_kp_time, __pyx_k_time, sizeof(__pyx_k_time), 1, 1, 1},
  {&__pyx_kp_ctime, __pyx_k_ctime, sizeof(__pyx_k_ctime), 1, 1, 1},
  {&__pyx_kp_curdir, __pyx_k_curdir, sizeof(__pyx_k_curdir), 1, 1, 1},
  {&__pyx_kp_listdir, __pyx_k_listdir, sizeof(__pyx_k_listdir), 1, 1, 1},
  {&__pyx_kp_path, __pyx_k_path, sizeof(__pyx_k_path), 1, 1, 1},
  {&__pyx_kp_exists, __pyx_k_exists, sizeof(__pyx_k_exists), 1, 1, 1},
  {&__pyx_kp_IOError, __pyx_k_IOError, sizeof(__pyx_k_IOError), 1, 1, 1},
  {&__pyx_kp_makedirs, __pyx_k_makedirs, sizeof(__pyx_k_makedirs), 1, 1, 1},
  {&__pyx_kp_chdir, __pyx_k_chdir, sizeof(__pyx_k_chdir), 1, 1, 1},
  {&__pyx_kp_open, __pyx_k_open, sizeof(__pyx_k_open), 1, 1, 1},
  {&__pyx_kp_60, __pyx_k_60, sizeof(__pyx_k_60), 0, 1, 0},
  {&__pyx_kp_logfile, __pyx_k_logfile, sizeof(__pyx_k_logfile), 1, 1, 1},
  {&__pyx_kp_write, __pyx_k_write, sizeof(__pyx_k_write), 1, 1, 1},
  {&__pyx_kp_67, __pyx_k_67, sizeof(__pyx_k_67), 0, 1, 0},
  {&__pyx_kp_outnameU, __pyx_k_outnameU, sizeof(__pyx_k_outnameU), 1, 1, 1},
  {&__pyx_kp_68, __pyx_k_68, sizeof(__pyx_k_68), 0, 1, 0},
  {&__pyx_kp_outnameM, __pyx_k_outnameM, sizeof(__pyx_k_outnameM), 1, 1, 1},
  {&__pyx_kp_arrayfolder, __pyx_k_arrayfolder, sizeof(__pyx_k_arrayfolder), 1, 1, 1},
  {&__pyx_kp_split, __pyx_k_split, sizeof(__pyx_k_split), 1, 1, 1},
  {&__pyx_kp_append, __pyx_k_append, sizeof(__pyx_k_append), 1, 1, 1},
  {&__pyx_kp_70, __pyx_k_70, sizeof(__pyx_k_70), 0, 1, 0},
  {&__pyx_kp_string, __pyx_k_string, sizeof(__pyx_k_string), 1, 1, 1},
  {&__pyx_kp_join, __pyx_k_join, sizeof(__pyx_k_join), 1, 1, 1},
  {&__pyx_kp_zeros, __pyx_k_zeros, sizeof(__pyx_k_zeros), 1, 1, 1},
  {&__pyx_kp_dtype, __pyx_k_dtype, sizeof(__pyx_k_dtype), 1, 1, 1},
  {&__pyx_kp_72, __pyx_k_72, sizeof(__pyx_k_72), 0, 1, 0},
  {&__pyx_kp_73, __pyx_k_73, sizeof(__pyx_k_73), 0, 1, 0},
  {&__pyx_kp_random, __pyx_k_random, sizeof(__pyx_k_random), 1, 1, 1},
  {&__pyx_kp_RandomState, __pyx_k_RandomState, sizeof(__pyx_k_RandomState), 1, 1, 1},
  {&__pyx_kp_range, __pyx_k_range, sizeof(__pyx_k_range), 1, 1, 1},
  {&__pyx_kp_uniform, __pyx_k_uniform, sizeof(__pyx_k_uniform), 1, 1, 1},
  {&__pyx_kp_low, __pyx_k_low, sizeof(__pyx_k_low), 1, 1, 1},
  {&__pyx_kp_high, __pyx_k_high, sizeof(__pyx_k_high), 1, 1, 1},
  {&__pyx_kp_size, __pyx_k_size, sizeof(__pyx_k_size), 1, 1, 1},
  {&__pyx_kp_astype, __pyx_k_astype, sizeof(__pyx_k_astype), 1, 1, 1},
  {&__pyx_kp_75, __pyx_k_75, sizeof(__pyx_k_75), 0, 1, 0},
  {&__pyx_kp_76, __pyx_k_76, sizeof(__pyx_k_76), 0, 1, 0},
  {&__pyx_kp_77, __pyx_k_77, sizeof(__pyx_k_77), 0, 1, 0},
  {&__pyx_kp_W, __pyx_k_W, sizeof(__pyx_k_W), 1, 1, 1},
  {&__pyx_kp_78, __pyx_k_78, sizeof(__pyx_k_78), 0, 1, 0},
  {&__pyx_kp_79, __pyx_k_79, sizeof(__pyx_k_79), 0, 1, 0},
  {&__pyx_kp_80, __pyx_k_80, sizeof(__pyx_k_80), 0, 1, 0},
  {&__pyx_kp_numnodes, __pyx_k_numnodes, sizeof(__pyx_k_numnodes), 1, 1, 1},
  {&__pyx_kp_81, __pyx_k_81, sizeof(__pyx_k_81), 0, 1, 0},
  {&__pyx_kp_82, __pyx_k_82, sizeof(__pyx_k_82), 0, 1, 0},
  {&__pyx_kp_84, __pyx_k_84, sizeof(__pyx_k_84), 0, 1, 0},
  {&__pyx_kp_85, __pyx_k_85, sizeof(__pyx_k_85), 0, 1, 0},
  {&__pyx_kp_ValueError, __pyx_k_ValueError, sizeof(__pyx_k_ValueError), 1, 1, 1},
  {&__pyx_kp_numfeaturesmf, __pyx_k_numfeaturesmf, sizeof(__pyx_k_numfeaturesmf), 1, 1, 1},
  {&__pyx_kp_87, __pyx_k_87, sizeof(__pyx_k_87), 0, 1, 0},
  {&__pyx_kp_89, __pyx_k_89, sizeof(__pyx_k_89), 0, 1, 0},
  {&__pyx_kp_91, __pyx_k_91, sizeof(__pyx_k_91), 0, 1, 0},
  {&__pyx_kp_93, __pyx_k_93, sizeof(__pyx_k_93), 0, 1, 0},
  {&__pyx_kp_95, __pyx_k_95, sizeof(__pyx_k_95), 0, 1, 0},
  {&__pyx_kp_97, __pyx_k_97, sizeof(__pyx_k_97), 0, 1, 0},
  {&__pyx_kp_99, __pyx_k_99, sizeof(__pyx_k_99), 0, 1, 0},
  {&__pyx_kp_100, __pyx_k_100, sizeof(__pyx_k_100), 0, 1, 0},
  {&__pyx_kp_101, __pyx_k_101, sizeof(__pyx_k_101), 0, 1, 0},
  {&__pyx_kp_102, __pyx_k_102, sizeof(__pyx_k_102), 0, 1, 0},
  {&__pyx_kp_103, __pyx_k_103, sizeof(__pyx_k_103), 0, 1, 0},
  {&__pyx_kp_104, __pyx_k_104, sizeof(__pyx_k_104), 0, 1, 0},
  {&__pyx_kp_105, __pyx_k_105, sizeof(__pyx_k_105), 0, 1, 0},
  {&__pyx_kp_106, __pyx_k_106, sizeof(__pyx_k_106), 0, 1, 0},
  {&__pyx_kp_107, __pyx_k_107, sizeof(__pyx_k_107), 0, 1, 0},
  {&__pyx_kp_108, __pyx_k_108, sizeof(__pyx_k_108), 0, 1, 0},
  {&__pyx_kp_109, __pyx_k_109, sizeof(__pyx_k_109), 0, 1, 0},
  {&__pyx_kp_110, __pyx_k_110, sizeof(__pyx_k_110), 0, 1, 0},
  {&__pyx_kp_beta, __pyx_k_beta, sizeof(__pyx_k_beta), 1, 1, 1},
  {&__pyx_kp_111, __pyx_k_111, sizeof(__pyx_k_111), 0, 1, 0},
  {&__pyx_kp_113, __pyx_k_113, sizeof(__pyx_k_113), 0, 1, 0},
  {&__pyx_kp_115, __pyx_k_115, sizeof(__pyx_k_115), 0, 1, 0},
  {&__pyx_kp_116, __pyx_k_116, sizeof(__pyx_k_116), 0, 1, 0},
  {&__pyx_kp_117, __pyx_k_117, sizeof(__pyx_k_117), 0, 1, 0},
  {&__pyx_kp_118, __pyx_k_118, sizeof(__pyx_k_118), 0, 1, 0},
  {&__pyx_kp_RMSEhistory, __pyx_k_RMSEhistory, sizeof(__pyx_k_RMSEhistory), 1, 1, 1},
  {&__pyx_kp_save, __pyx_k_save, sizeof(__pyx_k_save), 1, 1, 1},
  {&__pyx_kp_124, __pyx_k_124, sizeof(__pyx_k_124), 0, 1, 0},
  {&__pyx_kp_125, __pyx_k_125, sizeof(__pyx_k_125), 0, 1, 0},
  {&__pyx_kp_load, __pyx_k_load, sizeof(__pyx_k_load), 1, 1, 1},
  {&__pyx_kp_128, __pyx_k_128, sizeof(__pyx_k_128), 0, 1, 0},
  {&__pyx_kp_129, __pyx_k_129, sizeof(__pyx_k_129), 0, 1, 0},
  {&__pyx_kp_close, __pyx_k_close, sizeof(__pyx_k_close), 1, 1, 1},
  {&__pyx_kp_131, __pyx_k_131, sizeof(__pyx_k_131), 0, 1, 0},
  {&__pyx_kp_dump, __pyx_k_dump, sizeof(__pyx_k_dump), 1, 1, 1},
  {&__pyx_kp_132, __pyx_k_132, sizeof(__pyx_k_132), 0, 1, 0},
  {&__pyx_kp_133, __pyx_k_133, sizeof(__pyx_k_133), 0, 1, 0},
  {&__pyx_kp_135, __pyx_k_135, sizeof(__pyx_k_135), 0, 1, 0},
  {&__pyx_kp_136, __pyx_k_136, sizeof(__pyx_k_136), 0, 1, 0},
  {&__pyx_kp_137, __pyx_k_137, sizeof(__pyx_k_137), 0, 1, 0},
  {&__pyx_kp_138, __pyx_k_138, sizeof(__pyx_k_138), 0, 1, 0},
  {&__pyx_kp_140, __pyx_k_140, sizeof(__pyx_k_140), 0, 1, 0},
  {&__pyx_kp_sqrt, __pyx_k_sqrt, sizeof(__pyx_k_sqrt), 1, 1, 1},
  {&__pyx_kp_float, __pyx_k_float, sizeof(__pyx_k_float), 1, 1, 1},
  {&__pyx_kp_numconnectednodes, __pyx_k_numconnectednodes, sizeof(__pyx_k_numconnectednodes), 1, 1, 1},
  {&__pyx_kp_userIndex, __pyx_k_userIndex, sizeof(__pyx_k_userIndex), 1, 1, 1},
  {&__pyx_kp_141, __pyx_k_141, sizeof(__pyx_k_141), 0, 1, 0},
  {&__pyx_kp_arange, __pyx_k_arange, sizeof(__pyx_k_arange), 1, 1, 1},
  {&__pyx_kp_int, __pyx_k_int, sizeof(__pyx_k_int), 1, 1, 1},
  {&__pyx_kp_shuffle, __pyx_k_shuffle, sizeof(__pyx_k_shuffle), 1, 1, 1},
  {&__pyx_kp_143, __pyx_k_143, sizeof(__pyx_k_143), 0, 1, 0},
  {&__pyx_kp_145, __pyx_k_145, sizeof(__pyx_k_145), 0, 1, 0},
  {&__pyx_kp_movieIndex, __pyx_k_movieIndex, sizeof(__pyx_k_movieIndex), 1, 1, 1},
  {&__pyx_kp_147, __pyx_k_147, sizeof(__pyx_k_147), 0, 1, 0},
  {&__pyx_kp_149, __pyx_k_149, sizeof(__pyx_k_149), 0, 1, 0},
  {&__pyx_kp_151, __pyx_k_151, sizeof(__pyx_k_151), 0, 1, 0},
  {&__pyx_kp_lrateUn, __pyx_k_lrateUn, sizeof(__pyx_k_lrateUn), 1, 1, 1},
  {&__pyx_kp_lrateMn, __pyx_k_lrateMn, sizeof(__pyx_k_lrateMn), 1, 1, 1},
  {&__pyx_kp_dampfactUn, __pyx_k_dampfactUn, sizeof(__pyx_k_dampfactUn), 1, 1, 1},
  {&__pyx_kp_dampfactMn, __pyx_k_dampfactMn, sizeof(__pyx_k_dampfactMn), 1, 1, 1},
  {&__pyx_kp_153, __pyx_k_153, sizeof(__pyx_k_153), 0, 1, 0},
  {&__pyx_kp_argwhere, __pyx_k_argwhere, sizeof(__pyx_k_argwhere), 1, 1, 1},
  {&__pyx_kp_23, __pyx_k_23, sizeof(__pyx_k_23), 0, 0, 0},
  {&__pyx_kp_36, __pyx_k_36, sizeof(__pyx_k_36), 0, 0, 0},
  {&__pyx_kp_58, __pyx_k_58, sizeof(__pyx_k_58), 0, 0, 0},
  {&__pyx_kp_59, __pyx_k_59, sizeof(__pyx_k_59), 0, 0, 0},
  {&__pyx_kp_61, __pyx_k_61, sizeof(__pyx_k_61), 0, 0, 0},
  {&__pyx_kp_62, __pyx_k_62, sizeof(__pyx_k_62), 0, 0, 0},
  {&__pyx_kp_63, __pyx_k_63, sizeof(__pyx_k_63), 0, 0, 0},
  {&__pyx_kp_64, __pyx_k_64, sizeof(__pyx_k_64), 0, 0, 0},
  {&__pyx_kp_65, __pyx_k_65, sizeof(__pyx_k_65), 0, 0, 0},
  {&__pyx_kp_66, __pyx_k_66, sizeof(__pyx_k_66), 0, 0, 0},
  {&__pyx_kp_69, __pyx_k_69, sizeof(__pyx_k_69), 0, 0, 0},
  {&__pyx_kp_71, __pyx_k_71, sizeof(__pyx_k_71), 0, 0, 0},
  {&__pyx_kp_74, __pyx_k_74, sizeof(__pyx_k_74), 0, 0, 0},
  {&__pyx_kp_83, __pyx_k_83, sizeof(__pyx_k_83), 0, 0, 0},
  {&__pyx_kp_86, __pyx_k_86, sizeof(__pyx_k_86), 0, 0, 0},
  {&__pyx_kp_88, __pyx_k_88, sizeof(__pyx_k_88), 0, 0, 0},
  {&__pyx_kp_90, __pyx_k_90, sizeof(__pyx_k_90), 0, 0, 0},
  {&__pyx_kp_92, __pyx_k_92, sizeof(__pyx_k_92), 0, 0, 0},
  {&__pyx_kp_94, __pyx_k_94, sizeof(__pyx_k_94), 0, 0, 0},
  {&__pyx_kp_96, __pyx_k_96, sizeof(__pyx_k_96), 0, 0, 0},
  {&__pyx_kp_98, __pyx_k_98, sizeof(__pyx_k_98), 0, 0, 0},
  {&__pyx_kp_112, __pyx_k_112, sizeof(__pyx_k_112), 0, 0, 0},
  {&__pyx_kp_114, __pyx_k_114, sizeof(__pyx_k_114), 0, 0, 0},
  {&__pyx_kp_119, __pyx_k_119, sizeof(__pyx_k_119), 0, 0, 0},
  {&__pyx_kp_120, __pyx_k_120, sizeof(__pyx_k_120), 0, 0, 0},
  {&__pyx_kp_121, __pyx_k_121, sizeof(__pyx_k_121), 0, 0, 0},
  {&__pyx_kp_122, __pyx_k_122, sizeof(__pyx_k_122), 0, 0, 0},
  {&__pyx_kp_123, __pyx_k_123, sizeof(__pyx_k_123), 0, 0, 0},
  {&__pyx_kp_126, __pyx_k_126, sizeof(__pyx_k_126), 0, 0, 0},
  {&__pyx_kp_127, __pyx_k_127, sizeof(__pyx_k_127), 0, 0, 0},
  {&__pyx_kp_130, __pyx_k_130, sizeof(__pyx_k_130), 0, 0, 0},
  {&__pyx_kp_134, __pyx_k_134, sizeof(__pyx_k_134), 0, 0, 0},
  {&__pyx_kp_139, __pyx_k_139, sizeof(__pyx_k_139), 0, 0, 0},
  {&__pyx_kp_142, __pyx_k_142, sizeof(__pyx_k_142), 0, 0, 0},
  {&__pyx_kp_144, __pyx_k_144, sizeof(__pyx_k_144), 0, 0, 0},
  {&__pyx_kp_146, __pyx_k_146, sizeof(__pyx_k_146), 0, 0, 0},
  {&__pyx_kp_148, __pyx_k_148, sizeof(__pyx_k_148), 0, 0, 0},
  {&__pyx_kp_150, __pyx_k_150, sizeof(__pyx_k_150), 0, 0, 0},
  {&__pyx_kp_152, __pyx_k_152, sizeof(__pyx_k_152), 0, 0, 0},
  {&__pyx_kp_154, __pyx_k_154, sizeof(__pyx_k_154), 0, 0, 0},
  {&__pyx_kp_155, __pyx_k_155, sizeof(__pyx_k_155), 0, 0, 0},
  {&__pyx_kp_156, __pyx_k_156, sizeof(__pyx_k_156), 0, 0, 0},
  {&__pyx_kp_157, __pyx_k_157, sizeof(__pyx_k_157), 0, 0, 0},
  {&__pyx_kp_158, __pyx_k_158, sizeof(__pyx_k_158), 0, 0, 0},
  {&__pyx_kp___getbuffer__, __pyx_k___getbuffer__, sizeof(__pyx_k___getbuffer__), 1, 1, 1},
  {&__pyx_kp___releasebuffer__, __pyx_k___releasebuffer__, sizeof(__pyx_k___releasebuffer__), 1, 1, 1},
  {&__pyx_kp_info, __pyx_k_info, sizeof(__pyx_k_info), 1, 1, 1},
  {&__pyx_kp_flags, __pyx_k_flags, sizeof(__pyx_k_flags), 1, 1, 1},
  {&__pyx_kp_iteritems, __pyx_k_iteritems, sizeof(__pyx_k_iteritems), 1, 1, 1},
  {&__pyx_kp_next, __pyx_k_next, sizeof(__pyx_k_next), 1, 1, 1},
  {&__pyx_kp_StopIteration, __pyx_k_StopIteration, sizeof(__pyx_k_StopIteration), 1, 1, 1},
  {&__pyx_kp_pop, __pyx_k_pop, sizeof(__pyx_k_pop), 1, 1, 1},
  {&__pyx_kp_RuntimeError, __pyx_k_RuntimeError, sizeof(__pyx_k_RuntimeError), 1, 1, 1},
  {&__pyx_kp_1, __pyx_k_1, sizeof(__pyx_k_1), 0, 0, 0},
  {&__pyx_kp_2, __pyx_k_2, sizeof(__pyx_k_2), 0, 0, 0},
  {&__pyx_kp_20, __pyx_k_20, sizeof(__pyx_k_20), 0, 0, 0},
  {&__pyx_kp_21, __pyx_k_21, sizeof(__pyx_k_21), 0, 0, 0},
  {&__pyx_kp_22, __pyx_k_22, sizeof(__pyx_k_22), 0, 0, 0},
  {0, 0, 0, 0, 0, 0}
};
static int __Pyx_InitCachedBuiltins(void) {
  __pyx_builtin_object = __Pyx_GetName(__pyx_b, __pyx_kp_object); if (!__pyx_builtin_object) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_IOError = __Pyx_GetName(__pyx_b, __pyx_kp_IOError); if (!__pyx_builtin_IOError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 97; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_open = __Pyx_GetName(__pyx_b, __pyx_kp_open); if (!__pyx_builtin_open) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 105; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_range = __Pyx_GetName(__pyx_b, __pyx_kp_range); if (!__pyx_builtin_range) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 168; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_ValueError = __Pyx_GetName(__pyx_b, __pyx_kp_ValueError); if (!__pyx_builtin_ValueError) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 186; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_StopIteration = __Pyx_GetName(__pyx_b, __pyx_kp_StopIteration); if (!__pyx_builtin_StopIteration) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 144; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_builtin_RuntimeError = __Pyx_GetName(__pyx_b, __pyx_kp_RuntimeError); if (!__pyx_builtin_RuntimeError) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 158; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  return 0;
  __pyx_L1_error:;
  return -1;
}

static int __Pyx_InitGlobals(void) {
  __pyx_int_17770 = PyInt_FromLong(17770); if (unlikely(!__pyx_int_17770)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_12 = PyInt_FromLong(12); if (unlikely(!__pyx_int_12)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_2 = PyInt_FromLong(2); if (unlikely(!__pyx_int_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_100 = PyInt_FromLong(100); if (unlikely(!__pyx_int_100)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_123456789 = PyInt_FromLong(123456789); if (unlikely(!__pyx_int_123456789)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_0 = PyInt_FromLong(0); if (unlikely(!__pyx_int_0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_1 = PyInt_FromLong(1); if (unlikely(!__pyx_int_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  __pyx_int_480189 = PyInt_FromLong(480189); if (unlikely(!__pyx_int_480189)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  if (__Pyx_InitStrings(__pyx_string_tab) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  return 0;
  __pyx_L1_error:;
  return -1;
}

#if PY_MAJOR_VERSION < 3
PyMODINIT_FUNC initsvd(void); /*proto*/
PyMODINIT_FUNC initsvd(void)
#else
PyMODINIT_FUNC PyInit_svd(void); /*proto*/
PyMODINIT_FUNC PyInit_svd(void)
#endif
{
  PyObject *__pyx_1 = 0;
  PyObject *__pyx_2 = 0;
  PyObject *__pyx_3 = 0;
  PyObject *__pyx_4 = 0;
  PyObject *__pyx_5 = 0;
  PyObject *__pyx_6 = 0;
  PyObject *__pyx_7 = 0;
  PyObject *__pyx_8 = 0;
  __pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_empty_tuple)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  /*--- Library function declarations ---*/
  __pyx_init_filenames();
  /*--- Initialize various global constants etc. ---*/
  if (unlikely(__Pyx_InitGlobals() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  /*--- Module creation code ---*/
  #if PY_MAJOR_VERSION < 3
  __pyx_m = Py_InitModule4("svd", __pyx_methods, 0, 0, PYTHON_API_VERSION);
  #else
  __pyx_m = PyModule_Create(&__pyx_moduledef);
  #endif
  if (!__pyx_m) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  #if PY_MAJOR_VERSION < 3
  Py_INCREF(__pyx_m);
  #endif
  __pyx_b = PyImport_AddModule(__Pyx_BUILTIN_MODULE_NAME);
  if (!__pyx_b) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_b) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;};
  /*--- Builtin init code ---*/
  if (unlikely(__Pyx_InitCachedBuiltins() < 0)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_skip_dispatch = 0;
  /*--- Global init code ---*/
  /*--- Function export code ---*/
  /*--- Type init code ---*/
  /*--- Type import code ---*/
  __pyx_ptype_5numpy_dtype = __Pyx_ImportType("numpy", "dtype", sizeof(PyArray_Descr)); if (unlikely(!__pyx_ptype_5numpy_dtype)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 30; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_ptype_5numpy_ndarray = __Pyx_ImportType("numpy", "ndarray", sizeof(PyArrayObject)); if (unlikely(!__pyx_ptype_5numpy_ndarray)) {__pyx_filename = __pyx_f[1]; __pyx_lineno = 36; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  /*--- Function import code ---*/
  /*--- Execution code ---*/

  /* "/home/alex/workspace/flix/src/svd.pyx":3
 * cimport cython
 * cimport numpy as N
 * import numpy as N             # <<<<<<<<<<<<<<
 * 
 * ctypedef N.float64_t f64_t
 */
  __pyx_1 = __Pyx_Import(__pyx_kp_numpy, 0); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  if (PyObject_SetAttr(__pyx_m, __pyx_kp_N, __pyx_1) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 3; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_1); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":21
 * 
 * 
 * class SVD(object):             # <<<<<<<<<<<<<<
 * 	"""
 * 	SVD is a class wrapping functionality implementing various matrix factorization algorithms,
 */
  __pyx_1 = PyDict_New(); if (unlikely(!__pyx_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_2 = PyTuple_New(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_INCREF(__pyx_builtin_object);
  PyTuple_SET_ITEM(__pyx_2, 0, __pyx_builtin_object);
  if (PyDict_SetItemString(((PyObject *)__pyx_1), "__doc__", __pyx_kp_23) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_3 = __Pyx_CreateClass(((PyObject *)__pyx_2), ((PyObject *)__pyx_1), __pyx_kp_SVD, "svd"); if (unlikely(!__pyx_3)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(((PyObject *)__pyx_2)); __pyx_2 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":39
 * 	"""
 * 
 * 	def __init__(self, fd, td, qd=None, modelname='untitled_model'):             # <<<<<<<<<<<<<<
 * 		self.fd = fd # Full data FlixData class
 * 		self.td = td # Test data FlixData class (Gravity's probe10)
 */
  __pyx_2 = PyCFunction_New(&__pyx_mdef_3svd_3SVD___init__, 0); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_4 = PyMethod_New(__pyx_2, 0, __pyx_3); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_2); __pyx_2 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp___init__, __pyx_4) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 39; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":80
 * 		self.minimprovement = 0.00004 # pretty arbitrary, just thrown in to save time.
 * 
 * 	def startSVDLog(self, overwrite=True):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Create a folder of the model, and begin a logfile in that folder.
 */
  __pyx_2 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_k_25 = __pyx_2;
  __pyx_2 = 0;
  __pyx_4 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_startSVDLog, 0); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_5 = PyMethod_New(__pyx_4, 0, __pyx_3); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_4); __pyx_4 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_startSVDLog, __pyx_5) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 80; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":121
 * 		self.logfile.write('\nLog:\n')
 * 
 * 	def updateLog(self, message, displaytext=True):             # <<<<<<<<<<<<<<
 * 		"""
 * 		USAGE:
 */
  __pyx_4 = __Pyx_PyBool_FromLong(1); if (unlikely(!__pyx_4)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_k_26 = __pyx_4;
  __pyx_4 = 0;
  __pyx_5 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_updateLog, 0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_6 = PyMethod_New(__pyx_5, 0, __pyx_3); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_5); __pyx_5 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_updateLog, __pyx_6) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 121; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":135
 * 
 * 
 * 	def svd(self, havemats=False):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Run an SVD algorithm.
 */
  __pyx_5 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_5)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_k_27 = __pyx_5;
  __pyx_5 = 0;
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_svd, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_svd, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 135; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":297
 * 
 * 
 * 	def makeProbePrediction(self, N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs, predicttype='probe'):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Make predictions for the probe data based on the loaded model.
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_makeProbePrediction, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_makeProbePrediction, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 297; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":335
 * 		return probeRatings
 * 
 * 	def checkError(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_checkError, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_checkError, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 335; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":397
 * 	# ============================================================
 * 
 * 	def snmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_snmf, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_snmf, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 397; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":506
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd0(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_nsvd0, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_nsvd0, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 506; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":602
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd1(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_nsvd1, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_29, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 602; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":697
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd2(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_nsvd2, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_30, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 697; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":791
 * 
 * 	@cython.boundscheck(False)
 * 	def nsvd3(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_nsvd3, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_31, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 791; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":880
 * 
 * 	@cython.boundscheck(False)
 * 	def hybrid(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_hybrid, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_hybrid, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 880; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":989
 * 
 * 	@cython.boundscheck(False)
 * 	def hybrid2(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] movieRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_hybrid2, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_32, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 989; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1098
 * 
 * 	@cython.boundscheck(False)
 * 	def rmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Regularized Matrix Factorization.
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_rmf, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_rmf, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1098; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1134
 * 
 * 	@cython.boundscheck(False)
 * 	def brismf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Biased Regularized Incremental Simultaneous Matrix Factorization, a la
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_brismf, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_brismf, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1134; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1182
 * 
 * 	@cython.boundscheck(False)
 * 	def bpmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_bpmf, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_bpmf, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1182; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1242
 * 
 * 	@cython.boundscheck(False)
 * 	def pmf(self, N.ndarray[f32_t, ndim=2] U, N.ndarray[f32_t, ndim=2] M, N.ndarray[i8_t, ndim=1] userRatings, \             # <<<<<<<<<<<<<<
 * 							N.ndarray[i32_t, ndim=1] userIDsForUsers, N.ndarray[i16_t, ndim=1] movieIDs):
 * 		"""Positive matrix factorization.
 */
  __pyx_6 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_pmf, 0); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_7 = PyMethod_New(__pyx_6, 0, __pyx_3); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_6); __pyx_6 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_pmf, __pyx_7) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1242; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1284
 * 		return
 * 
 * 	def subsampleUsers(self, fraction=0.3):             # <<<<<<<<<<<<<<
 * 		"""
 * 		Update the svd model to use only a subsample of users
 */
  __pyx_6 = PyFloat_FromDouble(0.3); if (unlikely(!__pyx_6)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_k_33 = __pyx_6;
  __pyx_6 = 0;
  __pyx_7 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_subsampleUsers, 0); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_8 = PyMethod_New(__pyx_7, 0, __pyx_3); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_subsampleUsers, __pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1284; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1309
 * 		self.numratings = self.fd.numratings
 * 
 * 	def restoreFromSubsample(self):             # <<<<<<<<<<<<<<
 * 		self.numusers = 480189
 * 		self.fd.numusers = 480189
 */
  __pyx_7 = PyCFunction_New(&__pyx_mdef_3svd_3SVD_restoreFromSubsample, 0); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_8 = PyMethod_New(__pyx_7, 0, __pyx_3); if (unlikely(!__pyx_8)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_7); __pyx_7 = 0;
  if (PyObject_SetAttr(__pyx_3, __pyx_kp_34, __pyx_8) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1309; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_8); __pyx_8 = 0;
  if (PyObject_SetAttr(__pyx_m, __pyx_kp_SVD, __pyx_3) < 0) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 21; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  Py_DECREF(__pyx_3); __pyx_3 = 0;
  Py_DECREF(((PyObject *)__pyx_1)); __pyx_1 = 0;

  /* "/home/alex/workspace/flix/src/svd.pyx":1321
 * # END OF SVD CLASS
 * 
 * def loadModel(modelname, loadarrays=False, resultdir='/home/alex/workspace/flix/results/'):             # <<<<<<<<<<<<<<
 * 	"""
 * 	Make an instance of the SVD class using information from the logfile
 */
  __pyx_7 = __Pyx_PyBool_FromLong(0); if (unlikely(!__pyx_7)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 1321; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
  __pyx_k_35 = __pyx_7;
  __pyx_7 = 0;

  /* "/usr/lib/python2.5/site-packages/Cython/Includes/stdlib.pxd":2
 * 
 * cdef extern from "stdlib.h":             # <<<<<<<<<<<<<<
 *     ctypedef unsigned long size_t
 *     void free(void *ptr)
 */
  #if PY_MAJOR_VERSION < 3
  return;
  #else
  return __pyx_m;
  #endif
  __pyx_L1_error:;
  Py_XDECREF(__pyx_1);
  Py_XDECREF(__pyx_2);
  Py_XDECREF(__pyx_3);
  Py_XDECREF(__pyx_4);
  Py_XDECREF(__pyx_5);
  Py_XDECREF(__pyx_6);
  Py_XDECREF(__pyx_7);
  Py_XDECREF(__pyx_8);
  __Pyx_AddTraceback("svd");
  #if PY_MAJOR_VERSION >= 3
  return NULL;
  #endif
}

static const char *__pyx_filenames[] = {
  "svd.pyx",
  "numpy.pxd",
};

/* Runtime support code */

static void __pyx_init_filenames(void) {
  __pyx_f = __pyx_filenames;
}

static void __Pyx_RaiseDoubleKeywordsError(
    const char* func_name,
    PyObject* kw_name)
{
    PyErr_Format(PyExc_TypeError,
        #if PY_MAJOR_VERSION >= 3
        "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
        #else
        "%s() got multiple values for keyword argument '%s'", func_name,
        PyString_AS_STRING(kw_name));
        #endif
}

static void __Pyx_RaiseArgtupleInvalid(
    const char* func_name,
    int exact,
    Py_ssize_t num_min,
    Py_ssize_t num_max,
    Py_ssize_t num_found)
{
    Py_ssize_t num_expected;
    const char *number, *more_or_less;

    if (num_found < num_min) {
        num_expected = num_min;
        more_or_less = "at least";
    } else {
        num_expected = num_max;
        more_or_less = "at most";
    }
    if (exact) {
        more_or_less = "exactly";
    }
    number = (num_expected == 1) ? "" : "s";
    PyErr_Format(PyExc_TypeError,
        #if PY_VERSION_HEX < 0x02050000
            "%s() takes %s %d positional argument%s (%d given)",
        #else
            "%s() takes %s %zd positional argument%s (%zd given)",
        #endif
        func_name, more_or_less, num_expected, number, num_found);
}

static int __Pyx_ParseOptionalKeywords(
    PyObject *kwds,
    PyObject **argnames[],
    PyObject *kwds2,
    PyObject *values[],
    Py_ssize_t num_pos_args,
    const char* function_name)
{
    PyObject *key = 0, *value = 0;
    Py_ssize_t pos = 0;
    PyObject*** name;
    PyObject*** first_kw_arg = argnames + num_pos_args;

    while (PyDict_Next(kwds, &pos, &key, &value)) {
        #if PY_MAJOR_VERSION < 3
        if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
        #else
        if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
        #endif
            goto invalid_keyword_type;
        } else {
            name = argnames;
            while (*name && (**name != key)) name++;
            if (*name) {
                if (name < first_kw_arg) goto arg_passed_twice;
                values[name-argnames] = value;
            } else {
                for (name = first_kw_arg; *name; name++) {
                    #if PY_MAJOR_VERSION >= 3
                    if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
                        PyUnicode_Compare(**name, key) == 0) break;
                    #else
                    if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
                        strcmp(PyString_AS_STRING(**name),
                               PyString_AS_STRING(key)) == 0) break;
                    #endif
                }
                if (*name) {
                    values[name-argnames] = value;
                } else {
                    /* unexpected keyword found */
                    for (name=argnames; name != first_kw_arg; name++) {
                        if (**name == key) goto arg_passed_twice;
                        #if PY_MAJOR_VERSION >= 3
                        if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
                            PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
                        #else
                        if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
                            strcmp(PyString_AS_STRING(**name),
                                   PyString_AS_STRING(key)) == 0) goto arg_passed_twice;
                        #endif
                    }
                    if (kwds2) {
                        if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
                    } else {
                        goto invalid_keyword;
                    }
                }
            }
        }
    }
    return 0;
arg_passed_twice:
    __Pyx_RaiseDoubleKeywordsError(function_name, **name);
    goto bad;
invalid_keyword_type:
    PyErr_Format(PyExc_TypeError,
        "%s() keywords must be strings", function_name);
    goto bad;
invalid_keyword:
    PyErr_Format(PyExc_TypeError,
    #if PY_MAJOR_VERSION < 3
        "%s() got an unexpected keyword argument '%s'",
        function_name, PyString_AsString(key));
    #else
        "%s() got an unexpected keyword argument '%U'",
        function_name, key);
    #endif
bad:
    return -1;
}

static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) {
  if (info->buf == NULL) return;
  if (info->suboffsets == __Pyx_minusones) info->suboffsets = NULL;
  __Pyx_ReleaseBuffer(info);
}

static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) {
  buf->buf = NULL;
  buf->obj = NULL;
  buf->strides = __Pyx_zeros;
  buf->shape = __Pyx_zeros;
  buf->suboffsets = __Pyx_minusones;
}

static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts) {
  while (1) {
    switch (*ts) {
      case '@':
      case 10:
      case 13:
      case ' ':
        ++ts;
        break;
      case '=':
      case '<':
      case '>':
      case '!':
        PyErr_SetString(PyExc_ValueError, "Buffer acquisition error: Only native byte order, size and alignment supported.");
        return NULL;               
      default:
        return ts;
    }
  }
}

static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim) {
  PyErr_Format(PyExc_ValueError,
               "Buffer has wrong number of dimensions (expected %d, got %d)",
               expected_ndim, buffer->ndim);
}

static const char* __Pyx_DescribeTokenInFormatString(const char* ts) {
  switch (*ts) {
    case 'b': return "char";
    case 'B': return "unsigned char";
    case 'h': return "short";
    case 'H': return "unsigned short";
    case 'i': return "int";
    case 'I': return "unsigned int";
    case 'l': return "long";
    case 'L': return "unsigned long";
    case 'q': return "long long";
    case 'Q': return "unsigned long long";
    case 'f': return "float";
    case 'd': return "double";
    case 'g': return "long double";
    case 'Z': switch (*(ts+1)) {
        case 'f': return "complex float";
        case 'd': return "complex double";
        case 'g': return "complex long double";
        default: return "unparseable format string";
    }
    case 'T': return "a struct";
    case 'O': return "Python object";
    case 'P': return "a pointer";
    default: return "unparseable format string";
  }
}

static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_f32_t(const char* ts) {
    int ok;
    ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;
    if (*ts == '1') ++ts;
    switch (*ts) {
      case 'f': ok = (sizeof(__pyx_t_3svd_f32_t) == sizeof(float) && (__pyx_t_3svd_f32_t)-1 < 0); break;
      case 'd': ok = (sizeof(__pyx_t_3svd_f32_t) == sizeof(double) && (__pyx_t_3svd_f32_t)-1 < 0); break;
      case 'g': ok = (sizeof(__pyx_t_3svd_f32_t) == sizeof(long double) && (__pyx_t_3svd_f32_t)-1 < 0); break;
      default: ok = 0;
    }
    if (!(ok)) {
      PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (expected svd.f32_t, got %s)", __Pyx_DescribeTokenInFormatString(ts));
      return NULL;
    }
    ++ts;
    return ts;
  }
  
static int __Pyx_GetBuffer_nn___pyx_t_3svd_f32_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
  const char* ts;
  if (obj == Py_None) {
    __Pyx_ZeroBuffer(buf);
    return 0;
  }
  buf->buf = NULL;
  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
  if (buf->ndim != nd) {
    __Pyx_BufferNdimError(buf, nd);
    goto fail;
  }
  if (!cast) {
    ts = buf->format;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    ts = __Pyx_CheckTypestring_nn___pyx_t_3svd_f32_t(ts);
    if (!ts) goto fail;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    if (*ts != 0) {
      PyErr_Format(PyExc_ValueError,
        "Buffer dtype mismatch (expected end, got %s)",
        __Pyx_DescribeTokenInFormatString(ts));
      goto fail;
    }
  } else {
    if (buf->itemsize != sizeof(__pyx_t_3svd_f32_t)) {
      PyErr_SetString(PyExc_ValueError,
        "Attempted cast of buffer to datatype of different size.");
      goto fail;
    }
  }
  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
  return 0;
fail:;
  __Pyx_ZeroBuffer(buf);
  return -1;
}
static void __Pyx_RaiseBufferFallbackError(void) {
  PyErr_Format(PyExc_ValueError,
     "Buffer acquisition failed on assignment; and then reacquiring the old buffer failed too!");
}


static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    PyThreadState *tstate = PyThreadState_GET();

    tmp_type = tstate->curexc_type;
    tmp_value = tstate->curexc_value;
    tmp_tb = tstate->curexc_traceback;
    tstate->curexc_type = type;
    tstate->curexc_value = value;
    tstate->curexc_traceback = tb;
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
}

static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
    PyThreadState *tstate = PyThreadState_GET();
    *type = tstate->curexc_type;
    *value = tstate->curexc_value;
    *tb = tstate->curexc_traceback;

    tstate->curexc_type = 0;
    tstate->curexc_value = 0;
    tstate->curexc_traceback = 0;
}

static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i32_t(const char* ts) {
    int ok;
    ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;
    if (*ts == '1') ++ts;
    switch (*ts) {
      case 'b': ok = (sizeof(__pyx_t_3svd_i32_t) == sizeof(char) && (__pyx_t_3svd_i32_t)-1 < 0); break;
      case 'h': ok = (sizeof(__pyx_t_3svd_i32_t) == sizeof(short) && (__pyx_t_3svd_i32_t)-1 < 0); break;
      case 'i': ok = (sizeof(__pyx_t_3svd_i32_t) == sizeof(int) && (__pyx_t_3svd_i32_t)-1 < 0); break;
      case 'l': ok = (sizeof(__pyx_t_3svd_i32_t) == sizeof(long) && (__pyx_t_3svd_i32_t)-1 < 0); break;
      case 'q': ok = (sizeof(__pyx_t_3svd_i32_t) == sizeof(long long) && (__pyx_t_3svd_i32_t)-1 < 0); break;
      default: ok = 0;
    }
    if (!(ok)) {
      PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (expected svd.i32_t, got %s)", __Pyx_DescribeTokenInFormatString(ts));
      return NULL;
    }
    ++ts;
    return ts;
  }
  
static int __Pyx_GetBuffer_nn___pyx_t_3svd_i32_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
  const char* ts;
  if (obj == Py_None) {
    __Pyx_ZeroBuffer(buf);
    return 0;
  }
  buf->buf = NULL;
  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
  if (buf->ndim != nd) {
    __Pyx_BufferNdimError(buf, nd);
    goto fail;
  }
  if (!cast) {
    ts = buf->format;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    ts = __Pyx_CheckTypestring_nn___pyx_t_3svd_i32_t(ts);
    if (!ts) goto fail;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    if (*ts != 0) {
      PyErr_Format(PyExc_ValueError,
        "Buffer dtype mismatch (expected end, got %s)",
        __Pyx_DescribeTokenInFormatString(ts));
      goto fail;
    }
  } else {
    if (buf->itemsize != sizeof(__pyx_t_3svd_i32_t)) {
      PyErr_SetString(PyExc_ValueError,
        "Attempted cast of buffer to datatype of different size.");
      goto fail;
    }
  }
  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
  return 0;
fail:;
  __Pyx_ZeroBuffer(buf);
  return -1;
}static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i16_t(const char* ts) {
    int ok;
    ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;
    if (*ts == '1') ++ts;
    switch (*ts) {
      case 'b': ok = (sizeof(__pyx_t_3svd_i16_t) == sizeof(char) && (__pyx_t_3svd_i16_t)-1 < 0); break;
      case 'h': ok = (sizeof(__pyx_t_3svd_i16_t) == sizeof(short) && (__pyx_t_3svd_i16_t)-1 < 0); break;
      case 'i': ok = (sizeof(__pyx_t_3svd_i16_t) == sizeof(int) && (__pyx_t_3svd_i16_t)-1 < 0); break;
      case 'l': ok = (sizeof(__pyx_t_3svd_i16_t) == sizeof(long) && (__pyx_t_3svd_i16_t)-1 < 0); break;
      case 'q': ok = (sizeof(__pyx_t_3svd_i16_t) == sizeof(long long) && (__pyx_t_3svd_i16_t)-1 < 0); break;
      default: ok = 0;
    }
    if (!(ok)) {
      PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (expected svd.i16_t, got %s)", __Pyx_DescribeTokenInFormatString(ts));
      return NULL;
    }
    ++ts;
    return ts;
  }
  
static int __Pyx_GetBuffer_nn___pyx_t_3svd_i16_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
  const char* ts;
  if (obj == Py_None) {
    __Pyx_ZeroBuffer(buf);
    return 0;
  }
  buf->buf = NULL;
  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
  if (buf->ndim != nd) {
    __Pyx_BufferNdimError(buf, nd);
    goto fail;
  }
  if (!cast) {
    ts = buf->format;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    ts = __Pyx_CheckTypestring_nn___pyx_t_3svd_i16_t(ts);
    if (!ts) goto fail;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    if (*ts != 0) {
      PyErr_Format(PyExc_ValueError,
        "Buffer dtype mismatch (expected end, got %s)",
        __Pyx_DescribeTokenInFormatString(ts));
      goto fail;
    }
  } else {
    if (buf->itemsize != sizeof(__pyx_t_3svd_i16_t)) {
      PyErr_SetString(PyExc_ValueError,
        "Attempted cast of buffer to datatype of different size.");
      goto fail;
    }
  }
  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
  return 0;
fail:;
  __Pyx_ZeroBuffer(buf);
  return -1;
}static void __Pyx_RaiseBufferIndexError(int axis) {
  PyErr_Format(PyExc_IndexError,
     "Out of bounds on buffer access (axis %d)", axis);
}

static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i8_t(const char* ts) {
    int ok;
    ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;
    if (*ts == '1') ++ts;
    switch (*ts) {
      case 'b': ok = (sizeof(__pyx_t_3svd_i8_t) == sizeof(char) && (__pyx_t_3svd_i8_t)-1 < 0); break;
      case 'h': ok = (sizeof(__pyx_t_3svd_i8_t) == sizeof(short) && (__pyx_t_3svd_i8_t)-1 < 0); break;
      case 'i': ok = (sizeof(__pyx_t_3svd_i8_t) == sizeof(int) && (__pyx_t_3svd_i8_t)-1 < 0); break;
      case 'l': ok = (sizeof(__pyx_t_3svd_i8_t) == sizeof(long) && (__pyx_t_3svd_i8_t)-1 < 0); break;
      case 'q': ok = (sizeof(__pyx_t_3svd_i8_t) == sizeof(long long) && (__pyx_t_3svd_i8_t)-1 < 0); break;
      default: ok = 0;
    }
    if (!(ok)) {
      PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (expected svd.i8_t, got %s)", __Pyx_DescribeTokenInFormatString(ts));
      return NULL;
    }
    ++ts;
    return ts;
  }
  
static int __Pyx_GetBuffer_nn___pyx_t_3svd_i8_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
  const char* ts;
  if (obj == Py_None) {
    __Pyx_ZeroBuffer(buf);
    return 0;
  }
  buf->buf = NULL;
  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
  if (buf->ndim != nd) {
    __Pyx_BufferNdimError(buf, nd);
    goto fail;
  }
  if (!cast) {
    ts = buf->format;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    ts = __Pyx_CheckTypestring_nn___pyx_t_3svd_i8_t(ts);
    if (!ts) goto fail;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    if (*ts != 0) {
      PyErr_Format(PyExc_ValueError,
        "Buffer dtype mismatch (expected end, got %s)",
        __Pyx_DescribeTokenInFormatString(ts));
      goto fail;
    }
  } else {
    if (buf->itemsize != sizeof(__pyx_t_3svd_i8_t)) {
      PyErr_SetString(PyExc_ValueError,
        "Attempted cast of buffer to datatype of different size.");
      goto fail;
    }
  }
  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
  return 0;
fail:;
  __Pyx_ZeroBuffer(buf);
  return -1;
}static const char* __Pyx_CheckTypestring_nn___pyx_t_3svd_i64_t(const char* ts) {
    int ok;
    ts = __Pyx_ConsumeWhitespace(ts); if (!ts) return NULL;
    if (*ts == '1') ++ts;
    switch (*ts) {
      case 'b': ok = (sizeof(__pyx_t_3svd_i64_t) == sizeof(char) && (__pyx_t_3svd_i64_t)-1 < 0); break;
      case 'h': ok = (sizeof(__pyx_t_3svd_i64_t) == sizeof(short) && (__pyx_t_3svd_i64_t)-1 < 0); break;
      case 'i': ok = (sizeof(__pyx_t_3svd_i64_t) == sizeof(int) && (__pyx_t_3svd_i64_t)-1 < 0); break;
      case 'l': ok = (sizeof(__pyx_t_3svd_i64_t) == sizeof(long) && (__pyx_t_3svd_i64_t)-1 < 0); break;
      case 'q': ok = (sizeof(__pyx_t_3svd_i64_t) == sizeof(long long) && (__pyx_t_3svd_i64_t)-1 < 0); break;
      default: ok = 0;
    }
    if (!(ok)) {
      PyErr_Format(PyExc_ValueError, "Buffer dtype mismatch (expected svd.i64_t, got %s)", __Pyx_DescribeTokenInFormatString(ts));
      return NULL;
    }
    ++ts;
    return ts;
  }
  
static int __Pyx_GetBuffer_nn___pyx_t_3svd_i64_t(PyObject* obj, Py_buffer* buf, int flags, int nd, int cast) {
  const char* ts;
  if (obj == Py_None) {
    __Pyx_ZeroBuffer(buf);
    return 0;
  }
  buf->buf = NULL;
  if (__Pyx_GetBuffer(obj, buf, flags) == -1) goto fail;
  if (buf->ndim != nd) {
    __Pyx_BufferNdimError(buf, nd);
    goto fail;
  }
  if (!cast) {
    ts = buf->format;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    ts = __Pyx_CheckTypestring_nn___pyx_t_3svd_i64_t(ts);
    if (!ts) goto fail;
    ts = __Pyx_ConsumeWhitespace(ts);
    if (!ts) goto fail;
    if (*ts != 0) {
      PyErr_Format(PyExc_ValueError,
        "Buffer dtype mismatch (expected end, got %s)",
        __Pyx_DescribeTokenInFormatString(ts));
      goto fail;
    }
  } else {
    if (buf->itemsize != sizeof(__pyx_t_3svd_i64_t)) {
      PyErr_SetString(PyExc_ValueError,
        "Attempted cast of buffer to datatype of different size.");
      goto fail;
    }
  }
  if (buf->suboffsets == NULL) buf->suboffsets = __Pyx_minusones;
  return 0;
fail:;
  __Pyx_ZeroBuffer(buf);
  return -1;
}

static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
    const char *name, int exact)
{
    if (!type) {
        PyErr_Format(PyExc_SystemError, "Missing type object");
        return 0;
    }
    if (none_allowed && obj == Py_None) return 1;
    else if (exact) {
        if (Py_TYPE(obj) == type) return 1;
    }
    else {
        if (PyObject_TypeCheck(obj, type)) return 1;
    }
    PyErr_Format(PyExc_TypeError,
        "Argument '%s' has incorrect type (expected %s, got %s)",
        name, type->tp_name, Py_TYPE(obj)->tp_name);
    return 0;
}

#if PY_MAJOR_VERSION < 3
static int __Pyx_GetBuffer(PyObject *obj, Py_buffer *view, int flags) {
  #if PY_VERSION_HEX >= 0x02060000
  if (Py_TYPE(obj)->tp_flags & Py_TPFLAGS_HAVE_NEWBUFFER)
      return PyObject_GetBuffer(obj, view, flags);
  #endif
  if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) return __pyx_pf_5numpy_7ndarray___getbuffer__(obj, view, flags);
  else {
  PyErr_Format(PyExc_TypeError, "'%100s' does not have the buffer interface", Py_TYPE(obj)->tp_name);
  return -1;
    }
}

static void __Pyx_ReleaseBuffer(Py_buffer *view) {
  PyObject* obj = view->obj;
  if (obj) {
if (PyObject_TypeCheck(obj, __pyx_ptype_5numpy_ndarray)) __pyx_pf_5numpy_7ndarray___releasebuffer__(obj, view);
    Py_DECREF(obj);
    view->obj = NULL;
  }
}

#endif

static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
    PyObject *__import__ = 0;
    PyObject *empty_list = 0;
    PyObject *module = 0;
    PyObject *global_dict = 0;
    PyObject *empty_dict = 0;
    PyObject *list;
    __import__ = PyObject_GetAttrString(__pyx_b, "__import__");
    if (!__import__)
        goto bad;
    if (from_list)
        list = from_list;
    else {
        empty_list = PyList_New(0);
        if (!empty_list)
            goto bad;
        list = empty_list;
    }
    global_dict = PyModule_GetDict(__pyx_m);
    if (!global_dict)
        goto bad;
    empty_dict = PyDict_New();
    if (!empty_dict)
        goto bad;
    module = PyObject_CallFunction(__import__, "OOOO",
        name, global_dict, empty_dict, list);
bad:
    Py_XDECREF(empty_list);
    Py_XDECREF(__import__);
    Py_XDECREF(empty_dict);
    return module;
}

static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
    PyObject *result;
    result = PyObject_GetAttr(dict, name);
    if (!result)
        PyErr_SetObject(PyExc_NameError, name);
    return result;
}

static PyObject *__Pyx_CreateClass(
    PyObject *bases, PyObject *dict, PyObject *name, char *modname)
{
    PyObject *py_modname;
    PyObject *result = 0;

    #if PY_MAJOR_VERSION < 3
    py_modname = PyString_FromString(modname);
    #else
    py_modname = PyUnicode_FromString(modname);
    #endif
    if (!py_modname)
        goto bad;
    if (PyDict_SetItemString(dict, "__module__", py_modname) < 0)
        goto bad;
    #if PY_MAJOR_VERSION < 3
    result = PyClass_New(bases, dict, name);
    #else
    result = PyObject_CallFunctionObjArgs((PyObject *)&PyType_Type, name, bases, dict, NULL);
    #endif
bad:
    Py_XDECREF(py_modname);
    return result;
}

static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
    Py_XINCREF(type);
    Py_XINCREF(value);
    Py_XINCREF(tb);
    /* First, check the traceback argument, replacing None with NULL. */
    if (tb == Py_None) {
        Py_DECREF(tb);
        tb = 0;
    }
    else if (tb != NULL && !PyTraceBack_Check(tb)) {
        PyErr_SetString(PyExc_TypeError,
            "raise: arg 3 must be a traceback or None");
        goto raise_error;
    }
    /* Next, replace a missing value with None */
    if (value == NULL) {
        value = Py_None;
        Py_INCREF(value);
    }
    #if PY_VERSION_HEX < 0x02050000
    if (!PyClass_Check(type))
    #else
    if (!PyType_Check(type))
    #endif
    {
        /* Raising an instance.  The value should be a dummy. */
        if (value != Py_None) {
            PyErr_SetString(PyExc_TypeError,
                "instance exception may not have a separate value");
            goto raise_error;
        }
        /* Normalize to raise <class>, <instance> */
        Py_DECREF(value);
        value = type;
        #if PY_VERSION_HEX < 0x02050000
            if (PyInstance_Check(type)) {
                type = (PyObject*) ((PyInstanceObject*)type)->in_class;
                Py_INCREF(type);
            }
            else {
                type = 0;
                PyErr_SetString(PyExc_TypeError,
                    "raise: exception must be an old-style class or instance");
                goto raise_error;
            }
        #else
            type = (PyObject*) Py_TYPE(type);
            Py_INCREF(type);
            if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
                PyErr_SetString(PyExc_TypeError,
                    "raise: exception class must be a subclass of BaseException");
                goto raise_error;
            }
        #endif
    }
    __Pyx_ErrRestore(type, value, tb);
    return;
raise_error:
    Py_XDECREF(value);
    Py_XDECREF(type);
    Py_XDECREF(tb);
    return;
}

#if PY_MAJOR_VERSION < 3
static PyObject *__Pyx_GetStdout(void) {
    PyObject *f = PySys_GetObject("stdout");
    if (!f) {
        PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
    }
    return f;
}

static int __Pyx_Print(PyObject *arg_tuple, int newline) {
    PyObject *f;
    PyObject* v;
    int i;
    
    if (!(f = __Pyx_GetStdout()))
        return -1;
    for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
        if (PyFile_SoftSpace(f, 1)) {
            if (PyFile_WriteString(" ", f) < 0)
                return -1;
        }
        v = PyTuple_GET_ITEM(arg_tuple, i);
        if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
            return -1;
        if (PyString_Check(v)) {
            char *s = PyString_AsString(v);
            Py_ssize_t len = PyString_Size(v);
            if (len > 0 &&
                isspace(Py_CHARMASK(s[len-1])) &&
                s[len-1] != ' ')
                    PyFile_SoftSpace(f, 0);
        }
    }
    if (newline) {
        if (PyFile_WriteString("\n", f) < 0)
            return -1;
        PyFile_SoftSpace(f, 0);
    }
    return 0;
}

#else /* Python 3 has a print function */
static int __Pyx_Print(PyObject *arg_tuple, int newline) {
    PyObject* kwargs = 0;
    PyObject* result = 0;
    PyObject* end_string;
    if (!__pyx_print) {
        __pyx_print = PyObject_GetAttrString(__pyx_b, "print");
        if (!__pyx_print)
            return -1;
    }
    if (!newline) {
        if (!__pyx_print_kwargs) {
            __pyx_print_kwargs = PyDict_New();
            if (!__pyx_print_kwargs)
                return -1;
            end_string = PyUnicode_FromStringAndSize(" ", 1);
            if (!end_string)
                return -1;
            if (PyDict_SetItemString(__pyx_print_kwargs, "end", end_string) < 0) {
                Py_DECREF(end_string);
                return -1;
            }
            Py_DECREF(end_string);
        }
        kwargs = __pyx_print_kwargs;
    }
    result = PyObject_Call(__pyx_print, arg_tuple, kwargs);
    if (!result)
        return -1;
    Py_DECREF(result);
    return 0;
}
#endif

static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
    if (!type) {
        PyErr_Format(PyExc_SystemError, "Missing type object");
        return 0;
    }
    if (obj == Py_None || PyObject_TypeCheck(obj, type))
        return 1;
    PyErr_Format(PyExc_TypeError, "Cannot convert %s to %s",
        Py_TYPE(obj)->tp_name, type->tp_name);
    return 0;
}

static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
    PyThreadState *tstate = PyThreadState_GET();
    *type = tstate->exc_type;
    *value = tstate->exc_value;
    *tb = tstate->exc_traceback;
    Py_XINCREF(*type);
    Py_XINCREF(*value);
    Py_XINCREF(*tb);
}

static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    PyThreadState *tstate = PyThreadState_GET();
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = type;
    tstate->exc_value = value;
    tstate->exc_traceback = tb;
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
}

static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
    PyObject *tmp_type, *tmp_value, *tmp_tb;
    PyThreadState *tstate = PyThreadState_GET();
    __Pyx_ErrFetch(type, value, tb);
    PyErr_NormalizeException(type, value, tb);
    if (PyErr_Occurred())
        goto bad;
    Py_INCREF(*type);
    Py_INCREF(*value);
    Py_INCREF(*tb);
    tmp_type = tstate->exc_type;
    tmp_value = tstate->exc_value;
    tmp_tb = tstate->exc_traceback;
    tstate->exc_type = *type;
    tstate->exc_value = *value;
    tstate->exc_traceback = *tb;
    /* Make sure tstate is in a consistent state when we XDECREF
    these objects (XDECREF may run arbitrary code). */
    Py_XDECREF(tmp_type);
    Py_XDECREF(tmp_value);
    Py_XDECREF(tmp_tb);
    return 0;
bad:
    Py_XDECREF(*type);
    Py_XDECREF(*value);
    Py_XDECREF(*tb);
    return -1;
}


#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
    long size)
{
    PyObject *py_module = 0;
    PyObject *result = 0;
    PyObject *py_name = 0;

    py_module = __Pyx_ImportModule(module_name);
    if (!py_module)
        goto bad;
    #if PY_MAJOR_VERSION < 3
    py_name = PyString_FromString(class_name);
    #else
    py_name = PyUnicode_FromString(class_name);
    #endif
    if (!py_name)
        goto bad;
    result = PyObject_GetAttr(py_module, py_name);
    Py_DECREF(py_name);
    py_name = 0;
    Py_DECREF(py_module);
    py_module = 0;
    if (!result)
        goto bad;
    if (!PyType_Check(result)) {
        PyErr_Format(PyExc_TypeError, 
            "%s.%s is not a type object",
            module_name, class_name);
        goto bad;
    }
    if (((PyTypeObject *)result)->tp_basicsize != size) {
        PyErr_Format(PyExc_ValueError, 
            "%s.%s does not appear to be the correct type object",
            module_name, class_name);
        goto bad;
    }
    return (PyTypeObject *)result;
bad:
    Py_XDECREF(py_module);
    Py_XDECREF(result);
    return 0;
}
#endif

#ifndef __PYX_HAVE_RT_ImportModule
#define __PYX_HAVE_RT_ImportModule
static PyObject *__Pyx_ImportModule(const char *name) {
    PyObject *py_name = 0;
    PyObject *py_module = 0;

    #if PY_MAJOR_VERSION < 3
    py_name = PyString_FromString(name);
    #else
    py_name = PyUnicode_FromString(name);
    #endif
    if (!py_name)
        goto bad;
    py_module = PyImport_Import(py_name);
    Py_DECREF(py_name);
    return py_module;
bad:
    Py_XDECREF(py_name);
    return 0;
}
#endif

#include "compile.h"
#include "frameobject.h"
#include "traceback.h"

static void __Pyx_AddTraceback(const char *funcname) {
    PyObject *py_srcfile = 0;
    PyObject *py_funcname = 0;
    PyObject *py_globals = 0;
    PyObject *empty_string = 0;
    PyCodeObject *py_code = 0;
    PyFrameObject *py_frame = 0;

    #if PY_MAJOR_VERSION < 3
    py_srcfile = PyString_FromString(__pyx_filename);
    #else
    py_srcfile = PyUnicode_FromString(__pyx_filename);
    #endif
    if (!py_srcfile) goto bad;
    if (__pyx_clineno) {
        #if PY_MAJOR_VERSION < 3
        py_funcname = PyString_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
        #else
        py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, __pyx_clineno);
        #endif
    }
    else {
        #if PY_MAJOR_VERSION < 3
        py_funcname = PyString_FromString(funcname);
        #else
        py_funcname = PyUnicode_FromString(funcname);
        #endif
    }
    if (!py_funcname) goto bad;
    py_globals = PyModule_GetDict(__pyx_m);
    if (!py_globals) goto bad;
    #if PY_MAJOR_VERSION < 3
    empty_string = PyString_FromStringAndSize("", 0);
    #else
    empty_string = PyBytes_FromStringAndSize("", 0);
    #endif
    if (!empty_string) goto bad;
    py_code = PyCode_New(
        0,            /*int argcount,*/
        #if PY_MAJOR_VERSION >= 3
        0,            /*int kwonlyargcount,*/
        #endif
        0,            /*int nlocals,*/
        0,            /*int stacksize,*/
        0,            /*int flags,*/
        empty_string, /*PyObject *code,*/
        __pyx_empty_tuple,  /*PyObject *consts,*/
        __pyx_empty_tuple,  /*PyObject *names,*/
        __pyx_empty_tuple,  /*PyObject *varnames,*/
        __pyx_empty_tuple,  /*PyObject *freevars,*/
        __pyx_empty_tuple,  /*PyObject *cellvars,*/
        py_srcfile,   /*PyObject *filename,*/
        py_funcname,  /*PyObject *name,*/
        __pyx_lineno,   /*int firstlineno,*/
        empty_string  /*PyObject *lnotab*/
    );
    if (!py_code) goto bad;
    py_frame = PyFrame_New(
        PyThreadState_GET(), /*PyThreadState *tstate,*/
        py_code,             /*PyCodeObject *code,*/
        py_globals,          /*PyObject *globals,*/
        0                    /*PyObject *locals*/
    );
    if (!py_frame) goto bad;
    py_frame->f_lineno = __pyx_lineno;
    PyTraceBack_Here(py_frame);
bad:
    Py_XDECREF(py_srcfile);
    Py_XDECREF(py_funcname);
    Py_XDECREF(empty_string);
    Py_XDECREF(py_code);
    Py_XDECREF(py_frame);
}

static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
    while (t->p) {
        #if PY_MAJOR_VERSION < 3
        if (t->is_unicode && (!t->is_identifier)) {
            *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
        } else if (t->intern) {
            *t->p = PyString_InternFromString(t->s);
        } else {
            *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
        }
        #else  /* Python 3+ has unicode identifiers */
        if (t->is_identifier || (t->is_unicode && t->intern)) {
            *t->p = PyUnicode_InternFromString(t->s);
        } else if (t->is_unicode) {
            *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
        } else {
            *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
        }
        #endif
        if (!*t->p)
            return -1;
        ++t;
    }
    return 0;
}

/* Type Conversion Functions */

static INLINE Py_ssize_t __pyx_PyIndex_AsSsize_t(PyObject* b) {
  Py_ssize_t ival;
  PyObject* x = PyNumber_Index(b);
  if (!x) return -1;
  ival = PyInt_AsSsize_t(x);
  Py_DECREF(x);
  return ival;
}

static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
   if (x == Py_True) return 1;
   else if (x == Py_False) return 0;
   else return PyObject_IsTrue(x);
}

static INLINE PY_LONG_LONG __pyx_PyInt_AsLongLong(PyObject* x) {
    if (PyInt_CheckExact(x)) {
        return PyInt_AS_LONG(x);
    }
    else if (PyLong_CheckExact(x)) {
        return PyLong_AsLongLong(x);
    }
    else {
        PY_LONG_LONG val;
        PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
        val = __pyx_PyInt_AsLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}

static INLINE unsigned PY_LONG_LONG __pyx_PyInt_AsUnsignedLongLong(PyObject* x) {
    if (PyInt_CheckExact(x)) {
        long val = PyInt_AS_LONG(x);
        if (unlikely(val < 0)) {
            PyErr_SetString(PyExc_TypeError, "Negative assignment to unsigned type.");
            return (unsigned PY_LONG_LONG)-1;
        }
        return val;
    }
    else if (PyLong_CheckExact(x)) {
        return PyLong_AsUnsignedLongLong(x);
    }
    else {
        PY_LONG_LONG val;
        PyObject* tmp = PyNumber_Int(x); if (!tmp) return (PY_LONG_LONG)-1;
        val = __pyx_PyInt_AsUnsignedLongLong(tmp);
        Py_DECREF(tmp);
        return val;
    }
}


static INLINE unsigned char __pyx_PyInt_unsigned_char(PyObject* x) {
    if (sizeof(unsigned char) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        unsigned char val = (unsigned char)long_val;
        if (unlikely((val != long_val)  || (long_val < 0))) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned char");
            return (unsigned char)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE unsigned short __pyx_PyInt_unsigned_short(PyObject* x) {
    if (sizeof(unsigned short) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        unsigned short val = (unsigned short)long_val;
        if (unlikely((val != long_val)  || (long_val < 0))) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to unsigned short");
            return (unsigned short)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE char __pyx_PyInt_char(PyObject* x) {
    if (sizeof(char) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        char val = (char)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to char");
            return (char)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE short __pyx_PyInt_short(PyObject* x) {
    if (sizeof(short) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        short val = (short)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to short");
            return (short)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE int __pyx_PyInt_int(PyObject* x) {
    if (sizeof(int) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        int val = (int)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to int");
            return (int)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE long __pyx_PyInt_long(PyObject* x) {
    if (sizeof(long) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        long val = (long)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to long");
            return (long)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE signed char __pyx_PyInt_signed_char(PyObject* x) {
    if (sizeof(signed char) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        signed char val = (signed char)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed char");
            return (signed char)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE signed short __pyx_PyInt_signed_short(PyObject* x) {
    if (sizeof(signed short) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        signed short val = (signed short)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed short");
            return (signed short)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE signed int __pyx_PyInt_signed_int(PyObject* x) {
    if (sizeof(signed int) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        signed int val = (signed int)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed int");
            return (signed int)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE signed long __pyx_PyInt_signed_long(PyObject* x) {
    if (sizeof(signed long) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        signed long val = (signed long)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to signed long");
            return (signed long)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

static INLINE long double __pyx_PyInt_long_double(PyObject* x) {
    if (sizeof(long double) < sizeof(long)) {
        long long_val = __pyx_PyInt_AsLong(x);
        long double val = (long double)long_val;
        if (unlikely((val != long_val) )) {
            PyErr_SetString(PyExc_OverflowError, "value too large to convert to long double");
            return (long double)-1;
        }
        return val;
    }
    else {
        return __pyx_PyInt_AsLong(x);
    }
}

