Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

[NumPy] add op random.laplace #17316

Merged
merged 31 commits into from
Mar 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
585b238
NumPy Laplace Distribution partly Frontend and Backend
AntiZpvoh Jan 14, 2020
2de8ac4
NumPy Laplace Distribution Backend style rectified
AntiZpvoh Jan 14, 2020
b789cd7
NumPy Laplace Distribution Frontend modified
AntiZpvoh Jan 14, 2020
97a5d35
Laplece op nightly test and normal op test correction
AntiZpvoh Jan 15, 2020
94087e6
NumPy Laplace Distribution unit test and code style
AntiZpvoh Jan 15, 2020
eec4ec2
Register uniform_n in CUDA
AntiZpvoh Jan 15, 2020
14dd8b2
Delete the registering of Laplace_n
AntiZpvoh Jan 15, 2020
96c9130
fix some alignment and indentation problems
AntiZpvoh Jan 16, 2020
f0f6535
merge with upstream master
AntiZpvoh Feb 12, 2020
48cc7d3
fix some sanity problems such as too long lines
AntiZpvoh Feb 12, 2020
2d9a72c
fix some sanity problems again
AntiZpvoh Feb 12, 2020
6a79e2f
merge with upstream master
AntiZpvoh Feb 13, 2020
2302afa
merge with upstream master
AntiZpvoh Feb 15, 2020
c89f1f5
merge with upstream
AntiZpvoh Feb 20, 2020
de61812
laplace parmeters form change
AntiZpvoh Mar 9, 2020
5e14d39
Merge branch 'master' of https://github.com/apache/incubator-mxnet in…
AntiZpvoh Mar 9, 2020
115cc41
implement basic laplace function
AntiZpvoh Mar 10, 2020
29b0034
add frontend implement and ndarray loc case
AntiZpvoh Mar 10, 2020
d1e968b
complete the frontend
AntiZpvoh Mar 10, 2020
a849e94
Merge branch 'master' of https://github.com/apache/incubator-mxnet in…
AntiZpvoh Mar 10, 2020
4a62caa
fix some sanity problems
AntiZpvoh Mar 10, 2020
20c05c1
fix some sanity problems
AntiZpvoh Mar 10, 2020
b52931f
fix some typos
AntiZpvoh Mar 10, 2020
336cd9f
fix some problems
AntiZpvoh Mar 10, 2020
1e871ce
fix a typo
AntiZpvoh Mar 11, 2020
99e60cb
Merge branch 'NumPyLaplaceOp' of https://github.com/AntiZpvoh/incubat…
AntiZpvoh Mar 11, 2020
c115c73
add size==() condition handling
AntiZpvoh Mar 11, 2020
fe998f6
Merge branch 'master' of https://github.com/apache/incubator-mxnet in…
AntiZpvoh Mar 13, 2020
670e0ad
Merge branch 'NumPyLaplaceOp' of https://github.com/AntiZpvoh/incubat…
AntiZpvoh Mar 13, 2020
befba1e
fix some typos
Mar 13, 2020
5dc7075
remove unused code
Mar 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions python/mxnet/ndarray/numpy/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
from ...context import current_context
from . import _internal as _npi
from ..ndarray import NDArray
from . import _api_internal


__all__ = ['randint', 'uniform', 'normal', "choice", "rand", "multinomial", "multivariate_normal",
'logistic', 'gumbel', "rayleigh", 'f',
'laplace',
"shuffle", 'gamma', 'beta', 'chisquare', 'exponential', 'lognormal', 'weibull', 'pareto', 'power']


Expand Down Expand Up @@ -1067,3 +1069,43 @@ def shuffle(x):
[0., 1., 2.]])
"""
_npi.shuffle(x, out=x)


def laplace(loc=0.0, scale=1.0, size=None, dtype=None, ctx=None, out=None):
r"""Draw random samples from a Laplace distribution.

Samples are distributed according to a Laplace distribution parametrized
by *loc* (mean) and *scale* (the exponential decay).


Parameters
----------
loc : float, The position of the distribution peak.

scale : float, the exponential decay.

size : int or tuple of ints, optional. Output shape.
If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn.
Default is None, in which case a single value is returned.

dtype : {'float16', 'float32', 'float64'}, optional
Data type of output samples. Default is 'float32'
ctx : Context, optional
Device context of output. Default is current context.
out : ``ndarray``, optional
Store output to an existing ``ndarray``.

