prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  MemoryError when trying to convert TfIdf
  Hello
  Got an exception when trying to export a pipeline with a TfIdf : 
  Exception "unhandled MemoryError"
      cv = CountVectorizer()
      tt = TfidfTransformer()
      lsvc = LinearSVC(penalty=penalty, dual=False, tol=1e-3)
      text_clf = Pipeline([ 
          ('vect', cv),
          ('tfidf', tt),
          ('clf', lsvc),
      ])
      text_clf.fit(twenty_train.data, twenty_train.target) 
      print("Converting text_clf to onnx...")
      onnx = convert_sklearn(text_clf, target_opset=9, name='DocClassifierCV-Tfidf-LSVC', 
        initial_types=[('input', StringTensorType())]
        )
  
  Exception "unhandled MemoryError"
  
  The stack is:
  
  convert_sklearn()
  
  convert_topology() : 
              _registration.get_converter(operator.type)(scope, operator, container)
  
  convert_sklearn_tfidf_transformer()
          if not isinstance(cst, numpy.ndarray):
              cst = numpy.array(cst.todense())
  
  toDense()
       return np.asmatrix(self.toarray(order=order, out=out))
  
  _process_toarray_args()
        return np.zeros(self.shape, dtype=self.dtype, order=order)
  
  Could make sens : the input sparse matrix is (strangely) 130000 per 130000, pretty big to be densified.
  
  
  </issue>
  <code>
  [start of skl2onnx/operator_converters/TfIdfTransformer.py]
  1 # -------------------------------------------------------------------------
  2 # Copyright (c) Microsoft Corporation. All rights reserved.
  3 # Licensed under the MIT License. See License.txt in the project root for
  4 # license information.
  5 # --------------------------------------------------------------------------
  6 
  7 import numpy
  8 import numbers
  9 import warnings
  10 from ..common._registration import register_converter
  11 from ..common._apply_operation import apply_log, apply_add, apply_mul, apply_identity
  12 from ..proto import onnx_proto
  13 
  14 
  15 def convert_sklearn_tfidf_transformer(scope, operator, container):
  16     # TODO: use sparse containers when available
  17     op = operator.raw_operator
  18     data = operator.input_full_names
  19     final = operator.output_full_names
  20     C = operator.inputs[0].type.shape[1]
  21     
  22     if op.sublinear_tf:
  23         # code scikit-learn
  24         # np.log(X.data, X.data) --> does not apply on null coefficient
  25         # X.data += 1
  26         raise RuntimeError("ONNX does not support sparse tensors, sublinear_tf must be False")
  27             
  28         logged = scope.get_unique_variable_name('logged')
  29         apply_log(scope, data, logged, container)
  30         
  31         if not op.use_idf and op.norm is None:
  32             loggedplus1 = final
  33         else:
  34             loggedplus1 = scope.get_unique_variable_name('loggedplus1')
  35         ones = scope.get_unique_variable_name('ones')
  36         cst = numpy.ones((C,), dtype=numpy.float32)
  37         container.add_initializer(ones, onnx_proto.TensorProto.FLOAT, [C], cst.flatten())        
  38         apply_add(scope, [logged, ones], loggedplus1, container, broadcast=1)
  39         
  40         data = [loggedplus1]
  41     
  42     if op.use_idf:
  43         # code scikit-learn
  44         # X = X * self._idf_diag
  45         cst = op._idf_diag.astype(numpy.float32)
  46         if not isinstance(cst, numpy.ndarray):
  47             cst = numpy.array(cst.todense())
  48         if len(cst.shape) > 1:
  49             cst = numpy.diag(cst)
  50         cst = cst.ravel().flatten()
  51         shape = [len(cst)]
  52         idfcst = scope.get_unique_variable_name('idfcst')
  53         container.add_initializer(idfcst, onnx_proto.TensorProto.FLOAT, shape, cst)
  54         idfed = final if op.norm is None else scope.get_unique_variable_name('idfed')
  55         apply_mul(scope, data + [idfcst], idfed, container, broadcast=1)
  56         data = [idfed]
  57 
  58     if op.norm is not None:
  59         op_type = 'Normalizer'
  60         norm_map = {'max': 'MAX', 'l1': 'L1', 'l2': 'L2'}
  61         attrs = {'name': scope.get_unique_operator_name(op_type)}
  62         if op.norm in norm_map:
  63             attrs['norm'] = norm_map[op.norm]
  64         else:
  65             raise RuntimeError('Invalid norm: %s' % op.norm)
  66 
  67         container.add_node(op_type, data, operator.output_full_names, op_domain='ai.onnx.ml', **attrs)
  68         data = None
  69         
  70     if data == operator.input_full_names:
  71         # Nothing happened --> identity
  72         apply_identity(scope, data, final, container)
  73 
  74 
  75 register_converter('SklearnTfidfTransformer', convert_sklearn_tfidf_transformer)
  76
  [end of skl2onnx/operator_converters/TfIdfTransformer.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/skl2onnx/operator_converters/TfIdfTransformer.py b/skl2onnx/operator_converters/TfIdfTransformer.py
  --- a/skl2onnx/operator_converters/TfIdfTransformer.py
  +++ b/skl2onnx/operator_converters/TfIdfTransformer.py
  @@ -4,9 +4,10 @@
   # license information.
   # --------------------------------------------------------------------------
   
  -import numpy
   import numbers
   import warnings
  +import numpy
  +from scipy.sparse import diags
   from ..common._registration import register_converter
   from ..common._apply_operation import apply_log, apply_add, apply_mul, apply_identity
   from ..proto import onnx_proto
  @@ -44,7 +45,11 @@
           # X = X * self._idf_diag
           cst = op._idf_diag.astype(numpy.float32)
           if not isinstance(cst, numpy.ndarray):
  -            cst = numpy.array(cst.todense())
  +            if len(cst.shape) > 1:
  +                n = cst.shape[0]
  +                cst = numpy.array([cst[i, i] for i in range(n)])
  +            else:
  +                cst = numpy.array(cst.todense())
           if len(cst.shape) > 1:
               cst = numpy.diag(cst)
           cst = cst.ravel().flatten()
  
verification_info: {"golden_diff": "diff --git a/skl2onnx/operator_converters/TfIdfTransformer.py b/skl2onnx/operator_converters/TfIdfTransformer.py\n--- a/skl2onnx/operator_converters/TfIdfTransformer.py\n+++ b/skl2onnx/operator_converters/TfIdfTransformer.py\n@@ -4,9 +4,10 @@\n # license information.\n # --------------------------------------------------------------------------\n \n-import numpy\n import numbers\n import warnings\n+import numpy\n+from scipy.sparse import diags\n from ..common._registration import register_converter\n from ..common._apply_operation import apply_log, apply_add, apply_mul, apply_identity\n from ..proto import onnx_proto\n@@ -44,7 +45,11 @@\n         # X = X * self._idf_diag\n         cst = op._idf_diag.astype(numpy.float32)\n         if not isinstance(cst, numpy.ndarray):\n-            cst = numpy.array(cst.todense())\n+            if len(cst.shape) > 1:\n+                n = cst.shape[0]\n+                cst = numpy.array([cst[i, i] for i in range(n)])\n+            else:\n+                cst = numpy.array(cst.todense())\n         if len(cst.shape) > 1:\n             cst = numpy.diag(cst)\n         cst = cst.ravel().flatten()\n", "issue": "MemoryError when trying to convert TfIdf\nHello\r\nGot an exception when trying to export a pipeline with a TfIdf : \r\nException \"unhandled MemoryError\"\r\n    cv = CountVectorizer()\r\n    tt = TfidfTransformer()\r\n    lsvc = LinearSVC(penalty=penalty, dual=False, tol=1e-3)\r\n    text_clf = Pipeline([ \r\n        ('vect', cv),\r\n        ('tfidf', tt),\r\n        ('clf', lsvc),\r\n    ])\r\n    text_clf.fit(twenty_train.data, twenty_train.target) \r\n    print(\"Converting text_clf to onnx...\")\r\n    onnx = convert_sklearn(text_clf, target_opset=9, name='DocClassifierCV-Tfidf-LSVC', \r\n      initial_types=[('input', StringTensorType())]\r\n      )\r\n\r\nException \"unhandled MemoryError\"\r\n\r\nThe stack is:\r\n\r\nconvert_sklearn()\r\n\r\nconvert_topology() : \r\n            _registration.get_converter(operator.type)(scope, operator, container)\r\n\r\nconvert_sklearn_tfidf_transformer()\r\n        if not isinstance(cst, numpy.ndarray):\r\n            cst = numpy.array(cst.todense())\r\n\r\ntoDense()\r\n     return np.asmatrix(self.toarray(order=order, out=out))\r\n\r\n_process_toarray_args()\r\n      return np.zeros(self.shape, dtype=self.dtype, order=order)\r\n\r\nCould make sens : the input sparse matrix is (strangely) 130000 per 130000, pretty big to be densified.\r\n\n", "before_files": [{"content": "# -------------------------------------------------------------------------\n# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License. See License.txt in the project root for\n# license information.\n# --------------------------------------------------------------------------\n\nimport numpy\nimport numbers\nimport warnings\nfrom ..common._registration import register_converter\nfrom ..common._apply_operation import apply_log, apply_add, apply_mul, apply_identity\nfrom ..proto import onnx_proto\n\n\ndef convert_sklearn_tfidf_transformer(scope, operator, container):\n    # TODO: use sparse containers when available\n    op = operator.raw_operator\n    data = operator.input_full_names\n    final = operator.output_full_names\n    C = operator.inputs[0].type.shape[1]\n    \n    if op.sublinear_tf:\n        # code scikit-learn\n        # np.log(X.data, X.data) --> does not apply on null coefficient\n        # X.data += 1\n        raise RuntimeError(\"ONNX does not support sparse tensors, sublinear_tf must be False\")\n            \n        logged = scope.get_unique_variable_name('logged')\n        apply_log(scope, data, logged, container)\n        \n        if not op.use_idf and op.norm is None:\n            loggedplus1 = final\n        else:\n            loggedplus1 = scope.get_unique_variable_name('loggedplus1')\n        ones = scope.get_unique_variable_name('ones')\n        cst = numpy.ones((C,), dtype=numpy.float32)\n        container.add_initializer(ones, onnx_proto.TensorProto.FLOAT, [C], cst.flatten())        \n        apply_add(scope, [logged, ones], loggedplus1, container, broadcast=1)\n        \n        data = [loggedplus1]\n    \n    if op.use_idf:\n        # code scikit-learn\n        # X = X * self._idf_diag\n        cst = op._idf_diag.astype(numpy.float32)\n        if not isinstance(cst, numpy.ndarray):\n            cst = numpy.array(cst.todense())\n        if len(cst.shape) > 1:\n            cst = numpy.diag(cst)\n        cst = cst.ravel().flatten()\n        shape = [len(cst)]\n        idfcst = scope.get_unique_variable_name('idfcst')\n        container.add_initializer(idfcst, onnx_proto.TensorProto.FLOAT, shape, cst)\n        idfed = final if op.norm is None else scope.get_unique_variable_name('idfed')\n        apply_mul(scope, data + [idfcst], idfed, container, broadcast=1)\n        data = [idfed]\n\n    if op.norm is not None:\n        op_type = 'Normalizer'\n        norm_map = {'max': 'MAX', 'l1': 'L1', 'l2': 'L2'}\n        attrs = {'name': scope.get_unique_operator_name(op_type)}\n        if op.norm in norm_map:\n            attrs['norm'] = norm_map[op.norm]\n        else:\n            raise RuntimeError('Invalid norm: %s' % op.norm)\n\n        container.add_node(op_type, data, operator.output_full_names, op_domain='ai.onnx.ml', **attrs)\n        data = None\n        \n    if data == operator.input_full_names:\n        # Nothing happened --> identity\n        apply_identity(scope, data, final, container)\n\n\nregister_converter('SklearnTfidfTransformer', convert_sklearn_tfidf_transformer)\n", "path": "skl2onnx/operator_converters/TfIdfTransformer.py"}]}