david-seiler commented on a change in pull request #14579: PDF operators for each distribution URL: https://github.com/apache/incubator-mxnet/pull/14579#discussion_r271750062
########## File path: src/operator/random/pdf_op.cc ########## @@ -0,0 +1,292 @@ +/* + * 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) 2018 by Contributors + * \file pdf_op.cc + * \brief CPU-operators for computing the pdf of random distributions. + */ + +#include "./pdf_op.h" + +namespace mxnet { +namespace op { + +DMLC_REGISTER_PARAMETER(PdfParam); + +#define MXNET_OPERATOR_REGISTER_PDF(distr, pdffunc, num_parms, \ + parm_name_1, parm_name_2, \ + parm_desc_1, parm_desc_2, \ + description, vectorparms) \ + NNVM_REGISTER_OP(_random_pdf_##distr) \ + .add_alias("random_pdf_" #distr) \ + .describe(description()+std::string(ADD_FILELINE)) \ + .set_num_inputs(num_parms+1) \ + .set_num_outputs(1) \ + .set_attr_parser(ParamParser<PdfParam>) \ + .set_attr<nnvm::FListInputNames>("FListInputNames", \ + [](const NodeAttrs& attrs) { \ + std::vector<std::string> v = {"sample", parm_name_1, parm_name_2}; \ + v.resize(num_parms+1); \ + return v; \ + }) \ + .set_attr<nnvm::FInferShape>("FInferShape", PdfOpShape<vectorparms>) \ + .set_attr<nnvm::FInferType>("FInferType", ElemwiseType<num_parms+1, 1>) \ + .set_attr<FCompute>("FCompute<cpu>", PdfOpForward<cpu, pdffunc, num_parms, vectorparms>) \ + .set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseInOut{"_backward_pdf_" #distr}) \ + .add_argument("sample", "NDArray-or-Symbol", "Samples from the distributions.") \ + .add_argument(parm_name_1, "NDArray-or-Symbol", parm_desc_1) \ + .add_arguments(PdfParam::__FIELDS__()) + +#define MXNET_OPERATOR_REGISTER_PDF_GRAD(distr, pdffunc, num_parms, vectorparms) \ + NNVM_REGISTER_OP(_backward_pdf_##distr) \ + .set_num_inputs(num_parms+3) \ + .set_num_outputs(num_parms+1) \ + .set_attr_parser(ParamParser<PdfParam>) \ + .set_attr<nnvm::FInplaceOption>("FInplaceOption", [](const NodeAttrs& attrs) \ + { std::vector<std::pair<int, int> > v = {{1, 0}, {2, 1}, {3, 2}}; \ + v.resize(num_parms+1); \ + return v; }) \ + .set_attr<FResourceRequest>("FResourceRequest", [](const NodeAttrs& attrs) \ + { return std::vector<ResourceRequest>{ResourceRequest::kTempSpace}; }) \ + .set_attr<nnvm::TIsBackward>("TIsBackward", true) \ + .set_attr<FCompute>("FCompute<cpu>", PdfOpBackward<cpu, pdffunc##_Grad, num_parms, vectorparms>); + + +#define MXNET_OPERATOR_REGISTER_PDF1(distr, pdffunc, parm_name, parm_desc, \ + description, vectorparms) \ + MXNET_OPERATOR_REGISTER_PDF(distr, pdffunc, 1, parm_name, parm_name, \ + parm_desc, parm_desc, description, vectorparms); \ + MXNET_OPERATOR_REGISTER_PDF_GRAD(distr, pdffunc, 1, vectorparms) + +#define MXNET_OPERATOR_REGISTER_PDF2(distr, pdffunc, parm_name_1, parm_name_2, \ + parm_desc_1, parm_desc_2, description) \ + MXNET_OPERATOR_REGISTER_PDF(distr, pdffunc, 2, parm_name_1, parm_name_2, \ + parm_desc_1, parm_desc_2, description, false) \ + .add_argument(parm_name_2, "NDArray-or-Symbol", parm_desc_2); \ + MXNET_OPERATOR_REGISTER_PDF_GRAD(distr, pdffunc, 2, false) + +inline std::string uniform_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +uniform distributions on the intervals given by *[low,high)*. + +Given *low* and *high* each of dimension *n* and *sample* of dimension *n+1*, +produces output of dimension *n+1* such that each *n*-dimensional index *i* +in the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the values of *low* and *high* at index *i*. + +Examples:: + + random_pdf_uniform(sample=[[1,2,3,4]], low=[0], high=[10]) = [0.1 0.1 0.1 0.1] + + sample = [ + [[1,2,3], + [1,2,3]], + [[1,2,3], + [1,2,3]] + ] + low = [[0, 0], + [0, 0]] + high = [[ 5, 10], + [15, 20]] + random_pdf_uniform(sample=sample, low=low, high=high) = + [[[0.2 0.2 0.2 ] + [0.1 0.1 0.1 ]] + + [[0.06667 0.06667 0.06667] + [0.05 0.05 0.05 ]]] + +)code"); +} + +inline std::string normal_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +normal distributions with parameters *mu* (mean) and *sigma* (standard deviation). + +Given *mu* and *sigma* each of dimension *n* and *sample* of dimension *n+1*, +produces output of dimension *n+1* such that each *n*-dimensional index *i* +in the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the values of *mu* and *sigma* at index *i*. + +Examples:: + + sample = [[-2,-1,0,1,2]] + random_pdf_normal(sample=sample, mu=[0], sigma=[1]) = + [[0.05399097 0.24197073 0.3989423 0.24197073 0.05399097]] + + random_pdf_normal(sample=sample*2, mu=[0,0], sigma=[1,2]) = + [[0.05399097 0.24197073 0.3989423 0.24197073 0.05399097] + [0.12098537 0.17603266 0.19947115 0.17603266 0.12098537]] +)code"); +} + +inline std::string gamma_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +gamma distributions with parameters *alpha* (shape) and *beta* (rate). + +Given *alpha* and *beta* each of dimension *n* and *sample* of dimension *n+1*, +produces output of dimension *n+1* such that each *n*-dimensional index *i* +in the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the values of *alpha* and *beta* at index *i*. + +Examples:: + + random_pdf_gamma(sample=[[1,2,3,4,5]], alpha=[5], beta=[1]) = + [[0.01532831 0.09022352 0.16803136 0.19536681 0.17546739]] + + sample = [[1, 2, 3, 4, 5], + [2, 3, 4, 5, 6], + [3, 4, 5, 6, 7]] + + random_pdf_gamma(sample=sample, alpha=[5,6,7], beta=[1,1,1]) = + [[0.01532831 0.09022352 0.16803136 0.19536681 0.17546739] + [0.03608941 0.10081882 0.15629345 0.17546739 0.16062315] + [0.05040941 0.10419563 0.14622283 0.16062315 0.14900276]] +)code"); +} + +inline std::string exponential_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +exponential distributions with parameters *lam* (rate). + +Given *lam* of dimension *n* and *sample* of dimension *n+1*, produces +output of dimension *n+1* such that each *n*-dimensional index *i* in +the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the value of *lam* at index *i*. + +Examples:: + + random_pdf_exponential(sample=[[1, 2, 3]], lam=[1]) = + [[0.36787945 0.13533528 0.04978707]] + +)code"); +} + +inline std::string poisson_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +Poisson distributions with parameters *lam* (rate). + +Given *lam* of dimension *n* and *sample* of dimension *n+1*, produces +output of dimension *n+1* such that each *n*-dimensional index *i* in +the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the value of *lam* at index *i*. + +Examples:: + + random_pdf_poisson(sample=[[0,1,2,3]], lam=[1]) = + [[0.36787945 0.36787945 0.18393973 0.06131324]] + + sample = [[0,1,2,3], + [0,1,2,3], + [0,1,2,3]] + + random_pdf_poisson(sample=sample, lam=[1,2,3]) = + [[0.36787945 0.36787945 0.18393973 0.06131324] + [0.13533528 0.27067056 0.27067056 0.18044704] + [0.04978707 0.14936121 0.22404182 0.22404182]] +)code"); +} + +inline std::string negative_binomial_desc() { + return std::string(R"code(Computes the value of the PDF of samples of +negative binomial distributions with parameters *k* (failure limit) and *p* (failure probability). + +Given *k* and *p* of dimension *n* and *sample* of dimension *n+1*, produces +output of dimension *n+1* such that each *n*-dimensional index *i* in +the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the values of *k* and *p* at index *i*. + +Examples:: + + random_pdf_negative_binomial(sample=[[1,2,3,4]], k=[1], p=a[0.5]) = + [[0.25 0.125 0.0625 0.03125]] + + # Note that k may be real-valued + sample = [[1,2,3,4], + [1,2,3,4]] + random_pdf_negative_binomial(sample=sample, k=[1, 1.5], p=[0.5, 0.5]) = + [[0.25 0.125 0.0625 0.03125 ] + [0.26516506 0.16572815 0.09667476 0.05437956]] +)code"); +} + +inline std::string generalized_negative_binomial_desc() { + return std::string(R"code(Computes the value of the PDF of *sample* of +generalized negative binomial distributions with parameters *mu* (mean) +and *alpha* (dispersion). This can be understood as a reparameterization of +the negative binomial, where *k* = *1 / alpha* and *p* = *1 / (mu \* alpha + 1)*. + +Given *k* and *p* of dimension *n* and *sample* of dimension *n+1*, produces +output of dimension *n+1* such that each *n*-dimensional index *i* in +the output array holds the PDFs of the samples at index *i* in *sample*, +parameterized by the values of *k* and *p* at index *i*. + +Examples:: + + random_pdf_generalized_negative_binomial(sample=[[1, 2, 3, 4]], alpha=[1], mu=[1]) = + [[0.25 0.125 0.0625 0.03125]] + + sample = [[1,2,3,4], + [1,2,3,4]] + random_pdf_generalized_negative_binomial(sample=sample, alpha=[1, 0.6666], mu=[1, 1.5]) = + [[0.25 0.125 0.0625 0.03125 ] + [0.26517063 0.16573331 0.09667706 0.05437994]] +)code"); +} + +inline std::string dirichlet_desc() { Review comment: Updated the commit message to clarify that, unlike the other distributions, we don't have a Dirichlet sampler yet. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected] With regards, Apache Git Services