Returns
-------
out : ndarray
Drawn samples from the parameterized Laplace distribution.
"""
if ctx is None:
ctx = str(current_context())
else:
ctx = str(ctx)
if dtype is not None and not isinstance(dtype, str):
dtype = np.dtype(dtype).name
if size == ():
size = None
return _api_internal.laplace(loc, scale, size, dtype, ctx, out)
31 changes: 31 additions & 0 deletions python/mxnet/numpy/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

__all__ = ["randint", "uniform", "normal", "choice", "rand", "multinomial", "multivariate_normal",
"logistic", "gumbel", "f",
"laplace",
"shuffle", "randn", "gamma", "beta", "chisquare", "exponential", "lognormal",
"weibull", "pareto", "power", "rayleigh"]

Expand Down Expand Up @@ -1043,3 +1044,33 @@ def randn(*size, **kwargs):
for s in size:
output_shape += (s,)
return _mx_nd_np.random.normal(0, 1, size=output_shape, **kwargs)

def laplace(loc=0.0, scale=1.0, size=None, dtype=None, ctx=None, out=None):
r"""Draw random samples from a Laplace distribution.

Samples are distributed according to a Laplace distribution parametrized
by *loc* (mean) and *scale* (the exponential decay).

Parameters
----------
loc : float, The position of the distribution peak.

scale : float, the exponential decay.

size : int or tuple of ints, optional. Output shape.
If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn.
Default is None, in which case a single value is returned.

dtype : {'float16', 'float32', 'float64'}, optional
Data type of output samples. Default is 'float32'
ctx : Context, optional
Device context of output. Default is current context.
out : ``ndarray``, optional
Store output to an existing ``ndarray``.

Returns
-------
out : ndarray
Drawn samples from the parameterized Laplace distribution.
"""
return _mx_nd_np.random.laplace(loc, scale, size, dtype, ctx, out)
52 changes: 51 additions & 1 deletion python/mxnet/symbol/numpy/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
__all__ = ['randint', 'uniform', 'normal', 'multivariate_normal',
'logistic', 'gumbel', 'rayleigh', 'f',
'rand', 'shuffle', 'gamma', 'beta', 'chisquare', 'exponential', 'lognormal',
'weibull', 'pareto', 'power']
'weibull', 'pareto', 'power', 'laplace']


def randint(low, high=None, size=None, dtype=None, ctx=None, out=None):
Expand Down Expand Up @@ -416,6 +416,56 @@ def choice(a, size=None, replace=True, p=None, ctx=None, out=None):
return _npi.choice(p, a=a, size=size, replace=replace, ctx=ctx, weighted=True, out=out)


def laplace(loc=0.0, scale=1.0, size=None, dtype=None, ctx=None, out=None):
r"""Draw random samples from a Laplace distribution.

Samples are distributed according to a Laplace distribution parametrized
by *loc* (mean) and *scale* (the exponential decay).

Parameters
----------
loc : float, The position of the distribution peak.

scale : float, the exponential decay.

size : int or tuple of ints, optional. Output shape.
If the given shape is, e.g., (m, n, k), then m * n * k samples are drawn.
Default is None, in which case a single value is returned.

dtype : {'float16', 'float32', 'float64'}, optional
Data type of output samples. Default is 'float32'
ctx : Context, optional
Device context of output. Default is current context.
out : ``ndarray``, optional
Store output to an existing ``ndarray``.

Returns
-------
out : _Symbol (symbol representing `mxnet.numpy.ndarray` in computational graphs)
Drawn samples from the parameterized Laplace distribution.
"""
from ._symbol import _Symbol as np_symbol
input_type = (isinstance(loc, np_symbol), isinstance(scale, np_symbol))
if dtype is None:
dtype = 'float32'
if ctx is None:
ctx = current_context()
if size == ():
size = None
if input_type == (True, True):
return _npi.laplace(loc, scale, loc=None, scale=None, size=size,
ctx=ctx, dtype=dtype, out=out)
elif input_type == (False, True):
return _npi.laplace(scale, loc=loc, scale=None, size=size,
ctx=ctx, dtype=dtype, out=out)
elif input_type == (True, False):
return _npi.laplace(loc, loc=None, scale=scale, size=size,
ctx=ctx, dtype=dtype, out=out)
else:
return _npi.laplace(loc=loc, scale=scale, size=size,
ctx=ctx, dtype=dtype, out=out)


def gamma(shape, scale=1.0, size=None, dtype=None, ctx=None, out=None):
"""Draw samples from a Gamma distribution.

Expand Down
96 changes: 96 additions & 0 deletions src/api/operator/numpy/random/np_laplace_op.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

/*!
* \file np_laplace_op.cc
* \brief Implementation of the API of functions in src/operator/numpy/np_laplace_op.cc
*/
#include <mxnet/api_registry.h>
#include <mxnet/runtime/packed_func.h>
#include "../../utils.h"
#include "../../../../operator/numpy/random/np_laplace_op.h"

