Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
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