Files
2026-07-13 12:40:42 +08:00

486 lines
16 KiB
Python

# Copyright (c) 2023 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import unittest
import numpy as np
from op_test import get_device_place
import paddle
def ref_histogramdd(x, bins, ranges, weights, density):
D = x.shape[-1]
x = x.reshape(-1, D)
if ranges is not None:
ranges = np.array(ranges, dtype=x.dtype).reshape(D, 2).tolist()
if weights is not None:
weights = weights.reshape(-1)
ref_hist, ref_edges = np.histogramdd(x, bins, ranges, density, weights)
return ref_hist, ref_edges
# inputs, bins, ranges, weights, density
class TestHistogramddAPI(unittest.TestCase):
def setUp(self):
self.ranges = None
self.weights = None
self.density = False
self.init_input()
self.set_expect_output()
self.place = get_device_place()
def init_input(self):
# self.sample = np.array([[0.0, 1.0], [1.0, 0.0], [2.0, 0.0], [2.0, 2.0]])
self.sample = np.random.randn(
4,
2,
).astype(np.float64)
self.bins = [3, 3]
self.weights = np.array([1.0, 2.0, 4.0, 8.0], dtype=self.sample.dtype)
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
def test_static_api(self):
paddle.enable_static()
with paddle.static.program_guard(paddle.static.Program()):
x = paddle.static.data(
'x', self.sample.shape, dtype=self.sample.dtype
)
if self.weights is not None:
weights = paddle.static.data(
'weights', self.weights.shape, dtype=self.weights.dtype
)
out_0, out_1 = paddle.histogramdd(
x,
bins=self.bins,
weights=weights,
ranges=self.ranges,
density=self.density,
)
else:
out_0, out_1 = paddle.histogramdd(
x, bins=self.bins, ranges=self.ranges, density=self.density
)
exe = paddle.static.Executor(self.place)
if self.weights is not None:
res = exe.run(
feed={'x': self.sample, 'weights': self.weights},
fetch_list=[out_0, out_1],
)
else:
res = exe.run(
feed={'x': self.sample}, fetch_list=[out_0, out_1]
)
hist_out, edges_out = res[0], res[1:]
np.testing.assert_allclose(
hist_out,
self.expect_hist,
)
for idx, edge_out in enumerate(edges_out):
expect_edge = np.array(self.expect_edges[idx])
np.testing.assert_allclose(
edge_out,
expect_edge,
)
def test_dygraph_api(self):
paddle.disable_static(self.place)
self.sample_dy = paddle.to_tensor(self.sample, dtype=self.sample.dtype)
self.weights_dy = None
if self.weights is not None:
self.weights_dy = paddle.to_tensor(self.weights)
if isinstance(self.bins, tuple):
self.bins = tuple([paddle.to_tensor(bin) for bin in self.bins])
hist, edges = paddle.histogramdd(
self.sample_dy,
bins=self.bins,
weights=self.weights_dy,
ranges=self.ranges,
density=self.density,
)
np.testing.assert_allclose(
hist.numpy(),
self.expect_hist,
)
for idx, edge in enumerate(edges):
edge = edge.numpy()
expect_edge = np.array(self.expect_edges[idx])
np.testing.assert_allclose(
edge,
expect_edge,
)
paddle.enable_static()
def test_error(self):
pass
class TestHistogramddAPICase1ForDensity(TestHistogramddAPI):
def init_input(self):
# self.sample = np.array([[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]])
self.sample = np.random.randn(4, 2).astype(np.float64)
self.bins = [2, 2]
self.ranges = [0.0, 1.0, 0.0, 1.0]
self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase2ForMultiDimsAndDensity(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase3ForMultiDimsNotDensity(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
# self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase4ForRangesAndDensity(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
self.ranges = [1.0, 10.0, 1.0, 100.0]
self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase5ForRangesNotDensity(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
self.ranges = [1.0, 10.0, 1.0, 100.0]
# self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase6NotRangesAndDensityAndWeights(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
# self.ranges = [1., 10., 1., 100.]
self.density = True
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase7ForRangesAndDensityAndWeights(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.bins = [3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
self.ranges = [1.0, 10.0, 1.0, 100.0]
self.density = True
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase8MoreInnermostDim(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,4]
self.sample = np.random.randn(4, 2, 4).astype(np.float64)
self.bins = [1, 2, 3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
self.density = False
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase8MoreInnermostDimAndDensity(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,4]
self.sample = np.random.randn(4, 2, 4).astype(np.float64)
self.bins = [1, 2, 3, 4]
# [leftmost_1, rightmost_1, leftmost_2, rightmost_2,..., leftmost_D, rightmost_D]
self.density = True
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase9ForIntBin(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
self.bins = 5
self.density = True
self.ranges = [1.0, 10.0, 1.0, 100.0]
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase10ForTensorBin(TestHistogramddAPI):
def init_input(self):
# shape: [4,2,2]
self.sample = np.random.randn(4, 2, 2).astype(np.float64)
self.weights = np.array(
[
[1.0, 2.0],
[3.0, 4.0],
[5.0, 6.0],
[7.0, 8.0],
],
dtype=self.sample.dtype,
)
self.bins = (
np.array([1.0, 2.0, 10.0, 15.0, 20.0]),
np.array([0.0, 20.0, 100.0]),
)
self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
class TestHistogramddAPICase10ForFloat32(TestHistogramddAPI):
def init_input(self):
# self.sample = np.array([[0.0, 0.0], [1.0, 1.0], [2.0, 2.0]])
self.sample = np.random.randn(4, 2).astype(np.float32)
self.bins = [2, 2]
self.ranges = [0.0, 1.0, 0.0, 1.0]
self.density = True
def set_expect_output(self):
self.expect_hist, self.expect_edges = ref_histogramdd(
self.sample, self.bins, self.ranges, self.weights, self.density
)
# histogramdd(sample, bins=10, ranges=None, density=False, weights=None, name=None):
class TestHistogramddAPI_check_sample_type_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor([[False, True], [True, False]])
with self.assertRaises(TypeError):
paddle.histogramdd(sample)
class TestHistogramddAPI_check_bins_element_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
bins = [3.4, 4.5]
with self.assertRaises(ValueError):
paddle.histogramdd(sample, bins=bins)
class TestHistogramddAPI_check_ranges_type_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
ranges = 10
with self.assertRaises(TypeError):
paddle.histogramdd(sample, ranges=ranges)
class TestHistogramddAPI_check_density_type_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
density = 10
with self.assertRaises(TypeError):
paddle.histogramdd(sample, density=density)
class TestHistogramddAPI_check_weights_type_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
weights = 10
with self.assertRaises(AttributeError):
paddle.histogramdd(sample, weights=weights)
class TestHistogramddAPI_sample_weights_shape_mismatch_error(
TestHistogramddAPI
):
def test_error(self):
sample = paddle.to_tensor(
[ # shape: [4,2]
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
weights = paddle.to_tensor(
[2.0, 3.0, 4.0], dtype=self.sample.dtype
) # shape: [3,]
with self.assertRaises(AssertionError):
paddle.histogramdd(sample, weights=weights)
class TestHistogramddAPI_sample_weights_type_mismatch_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[ # float32
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
],
dtype=paddle.float32,
)
weights = paddle.to_tensor(
[2.0, 3.0, 4.0], dtype=paddle.float64
) # float64
with self.assertRaises(AssertionError):
paddle.histogramdd(sample, weights=weights)
class TestHistogramddAPI_check_bins_type_error(TestHistogramddAPI):
def test_error(self):
sample = paddle.to_tensor(
[
[[1.0, 2.0], [3.0, 4.0]],
[[5.0, 6.0], [7.0, 8.0]],
[[9.0, 10.0], [11.0, 12.0]],
[[13.0, 14.0], [15.0, 16.0]],
]
)
bins = 2.0
with self.assertRaises(ValueError):
paddle.histogramdd(sample, bins=bins)
if __name__ == '__main__':
paddle.enable_static()
unittest.main()