Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
gaoqiong
pybind11
Commits
083a0219
Commit
083a0219
authored
Apr 13, 2017
by
uentity
Committed by
Jason Rhinelander
Apr 29, 2017
Browse files
array: implement array resize
parent
4ffa76ec
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
80 additions
and
1 deletion
+80
-1
include/pybind11/numpy.h
include/pybind11/numpy.h
+23
-0
tests/test_numpy_array.cpp
tests/test_numpy_array.cpp
+22
-1
tests/test_numpy_array.py
tests/test_numpy_array.py
+35
-0
No files found.
include/pybind11/numpy.h
View file @
083a0219
...
...
@@ -129,6 +129,11 @@ struct npy_api {
NPY_STRING_
,
NPY_UNICODE_
,
NPY_VOID_
};
typedef
struct
{
Py_intptr_t
*
ptr
;
int
len
;
}
PyArray_Dims
;
static
npy_api
&
get
()
{
static
npy_api
api
=
lookup
();
return
api
;
...
...
@@ -159,6 +164,7 @@ struct npy_api {
Py_ssize_t
*
,
PyObject
**
,
PyObject
*
);
PyObject
*
(
*
PyArray_Squeeze_
)(
PyObject
*
);
int
(
*
PyArray_SetBaseObject_
)(
PyObject
*
,
PyObject
*
);
PyObject
*
(
*
PyArray_Resize_
)(
PyObject
*
,
PyArray_Dims
*
,
int
,
int
);
private:
enum
functions
{
API_PyArray_GetNDArrayCFeatureVersion
=
211
,
...
...
@@ -168,6 +174,7 @@ private:
API_PyArray_DescrFromType
=
45
,
API_PyArray_DescrFromScalar
=
57
,
API_PyArray_FromAny
=
69
,
API_PyArray_Resize
=
80
,
API_PyArray_NewCopy
=
85
,
API_PyArray_NewFromDescr
=
94
,
API_PyArray_DescrNewFromType
=
9
,
...
...
@@ -197,6 +204,7 @@ private:
DECL_NPY_API
(
PyArray_DescrFromType
);
DECL_NPY_API
(
PyArray_DescrFromScalar
);
DECL_NPY_API
(
PyArray_FromAny
);
DECL_NPY_API
(
PyArray_Resize
);
DECL_NPY_API
(
PyArray_NewCopy
);
DECL_NPY_API
(
PyArray_NewFromDescr
);
DECL_NPY_API
(
PyArray_DescrNewFromType
);
...
...
@@ -652,6 +660,21 @@ public:
return
reinterpret_steal
<
array
>
(
api
.
PyArray_Squeeze_
(
m_ptr
));
}
/// Resize array to given shape
/// If refcheck is true and more that one reference exist to this array
/// then resize will succeed only if it makes a reshape, i.e. original size doesn't change
void
resize
(
ShapeContainer
new_shape
,
bool
refcheck
=
true
)
{
detail
::
npy_api
::
PyArray_Dims
d
=
{
new_shape
->
data
(),
int
(
new_shape
->
size
())
};
// try to resize, set ordering param to -1 cause it's not used anyway
object
new_array
=
reinterpret_steal
<
object
>
(
detail
::
npy_api
::
get
().
PyArray_Resize_
(
m_ptr
,
&
d
,
int
(
refcheck
),
-
1
)
);
if
(
!
new_array
)
throw
error_already_set
();
if
(
isinstance
<
array
>
(
new_array
))
{
*
this
=
std
::
move
(
new_array
);
}
}
/// Ensure that the argument is a NumPy array
/// In case of an error, nullptr is returned and the Python error is cleared.
static
array
ensure
(
handle
h
,
int
ExtraFlags
=
0
)
{
...
...
tests/test_numpy_array.cpp
View file @
083a0219
...
...
@@ -273,4 +273,25 @@ test_initializer numpy_array([](py::module &m) {
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
({
1
,
2
});
});
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
({
1
,
2
,
3
});
});
sm
.
def
(
"array_initializer_list"
,
[]()
{
return
py
::
array_t
<
float
>
({
1
,
2
,
3
,
4
});
});
});
// reshape array to 2D without changing size
sm
.
def
(
"array_reshape2"
,
[](
py
::
array_t
<
double
>
a
)
{
const
size_t
dim_sz
=
(
size_t
)
std
::
sqrt
(
a
.
size
());
if
(
dim_sz
*
dim_sz
!=
a
.
size
())
throw
std
::
domain_error
(
"array_reshape2: input array total size is not a squared integer"
);
a
.
resize
({
dim_sz
,
dim_sz
});
});
// resize to 3D array with each dimension = N
sm
.
def
(
"array_resize3"
,
[](
py
::
array_t
<
double
>
a
,
size_t
N
,
bool
refcheck
)
{
a
.
resize
({
N
,
N
,
N
},
refcheck
);
});
// return 2D array with Nrows = Ncols = N
sm
.
def
(
"create_and_resize"
,
[](
size_t
N
)
{
py
::
array_t
<
double
>
a
;
a
.
resize
({
N
,
N
});
std
::
fill
(
a
.
mutable_data
(),
a
.
mutable_data
()
+
a
.
size
(),
42.
);
return
a
;
});
});
\ No newline at end of file
tests/test_numpy_array.py
View file @
083a0219
...
...
@@ -389,3 +389,38 @@ def test_array_failure():
with
pytest
.
raises
(
ValueError
)
as
excinfo
:
array_t_fail_test
()
assert
str
(
excinfo
.
value
)
==
'cannot create a pybind11::array_t from a nullptr'
def
test_array_resize
(
msg
):
from
pybind11_tests.array
import
(
array_reshape2
,
array_resize3
)
a
=
np
.
array
([
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
],
dtype
=
'float64'
)
array_reshape2
(
a
)
assert
(
a
.
size
==
9
)
assert
(
np
.
all
(
a
==
[[
1
,
2
,
3
],
[
4
,
5
,
6
],
[
7
,
8
,
9
]]))
# total size change should succced with refcheck off
array_resize3
(
a
,
4
,
False
)
assert
(
a
.
size
==
64
)
# ... and fail with refcheck on
try
:
array_resize3
(
a
,
3
,
True
)
except
ValueError
as
e
:
assert
(
str
(
e
).
startswith
(
"cannot resize an array"
))
# transposed array doesn't own data
b
=
a
.
transpose
()
try
:
array_resize3
(
b
,
3
,
False
)
except
ValueError
as
e
:
assert
(
str
(
e
).
startswith
(
"cannot resize this array: it does not own its data"
))
# ... but reshape should be fine
array_reshape2
(
b
)
assert
(
b
.
shape
==
(
8
,
8
))
@
pytest
.
unsupported_on_pypy
def
test_array_create_and_resize
(
msg
):
from
pybind11_tests.array
import
create_and_resize
a
=
create_and_resize
(
2
)
assert
(
a
.
size
==
4
)
assert
(
np
.
all
(
a
==
42.
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment