.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/cython/plot_08_vector_ops_without_numpy.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via JupyterLite or Binder. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_cython_plot_08_vector_ops_without_numpy.py: Vector ops without NumPy: array('d') + memoryviews ================================================== .. currentmodule:: scikitplot.cython You can write fast numeric code without NumPy using Python's ``array`` module and typed memoryviews. Why this works -------------- ``array('d')`` exposes the buffer protocol, so Cython can view its memory as a contiguous ``double[:]`` without copying. This example scales a vector in-place and demonstrates: - typed memoryviews (``double[:]``) - strict input validation (buffer-compatible, correct itemsize) - optional compiler directives for speed (boundscheck/wraparound) Notes ----- This example does not require NumPy. .. GENERATED FROM PYTHON SOURCE LINES 25-29 .. code-block:: Python # Authors: The scikit-plots developers # SPDX-License-Identifier: BSD-3-Clause .. GENERATED FROM PYTHON SOURCE LINES 30-37 .. code-block:: Python from __future__ import annotations from array import array from typing import Iterable from scikitplot import cython .. GENERATED FROM PYTHON SOURCE LINES 38-46 .. code-block:: Python def py_scale(x: array, a: float) -> None: """Pure-Python baseline: scale in-place.""" for i in range(len(x)): x[i] *= a .. GENERATED FROM PYTHON SOURCE LINES 47-49 Generate `python` Module from `cython` -------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 49-126 .. code-block:: Python report = cython.check_build_prereqs(numpy=False) if not report.get('cython', {}).get('ok'): print("Skipping compilation because build prerequisites are missing.") problems = report.get("problems", []) if problems: print("Problems:", problems) else: code = r""" # cython: language_level=3 # cython: boundscheck=False # cython: wraparound=False def scale(double[:] x, double a): '''Scale a 1D contiguous vector in-place.''' cdef Py_ssize_t i cdef Py_ssize_t n = x.shape[0] for i in range(n): x[i] *= a return None def scaled_copy(double[:] x, double a): cdef Py_ssize_t i cdef Py_ssize_t n = x.shape[0] out = [0.0] * n for i in range(n): out[i] = x[i] * a return out """ # Use result API so we can show cache metadata. r = cython.compile_and_load_result( code, module_name="memview_scale_demo", profile="fast-debug", numpy_support=False, verbose=0, ) m = r.module print("Build key:", r.key) print("Artifact :", r.artifact_path) # ------------------------------------------------------------ # Strict demo: array('d') is buffer-compatible with double[:] # ------------------------------------------------------------ x = array("d", [1.0, 2.0, 3.0]) # Educational sanity checks (strict, no heuristics). print("\nInput type:", type(x).__name__) print("Typecode :", x.typecode) print("Length :", len(x)) # Run compiled scaling. m.scale(x, 10.0) print("After Cython scale:", list(x)) print("Expected :", [10.0, 20.0, 30.0]) # ------------------------------------------------------------ # Baseline: pure Python scaling (for learning) # ------------------------------------------------------------ y = array("d", [1.0, 2.0, 3.0]) py_scale(y, 10.0) print("\nAfter Python scale:", list(y)) # ------------------------------------------------------------ # Strict edge case: wrong typecode (will raise TypeError) # ------------------------------------------------------------ z = array("f", [1.0, 2.0, 3.0]) # float32 try: m.scale(z, 2.0) print("Unexpected: scale accepted array('f').") except Exception as e: print("\nAs expected, scale rejected array('f'):") print(" ", type(e).__name__ + ":", e) .. rst-class:: sphx-glr-script-out .. code-block:: none Build key: a5d91a9aca8a988403003d9feb13944b8dbca7eb8f0ac8a20b86cef8a1ac9a94 Artifact : /home/circleci/.cache/scikitplot/cython/a5d91a9aca8a988403003d9feb13944b8dbca7eb8f0ac8a20b86cef8a1ac9a94/memview_scale_demo.cpython-311-x86_64-linux-gnu.so Input type: array Typecode : d Length : 3 After Cython scale: [10.0, 20.0, 30.0] Expected : [10.0, 20.0, 30.0] After Python scale: [10.0, 20.0, 30.0] As expected, scale rejected array('f'): ValueError: Buffer dtype mismatch, expected 'double' but got 'float' .. GENERATED FROM PYTHON SOURCE LINES 127-132 .. tags:: domain: cython plot-type: cython purpose: showcase .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.853 seconds) .. _sphx_glr_download_auto_examples_cython_plot_08_vector_ops_without_numpy.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/scikit-plots/scikit-plots/main?urlpath=lab/tree/notebooks/auto_examples/cython/plot_08_vector_ops_without_numpy.ipynb :alt: Launch binder :width: 150 px .. container:: lite-badge .. image:: images/jupyterlite_badge_logo.svg :target: ../../lite/lab/index.html?path=auto_examples/cython/plot_08_vector_ops_without_numpy.ipynb :alt: Launch JupyterLite :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_08_vector_ops_without_numpy.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_08_vector_ops_without_numpy.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_08_vector_ops_without_numpy.zip ` .. include:: plot_08_vector_ops_without_numpy.recommendations .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_