Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 836d2b0

Browse files
authored
Merge pull request #27066 from QuLogic/array_view-pybind11
Tweak array_view to be more like pybind11
2 parents 62b252e + 343fa13 commit 836d2b0

File tree

9 files changed

+100
-75
lines changed

9 files changed

+100
-75
lines changed

lib/matplotlib/tests/test_transforms.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,9 @@ def test_invalid_arguments():
627627
t.transform([])
628628
with pytest.raises(RuntimeError):
629629
t.transform([1])
630-
with pytest.raises(RuntimeError):
630+
with pytest.raises(ValueError):
631631
t.transform([[1]])
632-
with pytest.raises(RuntimeError):
632+
with pytest.raises(ValueError):
633633
t.transform([[1, 2, 3]])
634634

635635

src/_backend_agg.h

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -731,22 +731,22 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
731731
rendererBase.reset_clipping(true);
732732
if (angle != 0.0) {
733733
agg::rendering_buffer srcbuf(
734-
image.data(), (unsigned)image.dim(1),
735-
(unsigned)image.dim(0), (unsigned)image.dim(1));
734+
image.data(), (unsigned)image.shape(1),
735+
(unsigned)image.shape(0), (unsigned)image.shape(1));
736736
agg::pixfmt_gray8 pixf_img(srcbuf);
737737

738738
set_clipbox(gc.cliprect, theRasterizer);
739739

740740
agg::trans_affine mtx;
741-
mtx *= agg::trans_affine_translation(0, -image.dim(0));
741+
mtx *= agg::trans_affine_translation(0, -image.shape(0));
742742
mtx *= agg::trans_affine_rotation(-angle * (agg::pi / 180.0));
743743
mtx *= agg::trans_affine_translation(x, y);
744744

745745
agg::path_storage rect;
746746
rect.move_to(0, 0);
747-
rect.line_to(image.dim(1), 0);
748-
rect.line_to(image.dim(1), image.dim(0));
749-
rect.line_to(0, image.dim(0));
747+
rect.line_to(image.shape(1), 0);
748+
rect.line_to(image.shape(1), image.shape(0));
749+
rect.line_to(0, image.shape(0));
750750
rect.line_to(0, 0);
751751
agg::conv_transform<agg::path_storage> rect2(rect, mtx);
752752

@@ -767,10 +767,10 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
767767
} else {
768768
agg::rect_i fig, text;
769769

770-
int deltay = y - image.dim(0);
770+
int deltay = y - image.shape(0);
771771

772772
fig.init(0, 0, width, height);
773-
text.init(x, deltay, x + image.dim(1), y);
773+
text.init(x, deltay, x + image.shape(1), y);
774774
text.clip(fig);
775775

776776
if (gc.cliprect.x1 != 0.0 || gc.cliprect.y1 != 0.0 || gc.cliprect.x2 != 0.0 || gc.cliprect.y2 != 0.0) {
@@ -832,19 +832,19 @@ inline void RendererAgg::draw_image(GCAgg &gc,
832832

833833
agg::rendering_buffer buffer;
834834
buffer.attach(
835-
image.data(), (unsigned)image.dim(1), (unsigned)image.dim(0), -(int)image.dim(1) * 4);
835+
image.data(), (unsigned)image.shape(1), (unsigned)image.shape(0), -(int)image.shape(1) * 4);
836836
pixfmt pixf(buffer);
837837

838838
if (has_clippath) {
839839
agg::trans_affine mtx;
840840
agg::path_storage rect;
841841

842-
mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.dim(0))));
842+
mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.shape(0))));
843843

844844
rect.move_to(0, 0);
845-
rect.line_to(image.dim(1), 0);
846-
rect.line_to(image.dim(1), image.dim(0));
847-
rect.line_to(0, image.dim(0));
845+
rect.line_to(image.shape(1), 0);
846+
rect.line_to(image.shape(1), image.shape(0));
847+
rect.line_to(0, image.shape(0));
848848
rect.line_to(0, 0);
849849

850850
agg::conv_transform<agg::path_storage> rect2(rect, mtx);
@@ -880,7 +880,7 @@ inline void RendererAgg::draw_image(GCAgg &gc,
880880
} else {
881881
set_clipbox(gc.cliprect, rendererBase);
882882
rendererBase.blend_from(
883-
pixf, 0, (int)x, (int)(height - (y + image.dim(0))), (agg::int8u)(alpha * 255));
883+
pixf, 0, (int)x, (int)(height - (y + image.shape(0))), (agg::int8u)(alpha * 255));
884884
}
885885

886886
rendererBase.reset_clipping(true);
@@ -918,15 +918,15 @@ inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
918918
typedef agg::conv_curve<clipped_t> curve_t;
919919

920920
size_t Npaths = path_generator.num_paths();
921-
size_t Noffsets = offsets.size();
921+
size_t Noffsets = safe_first_shape(offsets);
922922
size_t N = std::max(Npaths, Noffsets);
923923

