example on manually vectorizing numpy code (closes #27)
diff --git a/docs/advanced.rst b/docs/advanced.rst
index 4683c70..d87abc8 100644
--- a/docs/advanced.rst
+++ b/docs/advanced.rst
@@ -473,6 +473,11 @@
     Patient != 0) and ``with_custodian_and_ward_postcall`` (if Nurse/Patient ==
     0) policies from Boost.Python.
 
+.. seealso::
+
+    The file :file:`example/example13.cpp` contains a complete example that
+    demonstrates using :class:`keep_alive` in more detail.
+
 Implicit type conversions
 =========================
 
@@ -850,6 +855,55 @@
         }
     );
 
+In cases where the computation is too complicated to be reduced to
+``vectorize``, it will be necessary to create and access the buffer contents
+manually. The following snippet contains a complete example that shows how this
+works (the code is somewhat contrived, since it could have been done more
+simply using ``vectorize``).
+
+.. code-block:: cpp
+
+    #include <pybind11/pybind11.h>
+    #include <pybind11/numpy.h>
+
+    namespace py = pybind11;
+
+    py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
+        auto buf1 = input1.request(), buf2 = input2.request();
+
+        if (buf1.ndim != 1 || buf2.ndim != 1)
+            throw std::runtime_error("Number of dimensions must be one");
+
+        if (buf1.shape[0] != buf2.shape[0])
+            throw std::runtime_error("Input shapes must match");
+
+        auto result = py::array(py::buffer_info(
+            nullptr,            /* Pointer to data (nullptr -> ask NumPy to allocate!) */
+            sizeof(double),     /* Size of one item */
+            py::format_descriptor<double>::value(), /* Buffer format */
+            buf1.ndim,          /* How many dimensions? */
+            { buf1.shape[0] },  /* Number of elements for each dimension */
+            { sizeof(double) }  /* Strides for each dimension */
+        ));
+
+        auto buf3 = result.request();
+
+        double *ptr1 = (double *) buf1.ptr,
+               *ptr2 = (double *) buf2.ptr,
+               *ptr3 = (double *) buf3.ptr;
+
+        for (size_t idx = 0; idx < buf1.shape[0]; idx++)
+            ptr3[idx] = ptr1[idx] + ptr2[idx];
+
+        return result;
+    }
+
+    PYBIND11_PLUGIN(test) {
+        py::module m("test");
+        m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
+        return m.ptr();
+    }
+
 .. seealso::
 
     The file :file:`example/example10.cpp` contains a complete example that