namespace mxnet {

MXNET_REGISTER_API("_npi.laplace")
.set_body([](runtime::MXNetArgs args, runtime::MXNetRetValue* ret) {
using namespace runtime;
const nnvm::Op* op = Op::Get("_npi_laplace");
nnvm::NodeAttrs attrs;
op::NumpyLaplaceParam param;

NDArray** inputs = new NDArray*[2]();
int num_inputs = 0;

if (args[0].type_code() == kNull) {
param.loc = dmlc::nullopt;
} else if (args[0].type_code() == kNDArrayHandle) {
param.loc = dmlc::nullopt;
inputs[num_inputs] = args[0].operator mxnet::NDArray *();
num_inputs++;
} else {
param.loc = args[0].operator double(); // convert arg to T
}

if (args[1].type_code() == kNull) {
param.scale = dmlc::nullopt;
} else if (args[1].type_code() == kNDArrayHandle) {
param.scale = dmlc::nullopt;
inputs[num_inputs] = args[1].operator mxnet::NDArray *();
num_inputs++;
} else {
param.scale = args[1].operator double(); // convert arg to T
}

if (args[2].type_code() == kNull) {
param.size = dmlc::nullopt;
} else {
if (args[2].type_code() == kDLInt) {
param.size = mxnet::Tuple<int>(1, args[2].operator int64_t());
} else {
param.size = mxnet::Tuple<int>(args[2].operator ObjectRef());
}
}

if (args[3].type_code() == kNull) {
param.dtype = mshadow::kFloat32;
} else {
param.dtype = String2MXNetTypeWithBool(args[3].operator std::string());
}
attrs.parsed = std::move(param);
attrs.op = op;
SetAttrDict<op::NumpyLaplaceParam>(&attrs);
if (args[4].type_code() != kNull) {
attrs.dict["ctx"] = args[4].operator std::string();
}

inputs = inputs == nullptr ? nullptr : inputs;

NDArray* out = args[5].operator mxnet::NDArray*();
NDArray** outputs = out == nullptr ? nullptr : &out;
int num_outputs = out != nullptr;
auto ndoutputs = Invoke(op, &attrs, num_inputs, inputs, &num_outputs, outputs);
if (out) {
*ret = PythonArg(5);
} else {
*ret = ndoutputs[0];
}
});

} // namespace mxnet
69 changes: 69 additions & 0 deletions src/operator/numpy/random/np_laplace_op.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

/*!
* Copyright (c) 2019 by Contributors
* \file np_laplace_op.cc
* \brief Operator for numpy sampling from Laplace distributions
*/
#include "./np_laplace_op.h"

namespace mxnet {
namespace op {

DMLC_REGISTER_PARAMETER(NumpyLaplaceParam);

NNVM_REGISTER_OP(_npi_laplace)
.describe("numpy behavior Laplace")
.set_num_inputs(
[](const nnvm::NodeAttrs& attrs) {
const NumpyLaplaceParam& param = nnvm::get<NumpyLaplaceParam>(attrs.parsed);
int num_inputs = 2;
if (param.loc.has_value()) num_inputs -= 1;
if (param.scale.has_value()) num_inputs -= 1;
return num_inputs;
}
)
.set_num_outputs(1)
.set_attr<nnvm::FListInputNames>("FListInputNames",
[](const NodeAttrs& attrs) {
const NumpyLaplaceParam& param = nnvm::get<NumpyLaplaceParam>(attrs.parsed);
int num_inputs = 2;
if (param.loc.has_value()) num_inputs -= 1;
if (param.scale.has_value()) num_inputs -= 1;
if (num_inputs == 0) return std::vector<std::string>();
if (num_inputs == 1) return std::vector<std::string>{"input1"};
return std::vector<std::string>{"input1", "input2"};
})
.set_attr_parser(ParamParser<NumpyLaplaceParam>)
.set_attr<mxnet::FInferShape>("FInferShape", TwoparamsDistOpShape<NumpyLaplaceParam>)
.set_attr<nnvm::FInferType>("FInferType", NumpyLaplaceOpType)
.set_attr<FResourceRequest>("FResourceRequest",
[](const nnvm::NodeAttrs& attrs) {
return std::vector<ResourceRequest>{
ResourceRequest::kRandom, ResourceRequest::kTempSpace};
})
.set_attr<FCompute>("FCompute<cpu>", NumpyLaplaceForward<cpu>)
.set_attr<nnvm::FGradient>("FGradient", MakeZeroGradNodes)
.add_argument("input1", "NDArray-or-Symbol", "Source input")
.add_argument("input2", "NDArray-or-Symbol", "Source input")
.add_arguments(NumpyLaplaceParam::__FIELDS__());

} // namespace op
} // namespace mxnet
35 changes: 35 additions & 0 deletions src/operator/numpy/random/np_laplace_op.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/

/*!
* Copyright (c) 2019 by Contributors
* \file np_laplace_op.cu
* \brief Operator for numpy sampling from Laplace distributions
*/

#include "./np_laplace_op.h"

namespace mxnet {
namespace op {

NNVM_REGISTER_OP(_npi_laplace)
.set_attr<FCompute>("FCompute<gpu>", NumpyLaplaceForward<gpu>);

This comment was marked as resolved.

} // namespace op
} // namespace mxnet
Loading