924-
size_t Ntransforms = transforms.size();
925-
size_t Nfacecolors = facecolors.size();
926-
size_t Nedgecolors = edgecolors.size();
927-
size_t Nlinewidths = linewidths.size();
924+
size_t Ntransforms = safe_first_shape(transforms);
925+
size_t Nfacecolors = safe_first_shape(facecolors);
926+
size_t Nedgecolors = safe_first_shape(edgecolors);
927+
size_t Nlinewidths = safe_first_shape(linewidths);
928928
size_t Nlinestyles = std::min(linestyles.size(), N);
929-
size_t Naa = antialiaseds.size();
929+
size_t Naa = safe_first_shape(antialiaseds);
930930

931931
if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) {
932932
return;
@@ -1234,7 +1234,7 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12341234
set_clipbox(gc.cliprect, theRasterizer);
12351235
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
12361236

1237-
for (int i = 0; i < points.dim(0); ++i) {
1237+
for (int i = 0; i < points.shape(0); ++i) {
12381238
typename PointArray::sub_t point = points.subarray(i);
12391239
typename ColorArray::sub_t color = colors.subarray(i);
12401240

src/_backend_agg_wrapper.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,17 +456,17 @@ PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args)
456456
&trans)) {
457457
return NULL;
458458
}
459-
if (points.size() && !check_trailing_shape(points, "points", 3, 2)) {
459+
if (points.shape(0) && !check_trailing_shape(points, "points", 3, 2)) {
460460
return NULL;
461461
}
462-
if (colors.size() && !check_trailing_shape(colors, "colors", 3, 4)) {
462+
if (colors.shape(0) && !check_trailing_shape(colors, "colors", 3, 4)) {
463463
return NULL;
464464
}
465-
if (points.size() != colors.size()) {
465+
if (points.shape(0) != colors.shape(0)) {
466466
PyErr_Format(PyExc_ValueError,
467467
"points and colors arrays must be the same length, got "
468468
"%" NPY_INTP_FMT " points and %" NPY_INTP_FMT "colors",
469-
points.dim(0), colors.dim(0));
469+
points.shape(0), colors.shape(0));
470470
return NULL;
471471
}
472472

src/_path.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void point_in_path_impl(PointArray &points, PathIterator &path, ResultArray &ins
113113
size_t i;
114114
bool all_done;
115115

116-
size_t n = points.size();
116+
size_t n = safe_first_shape(points);
117117

118118
std::vector<uint8_t> yflag0(n);
119119
std::vector<uint8_t> subpath_flag(n);
@@ -247,7 +247,7 @@ inline void points_in_path(PointArray &points,
247247
typedef agg::conv_contour<curve_t> contour_t;
248248

249249
size_t i;
250-
for (i = 0; i < points.size(); ++i) {
250+
for (i = 0; i < safe_first_shape(points); ++i) {
251251
result[i] = false;
252252
}
253253

@@ -379,14 +379,14 @@ void get_path_collection_extents(agg::trans_affine &master_transform,
379379
agg::trans_affine &offset_trans,
380380
extent_limits &extent)
381381
{
382-
if (offsets.size() != 0 && offsets.dim(1) != 2) {
382+
if (offsets.size() != 0 && offsets.shape(1) != 2) {
383383
throw std::runtime_error("Offsets array must have shape (N, 2)");
384384
}
385385

386386
size_t Npaths = paths.size();
387-
size_t Noffsets = offsets.size();
387+
size_t Noffsets = safe_first_shape(offsets);
388388
size_t N = std::max(Npaths, Noffsets);
389-
size_t Ntransforms = std::min(transforms.size(), N);
389+
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
390390
size_t i;
391391

392392
agg::trans_affine trans;
@@ -436,9 +436,9 @@ void point_in_path_collection(double x,
436436
return;
437437
}
438438

439-
size_t Noffsets = offsets.size();
439+
size_t Noffsets = safe_first_shape(offsets);
440440
size_t N = std::max(Npaths, Noffsets);
441-
size_t Ntransforms = std::min(transforms.size(), N);
441+
size_t Ntransforms = std::min(safe_first_shape(transforms), N);
442442
size_t i;
443443

444444
agg::trans_affine trans;
@@ -709,11 +709,11 @@ clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vecto
709709
template <class VerticesArray, class ResultArray>
710710
void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
711711
{
712-
if (vertices.size() != 0 && vertices.dim(1) != 2) {
712+
if (vertices.size() != 0 && vertices.shape(1) != 2) {
713713
throw std::runtime_error("Invalid vertices array.");
714714
}
715715

716-
size_t n = vertices.size();
716+
size_t n = vertices.shape(0);
717717
double x;
718718
double y;
719719
double t0;
@@ -739,7 +739,7 @@ void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, Resu
739739
template <class VerticesArray, class ResultArray>
740740
void affine_transform_1d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
741741
{
742-
if (vertices.dim(0) != 2) {
742+
if (vertices.shape(0) != 2) {
743743
throw std::runtime_error("Invalid vertices array.");
744744
}
745745

@@ -776,7 +776,7 @@ int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
776776
std::swap(a.y1, a.y2);
777777
}
778778

779-
size_t num_bboxes = bboxes.size();
779+
size_t num_bboxes = safe_first_shape(bboxes);
780780
for (size_t i = 0; i < num_bboxes; ++i) {
781781
b = agg::rect_d(bboxes(i, 0, 0), bboxes(i, 0, 1), bboxes(i, 1, 0), bboxes(i, 1, 1));
782782

src/_path_wrapper.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ static PyObject *Py_points_in_path(PyObject *self, PyObject *args)
8383
return NULL;
8484
}
8585

86-
npy_intp dims[] = { (npy_intp)points.size() };
86+
if (!check_trailing_shape(points, "points", 2)) {
87+
return NULL;
88+
}
89+
90+
npy_intp dims[] = { (npy_intp)points.shape(0) };
8791
numpy::array_view<uint8_t, 1> results(dims);
8892

8993
CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results)));
@@ -118,10 +122,10 @@ static PyObject *Py_update_path_extents(PyObject *self, PyObject *args)
118122
return NULL;
119123
}
120124

121-
if (minpos.dim(0) != 2) {
125+
if (minpos.shape(0) != 2) {
122126
PyErr_Format(PyExc_ValueError,
123127
"minpos must be of length 2, got %" NPY_INTP_FMT,
124-
minpos.dim(0));
128+
minpos.shape(0));
125129
return NULL;
126130
}
127131

@@ -361,15 +365,19 @@ static PyObject *Py_affine_transform(PyObject *self, PyObject *args)
361365
numpy::array_view<double, 2> vertices(vertices_arr);
362366
Py_DECREF(vertices_arr);
363367

364-
npy_intp dims[] = { (npy_intp)vertices.size(), 2 };
368+
if(!check_trailing_shape(vertices, "vertices", 2)) {
369+
return NULL;
370+
}
371+
372+
npy_intp dims[] = { (npy_intp)vertices.shape(0), 2 };
365373
numpy::array_view<double, 2> result(dims);
366374
CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
367375
return result.pyobj();
368376
} else { // PyArray_NDIM(vertices_arr) == 1
369377
numpy::array_view<double, 1> vertices(vertices_arr);
370378
Py_DECREF(vertices_arr);
371379

372-
npy_intp dims[] = { (npy_intp)vertices.size() };
380+
npy_intp dims[] = { (npy_intp)vertices.shape(0) };
373381
numpy::array_view<double, 1> result(dims);
374382
CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
375383
return result.pyobj();

src/_qhull_wrapper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ delaunay(PyObject *self, PyObject *args)
267267
return NULL;
268268
}
269269

270-
npoints = xarray.dim(0);
271-
if (npoints != yarray.dim(0)) {
270+
npoints = xarray.shape(0);
271+
if (npoints != yarray.shape(0)) {
272272
PyErr_SetString(PyExc_ValueError,
273273
"x and y must be 1D arrays of the same length");
274274
return NULL;

src/array.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class scalar
2929
return m_value;
3030
}
3131

32-
int dim(size_t i)
32+
int shape(size_t i)
3333
{
3434
return 1;
3535
}
@@ -40,6 +40,13 @@ class scalar
4040
}
4141
};
4242

43+
template <typename T, int ND>
44+
size_t
45+
safe_first_shape(scalar<T, ND>)
46+
{
47+
return 1;
48+
}
49+
4350
template <typename T>
4451
class empty
4552
{
@@ -65,7 +72,7 @@ class empty
6572
return empty<T>();
6673
}
6774

68-
int dim(size_t i) const
75+
int shape(size_t i) const
6976
{
7077
return 0;
7178
}
@@ -75,6 +82,12 @@ class empty
7582
return 0;
7683
}
7784
};
85+
86+
template <typename T>
87+
size_t safe_first_shape(empty<T>)
88+
{
89+
return 0;
90+
}
7891
}
7992

8093
#endif

src/mplutils.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ inline int prepare_and_add_type(PyTypeObject *type, PyObject *module)
7272
template<typename T>
7373
inline bool check_trailing_shape(T array, char const* name, long d1)
7474
{
75-
if (array.dim(1) != d1) {
75+
if (array.shape(1) != d1) {
7676
PyErr_Format(PyExc_ValueError,
7777
"%s must have shape (N, %ld), got (%ld, %ld)",
78-
name, d1, array.dim(0), array.dim(1));
78+
name, d1, array.shape(0), array.shape(1));
7979
return false;
8080
}
8181
return true;
@@ -84,10 +84,10 @@ inline bool check_trailing_shape(T array, char const* name, long d1)
8484
template<typename T>
8585
inline bool check_trailing_shape(T array, char const* name, long d1, long d2)
8686
{
87-
if (array.dim(1) != d1 || array.dim(2) != d2) {
87+
if (array.shape(1) != d1 || array.shape(2) != d2) {
8888
PyErr_Format(PyExc_ValueError,
8989
"%s must have shape (N, %ld, %ld), got (%ld, %ld, %ld)",
90-
name, d1, d2, array.dim(0), array.dim(1), array.dim(2));
90+
name, d1, d2, array.shape(0), array.shape(1), array.shape(2));
9191
return false;
9292
}
9393
return true;

0 commit comments

Comments
 (0)