├── .gitignore ├── 3rd-party-licenses.txt ├── AUTHORS ├── CONTRIBUTING.md ├── CONTRIBUTORS ├── LICENSE ├── README.rst ├── User_Manual.pdf ├── admml ├── __init__.py ├── admml.py ├── examples.py ├── mappers.py ├── mlalgs.py └── utils.py ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ └── ADMML.png │ ├── conf.py │ ├── include_readme.rst │ └── index.rst └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | 3 | docs/build/ 4 | 5 | docs/source/admml.admml.rst 6 | docs/source/admml.examples.rst 7 | docs/source/admml.mappers.rst 8 | docs/source/admml.mlalgs.rst 9 | docs/source/admml.rst 10 | docs/source/admml.utils.rst 11 | docs/source/modules.rst 12 | -------------------------------------------------------------------------------- /3rd-party-licenses.txt: -------------------------------------------------------------------------------- 1 | Third Party Licenses 2 | 3 | This project is based on or incorporates material from the projects listed 4 | below (Third Party IP). The original copyright notice and the license under 5 | which Bosch received such Third Party IP, are set forth below. 6 | 7 | 8 | -------------------------------------------------------------------------- 9 | Overview 10 | -------------------------------------------------------------------------- 11 | 12 | Name: Sphinx 13 | Version: 1.5.5 14 | URL: http://sphinx-doc.org/ 15 | License: BSD 16 | Copyright: Copyright (c) 2007-2017 by the Sphinx team. 17 | 18 | 19 | -------------------------------------------------------------------------- 20 | Licenses 21 | -------------------------------------------------------------------------- 22 | 23 | a) Sphinx 24 | 25 | License for Sphinx 26 | ================== 27 | 28 | Copyright (c) 2007-2017 by the Sphinx team (see AUTHORS file). 29 | All rights reserved. 30 | 31 | Redistribution and use in source and binary forms, with or without 32 | modification, are permitted provided that the following conditions are 33 | met: 34 | 35 | * Redistributions of source code must retain the above copyright 36 | notice, this list of conditions and the following disclaimer. 37 | 38 | * Redistributions in binary form must reproduce the above copyright 39 | notice, this list of conditions and the following disclaimer in the 40 | documentation and/or other materials provided with the distribution. 41 | 42 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 | 54 | 55 | Licenses for incorporated software 56 | ================================== 57 | 58 | The pgen2 package, included in this distribution under the name 59 | sphinx.pycode.pgen2, is available in the Python 2.6 distribution under 60 | the PSF license agreement for Python: 61 | 62 | ---------------------------------------------------------------------- 63 | Copyright © 2001-2008 Python Software Foundation; All Rights Reserved. 64 | 65 | PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 66 | -------------------------------------------- 67 | 68 | 1. This LICENSE AGREEMENT is between the Python Software Foundation 69 | ("PSF"), and the Individual or Organization ("Licensee") accessing 70 | and otherwise using Python 2.6 software in source or binary form 71 | and its associated documentation. 72 | 73 | 2. Subject to the terms and conditions of this License Agreement, PSF 74 | hereby grants Licensee a nonexclusive, royalty-free, world-wide 75 | license to reproduce, analyze, test, perform and/or display 76 | publicly, prepare derivative works, distribute, and otherwise use 77 | Python 2.6 alone or in any derivative version, provided, however, 78 | that PSF's License Agreement and PSF's notice of copyright, i.e., 79 | "Copyright © 2001-2008 Python Software Foundation; All Rights 80 | Reserved" are retained in Python 2.6 alone or in any derivative 81 | version prepared by Licensee. 82 | 83 | 3. In the event Licensee prepares a derivative work that is based on 84 | or incorporates Python 2.6 or any part thereof, and wants to make 85 | the derivative work available to others as provided herein, then 86 | Licensee hereby agrees to include in any such work a brief summary 87 | of the changes made to Python 2.6. 88 | 89 | 4. PSF is making Python 2.6 available to Licensee on an "AS IS" basis. 90 | PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY 91 | WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY 92 | REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY 93 | PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.6 WILL NOT INFRINGE 94 | ANY THIRD PARTY RIGHTS. 95 | 96 | 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 97 | 2.6 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS 98 | AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 99 | 2.6, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY 100 | THEREOF. 101 | 102 | 6. This License Agreement will automatically terminate upon a material 103 | breach of its terms and conditions. 104 | 105 | 7. Nothing in this License Agreement shall be deemed to create any 106 | relationship of agency, partnership, or joint venture between PSF 107 | and Licensee. This License Agreement does not grant permission to 108 | use PSF trademarks or trade name in a trademark sense to endorse or 109 | promote products or services of Licensee, or any third party. 110 | 111 | 8. By copying, installing or otherwise using Python 2.6, Licensee 112 | agrees to be bound by the terms and conditions of this License 113 | Agreement. 114 | ---------------------------------------------------------------------- 115 | 116 | The included smartypants module, included as sphinx.util.smartypants, 117 | is available under the following license: 118 | 119 | ---------------------------------------------------------------------- 120 | SmartyPants_ license:: 121 | 122 | Copyright (c) 2003 John Gruber 123 | (http://daringfireball.net/) 124 | All rights reserved. 125 | 126 | Redistribution and use in source and binary forms, with or without 127 | modification, are permitted provided that the following conditions 128 | are met: 129 | 130 | * Redistributions of source code must retain the above copyright 131 | notice, this list of conditions and the following disclaimer. 132 | 133 | * Redistributions in binary form must reproduce the above 134 | copyright notice, this list of conditions and the following 135 | disclaimer in the documentation and/or other materials 136 | provided with the distribution. 137 | 138 | * Neither the name "SmartyPants" nor the names of its 139 | contributors may be used to endorse or promote products 140 | derived from this software without specific prior written 141 | permission. 142 | 143 | This software is provided by the copyright holders and 144 | contributors "as is" and any express or implied warranties, 145 | including, but not limited to, the implied warranties of 146 | merchantability and fitness for a particular purpose are 147 | disclaimed. In no event shall the copyright owner or contributors 148 | be liable for any direct, indirect, incidental, special, 149 | exemplary, or consequential damages (including, but not limited 150 | to, procurement of substitute goods or services; loss of use, 151 | data, or profits; or business interruption) however caused and on 152 | any theory of liability, whether in contract, strict liability, or 153 | tort (including negligence or otherwise) arising in any way out of 154 | the use of this software, even if advised of the possibility of 155 | such damage. 156 | 157 | 158 | smartypants.py license:: 159 | 160 | smartypants.py is a derivative work of SmartyPants. 161 | 162 | Redistribution and use in source and binary forms, with or without 163 | modification, are permitted provided that the following conditions 164 | are met: 165 | 166 | * Redistributions of source code must retain the above copyright 167 | notice, this list of conditions and the following disclaimer. 168 | 169 | * Redistributions in binary form must reproduce the above 170 | copyright notice, this list of conditions and the following 171 | disclaimer in the documentation and/or other materials 172 | provided with the distribution. 173 | 174 | This software is provided by the copyright holders and 175 | contributors "as is" and any express or implied warranties, 176 | including, but not limited to, the implied warranties of 177 | merchantability and fitness for a particular purpose are 178 | disclaimed. In no event shall the copyright owner or contributors 179 | be liable for any direct, indirect, incidental, special, 180 | exemplary, or consequential damages (including, but not limited 181 | to, procurement of substitute goods or services; loss of use, 182 | data, or profits; or business interruption) however caused and on 183 | any theory of liability, whether in contract, strict liability, or 184 | tort (including negligence or otherwise) arising in any way out of 185 | the use of this software, even if advised of the possibility of 186 | such damage. 187 | ---------------------------------------------------------------------- 188 | 189 | The ElementTree package, included in this distribution in 190 | test/etree13, is available under the following license: 191 | 192 | ---------------------------------------------------------------------- 193 | The ElementTree toolkit is 194 | 195 | Copyright (c) 1999-2007 by Fredrik Lundh 196 | 197 | By obtaining, using, and/or copying this software and/or its 198 | associated documentation, you agree that you have read, understood, 199 | and will comply with the following terms and conditions: 200 | 201 | Permission to use, copy, modify, and distribute this software and its 202 | associated documentation for any purpose and without fee is hereby 203 | granted, provided that the above copyright notice appears in all 204 | copies, and that both that copyright notice and this permission notice 205 | appear in supporting documentation, and that the name of Secret Labs 206 | AB or the author not be used in advertising or publicity pertaining to 207 | distribution of the software without specific, written prior 208 | permission. 209 | 210 | SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO 211 | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- ABILITY 212 | AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE 213 | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 214 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 215 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 216 | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 217 | ---------------------------------------------------------------------- 218 | 219 | The included JQuery JavaScript library is available under the MIT 220 | license: 221 | 222 | ---------------------------------------------------------------------- 223 | Copyright (c) 2008 John Resig, http://jquery.com/ 224 | 225 | Permission is hereby granted, free of charge, to any person obtaining 226 | a copy of this software and associated documentation files (the 227 | "Software"), to deal in the Software without restriction, including 228 | without limitation the rights to use, copy, modify, merge, publish, 229 | distribute, sublicense, and/or sell copies of the Software, and to 230 | permit persons to whom the Software is furnished to do so, subject to 231 | the following conditions: 232 | 233 | The above copyright notice and this permission notice shall be 234 | included in all copies or substantial portions of the Software. 235 | 236 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 237 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 238 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 239 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 240 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 241 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 242 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 243 | ---------------------------------------------------------------------- 244 | 245 | The included Underscore JavaScript library is available under the MIT 246 | license: 247 | 248 | ---------------------------------------------------------------------- 249 | Copyright (c) 2009 Jeremy Ashkenas, DocumentCloud 250 | 251 | Permission is hereby granted, free of charge, to any person 252 | obtaining a copy of this software and associated documentation 253 | files (the "Software"), to deal in the Software without 254 | restriction, including without limitation the rights to use, 255 | copy, modify, merge, publish, distribute, sublicense, and/or sell 256 | copies of the Software, and to permit persons to whom the 257 | Software is furnished to do so, subject to the following 258 | conditions: 259 | 260 | The above copyright notice and this permission notice shall be 261 | included in all copies or substantial portions of the Software. 262 | 263 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 264 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 265 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 266 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 267 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 268 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 269 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 270 | OTHER DEALINGS IN THE SOFTWARE. 271 | 272 | ------------------------------------------------------------------------------- 273 | 274 | The included implementation of NumpyDocstring._parse_numpydoc_see_also_section 275 | was derived from code under the following license: 276 | 277 | ------------------------------------------------------------------------------- 278 | 279 | Copyright (C) 2008 Stefan van der Walt , Pauli Virtanen 280 | 281 | Redistribution and use in source and binary forms, with or without 282 | modification, are permitted provided that the following conditions are 283 | met: 284 | 285 | 1. Redistributions of source code must retain the above copyright 286 | notice, this list of conditions and the following disclaimer. 287 | 2. Redistributions in binary form must reproduce the above copyright 288 | notice, this list of conditions and the following disclaimer in 289 | the documentation and/or other materials provided with the 290 | distribution. 291 | 292 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 293 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 294 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 295 | DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 296 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 297 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 298 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 299 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 300 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 301 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 302 | POSSIBILITY OF SUCH DAMAGE. 303 | 304 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of ADMML authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS file. 3 | # See the latter for an explanation. 4 | 5 | # Names should be added to this file as one of 6 | # Organization's name 7 | # Individual's name 8 | 9 | # Please keep the list sorted. 10 | 11 | Robert Bosch LLC 12 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Want to contribute? Great! You can do so through the standard GitHub pull 4 | request model. For large contributions we do encourage you to file a ticket in 5 | the GitHub issues tracking system prior to any code development to coordinate 6 | with the ADMML development team early in the process. Coordinating up 7 | front helps to avoid frustration later on. Please: 8 | 1. Follow a similar coding practice as mentioned in https://google.github.io/styleguide/pyguide.html 9 | 2. Rerun the examples in example.py and add a simple example highlighting the current functionality. 10 | 3. Run unit tests to check the correctness of the code. 11 | Any additional checks shall be discussed during integration. 12 | 13 | Your contribution should be licensed under the Apache-2.0 license, the license 14 | used by this project. 15 | 16 | ## Sign your work 17 | 18 | This project tracks patch provenance and licensing using a modified Developer 19 | Certificate of Origin (from [OSDL][DCO]) and Signed-off-by tags initially 20 | developed by the Linux kernel project. 21 | 22 | ``` 23 | ADMML Developer's Certificate of Origin. Version 1.0 24 | 25 | By making a contribution to this project, I certify that: 26 | 27 | (a) The contribution was created in whole or in part by me and I 28 | have the right to submit it under the license of "Apache License, 29 | Version 2.0" ("Apache-2.0"); or 30 | 31 | (b) The contribution is based upon previous work that is covered by 32 | an appropriate open source license and I have the right under 33 | that license to submit that work with modifications, whether 34 | created in whole or in part by me, under the Apache-2.0 license; 35 | or 36 | 37 | (c) The contribution was provided directly to me by some other 38 | person who certified (a), (b) and I have not modified it. 39 | 40 | (d) I understand and agree that this project and the contribution 41 | are public and that a record of the contribution (including all 42 | metadata and personal information I submit with it, including my 43 | sign-off) is maintained indefinitely and may be redistributed 44 | consistent with this project and the requirements of the Apache-2.0 45 | license or any open source license(s) involved, where they are 46 | relevant. 47 | 48 | (e) I am granting the contribution to this project under the terms of 49 | Apache-2.0. 50 | 51 | http://www.apache.org/licenses/LICENSE-2.0 52 | ``` 53 | 54 | With the sign-off in a commit message you certify that you authored the patch 55 | or otherwise have the right to submit it under an open source license. The 56 | procedure is simple: To certify above ADMML Developer's Certificate of 57 | Origin 1.0 for your contribution just append a line 58 | 59 | Signed-off-by: Random J Developer 60 | 61 | to every commit message using your real name (sorry, no pseudonyms or 62 | anonymous contributions). 63 | 64 | If you have set your `user.name` and `user.email` git configs you can 65 | automatically sign the commit by running the git-commit command with the `-s` 66 | option. There may be multiple sign-offs if more than one developer was 67 | involved in authoring the contribution. 68 | 69 | For a more detailed description of this procedure, please see 70 | [SubmittingPatches][] which was extracted from the Linux kernel project, and 71 | which is stored in an external repository. 72 | 73 | ### Individual vs. Corporate Contributors 74 | 75 | Often employers or academic institution claim ownership over code that is 76 | written in certain circumstances, so please do due diligence to ensure that 77 | you have the right to submit the code. 78 | 79 | If you are a developer who is authorized to contribute to ADMML on 80 | behalf of your employer, then please use your corporate email address in the 81 | Signed-off-by tag. Otherwise please use a personal email address. 82 | 83 | ## Maintain Contributors and Authors lists 84 | 85 | Each contributor is responsible for identifying themselves in the project 86 | [CONTRIBUTORS](CONTRIBUTORS) and [AUTHORS](AUTHORS) lists. Please add the 87 | respective information corresponding to the Singed-off-by tag to those files 88 | as part of your first pull request. 89 | 90 | If you are a developer who is authorized to contribute to ADMML on 91 | behalf of your employer, then add your company / organization to 92 | [AUTHORS](AUTHORS) and your name and corporate email address to 93 | [CONTRIBUTORS](CONTRIBUTORS) as in the Signed-off-by tag. 94 | 95 | 96 | [DCO]: http://web.archive.org/web/20070306195036/http://osdlab.org/newsroom/press_releases/2004/2004_05_24_dco.html 97 | 98 | [SubmittingPatches]: https://github.com/wking/signed-off-by/blob/7d71be37194df05c349157a2161c7534feaf86a4/Documentation/SubmittingPatches 99 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the official list of people who can contribute (and typically have 2 | # contributed) code to the ADMML repository. The AUTHORS file lists 3 | # the copyright holders; this file lists people. For example, Robert Bosch 4 | # LLC's employees are listed here but not in AUTHORS, because Robert Bosch 5 | # LLC holds the copyright. 6 | # 7 | # Often employers or academic institution claim ownership over code that is 8 | # written in certain circumstances, so please do due diligence to ensure that 9 | # you have the right to submit the code. 10 | # 11 | # When adding J Random Contributor's name to this file, either J's name or J's 12 | # organization's name should be added to the AUTHORS file, depending on 13 | # whether J's employer (or academic institution) claims ownership over code 14 | # that is written for this project. 15 | # 16 | # How to add names to this file: Individual's name . 17 | # Use corporate email address if Individual's organization is copyright holder 18 | # of her contributions. 19 | # List is sorted in chronological order of contribution. 20 | 21 | Sauptik Dhar 22 | Naveen Ramakrishnan 23 | Jeff Irion 24 | Jiayi Liu 25 | Unmesh Kurup 26 | Mohak Shah -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | **ADMML**: Alternating Direction Method based Scalable Machine Learning on Spark 2 | ================================================================================ 3 | 4 | The advent of big-data has seen an emergence of research on scalable machine learning (ML) algorithms and big data platforms. Several software frameworks have been introduced to handle the data deluge like, MapReduce, Hadoop, and Spark etc. Among them, Spark has been widely used by the ML community. Spark supports distributed in memory computations and provides practitioners with a powerful, fast, scalable and easy way to build ML algorithms. Although there have been several Spark based ML libraries, there are very few packages that cover a wide range of problems with fast and accurate results. This tool provides an Alternating Direction Method of Multipliers (ADMM) based approach that can be used as a general framework to accurately solve several standard and variants of most widely used machine learning algorithms at scale. 5 | 6 | The precursor to this tool is presented in [1,2]. It majorly follows the work provided in [3]. For implementation details please cite [1]. 7 | 8 | 1. S Dhar, C. Yi, N. Ramakrishnan N, M. Shah. `ADMM based scalable machine learning on Spark.` IEEE International Conference on in Big Data (Big Data), 2015 (pp. 1174-1182). 9 | 2. G Kamath, S. Dhar, N. Ramakrishnan, D. Hallac, J. Leskovec, M. Shah.`Scalable Machine Learning on Spark for multiclass problems`, Baylearn 2016 10 | 3. S Boyd, N. Parikh, E. Chu, B. Peleato, J. Eckstein. `Distributed optimization and statistical learning via the alternating direction method of multipliers.` Foundations and Trends in Machine Learning. 2011 Jan 1;3(1):1-22. 11 | 12 | Presented in Spark Summit 2017. ( https://spark-summit.org/2017/events/admm-based-scalable-machine-learning-on-apache-spark/ ) 13 | 14 | 15 | Installation and Configuration 16 | ------------------------------ 17 | 18 | Dependencies: 19 | 20 | * `Apache Spark `_ (Need Apache Spark 2.0.2 or higher. Tested on version 2.0.2) 21 | * `NumPy `_ (tested on version 1.10.4) 22 | * `setuptools `_ (tested on version 34.4.1) 23 | 24 | (These instructions were tested on centos2.6 only, but they should work on other platforms. Additionally, it has been tested on Python 2.7). 25 | 26 | 1. Clone the repository / Download the zipped file. 27 | 2. Navigate to the folder, i.e. the folder which contains setup.py 28 | 3. Build the .egg files (``python setup.py bdist_egg``) 29 | 4. Launch Pyspark and distribute the .egg file to all the cluster nodes for the pyspark context: 30 | ``sc.addPyFile('/dist/admml-0.1-py2.7.egg')`` 31 | 32 | 33 | Try the following example regression code: 34 | 35 | .. code-block:: python 36 | 37 | import admml.utils as utils 38 | import admml.mlalgs as ml 39 | trndata = sc.textFile('') 40 | trndata = trndata.map(utils.parse_vector) 41 | algoParam = ml.setDefaultAlgoParams() 42 | w, output, fval = ml.ADMMLeastSquares(trndata,algoParam) 43 | 44 | 45 | 46 | Building the Documentation 47 | -------------------------- 48 | 49 | (These instructions were tested on Windows only, but they should work on other platforms.) 50 | 51 | In order to build the documentation, you will need the following Python packages: 52 | 53 | * `Sphinx `_ (tested on version 1.5.5) 54 | * `numpydoc `_ (tested on version 0.6.0) 55 | * `sphinx_rtd_theme `_ (tested on version 0.2.4) 56 | * `mock `_ (tested on version 2.0.0) 57 | 58 | With these prerequisites in place, the documentation can be built as follows. 59 | 60 | 1. Navigate to the ``ADMML/docs`` folder. 61 | 2. Run the command ``sphinx-apidoc -f -e -o source/ ../admml/`` 62 | 3. Run the command ``make html`` (repeat this step until there are no warnings, which should require no more than 3 runs) 63 | 64 | Also see `User Manual `_ for detailed tool usage. 65 | 66 | License 67 | -------- 68 | ADMML is open-sourced under the Apache-2.0 license. See the `LICENSE `_ file for details. 69 | 70 | For a list of other open source components included in ADMML, see the 71 | file `3rd-party-licenses.txt <3rd-party-licenses.txt>`_ 72 | 73 | 74 | Contact 75 | ------- 76 | Sauptik Dhar 77 | -------------------------------------------------------------------------------- /User_Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DL-Benchmarks/ADMML/041c259d493cbd4b31018d002b311dfb0382eea0/User_Manual.pdf -------------------------------------------------------------------------------- /admml/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2017 The ADMML Authors. 3 | 4 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at : 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | """ 16 | 17 | from . import admml 18 | from . import examples 19 | from . import mappers 20 | from . import mlalgs 21 | from . import utils 22 | -------------------------------------------------------------------------------- /admml/admml.py: -------------------------------------------------------------------------------- 1 | """ADMM CORE ALGORITHM 2 | 3 | Copyright (c) 2017 The ADMML Authors. 4 | 5 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at : 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | """ 18 | 19 | from copy import copy 20 | 21 | import numpy as np 22 | from numpy.linalg import inv, norm 23 | 24 | from . import mappers 25 | from . import utils 26 | 27 | 28 | ########################## ADMM STEPS ################################ 29 | 30 | 31 | def ADMM(trndata, algoParam): 32 | """This is the main engine that implements the ADMM steps. 33 | 34 | Parameters 35 | ---------- 36 | trndata : RDD 37 | RDD with each entry as numpy array [y, **x**] 38 | algoParam : dict 39 | This contains the algorithm parameters for ML/ADMM algorithm. 40 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 41 | 42 | Returns 43 | ------- 44 | z : numpy.ndarray 45 | Weight vector [w,b] (bias term appended to end) 46 | output : dict 47 | Dictionary of the algorithm outputs 48 | 49 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 50 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 51 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 52 | * ``rel_norm_pri``: relative norm of primal residual 53 | * ``rel_norm_dual``: relative norm of dual residual 54 | 55 | """ 56 | def rho_initialize(algoParam): 57 | """This function initializes the algoParam['RHO'] value. 58 | 59 | There are several strategies, and this is an ongoing research topic. 60 | Current implementation use a fixed RHO = LAMBDA . 61 | Additional methods to be included later. For further details see: 62 | 63 | 1. Boyd, Stephen, et al. "Distributed optimization and statistical 64 | learning via the alternating direction method of multipliers." 65 | 2. Goldstein, Tom, et al. "Fast alternating direction optimization 66 | methods." SIAM Journal on Imaging Sciences 7.3 (2014): 1588-1623. 67 | 3. Ghadimi, Euhanna, et al. "Optimal parameter selection for the 68 | alternating direction method of multipliers (ADMM): quadratic 69 | problems." IEEE Transactions on Automatic Control 60.3 (2015): 70 | 644-658. 71 | 72 | Parameters 73 | ---------- 74 | algoParam : dict 75 | This contains the algorithm parameters for ML/ADMM algorithm. 76 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 77 | 78 | Returns 79 | ------- 80 | algoParam : dict 81 | The ``algoParam`` dict with correctly initialized rho 82 | 83 | """ 84 | if algoParam['RHO_INITIAL'] == 0: 85 | algoParam['RHO'] = algoParam['LAMBDA'] 86 | else: 87 | raise ValueError('Inconsistent RHO Selection!') 88 | return algoParam 89 | 90 | def rho_adjustment(rho, norm_pri, norm_dual): 91 | """This function defines the adaptive RHO updates. 92 | 93 | There are several strategies, and this is an ongoing research topic. 94 | We use the version of the strategy in [Boyd, 2011] pg. 20 95 | 96 | 1. Boyd, Stephen, et al. "Distributed optimization and statistical 97 | learning via the alternating direction method of multipliers." 98 | 99 | Parameters 100 | ---------- 101 | rho : float 102 | Current RHO value 103 | norm_pri : float 104 | Current normed primal residual 105 | norm_dual : float 106 | Current normed dual residual 107 | 108 | Returns 109 | ------- 110 | rho : float 111 | Updated RHO 112 | 113 | """ 114 | if norm_pri > 10*norm_dual: 115 | rho *= 2 116 | elif norm_dual > 10*norm_pri: 117 | rho /= 2 118 | 119 | return rho 120 | 121 | def z_update(w, u, algoParam): 122 | """**z** update steps in ADMM Algorithm. Changes only for different regularizers. 123 | 124 | Parameters 125 | ---------- 126 | w : numpy.ndarray 127 | w-vector obtained from the previous w-update step 128 | u : numpy.ndarray 129 | u-vector (current state) 130 | algoParam : dict 131 | This contains the algorithm parameters for ML/ADMM algorithm. 132 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 133 | 134 | Returns 135 | ------- 136 | z : numpy.ndarray 137 | z-update step 138 | 139 | """ 140 | D = algoParam['D'] 141 | z = np.zeros(D) 142 | 143 | # PROXIMAL OPERATORS 144 | # ELASTIC-NET REGULARIZER 145 | if algoParam['REG'] == 'elasticnet': 146 | for j in range(D): 147 | if algoParam['RHO']*(w[j]+u[j]) > algoParam['LAMBDA']*algoParam['DELTA'][j]*algoParam['ALPHA']: 148 | z[j] = (algoParam['RHO']*(w[j]+u[j])-algoParam['LAMBDA']*algoParam['DELTA'][j]*algoParam['ALPHA'])/(algoParam['LAMBDA']*algoParam['DELTA'][j]*(1-algoParam['ALPHA'])+algoParam['RHO']) 149 | elif algoParam['RHO']*(w[j]+u[j]) < -algoParam['LAMBDA']*algoParam['DELTA'][j]*algoParam['ALPHA']: 150 | z[j] = (algoParam['RHO']*(w[j]+u[j])+algoParam['LAMBDA']*algoParam['DELTA'][j]*algoParam['ALPHA'])/(algoParam['LAMBDA']*algoParam['DELTA'][j]*(1-algoParam['ALPHA'])+algoParam['RHO']) 151 | 152 | # GROUP-REGULARIZER 153 | elif algoParam['REG'] == 'group': 154 | G = algoParam['G'] 155 | Gmax = len(G) 156 | for j in range(Gmax): 157 | gind = np.where(algoParam['DELTA'] == j)[0] 158 | wG = w[gind] 159 | uG = u[gind] 160 | zG = max(norm(wG+uG)-(algoParam['LAMBDA']*G[j])/algoParam['RHO'], 0.)*((wG+uG)/norm(wG+uG)) 161 | z[gind] = zG 162 | else: 163 | raise ValueError('ERROR: Unsupported Regularizer.') 164 | 165 | return z 166 | 167 | def w_update(trndata, z, u, algoParam): 168 | """**w** update steps in ADMM Algorithm. Changes only for different loss functions 169 | 170 | Parameters 171 | ---------- 172 | trndata : RDD 173 | RDD with each entry as numpy array [y,x] 174 | z : numpy.ndarray 175 | z-vector from previous state 176 | u : numpy.ndarray 177 | u-vector from previous state 178 | algoParam : dict 179 | This contains the algorithm parameters for ML/ADMM algorithm. 180 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 181 | 182 | Returns 183 | ------- 184 | w : numpy.ndarray 185 | w-update step 186 | 187 | """ 188 | N = algoParam['N'] 189 | D = algoParam['D'] 190 | 191 | if algoParam['LOSS'] == 'leastsq': 192 | P = trndata.map(lambda x: np.outer(x[1:], x[1:])).reduce(lambda x, y: np.add(x, y))/N + algoParam['RHO']*np.identity(D) 193 | q = trndata.map(lambda x: np.dot(x[0], x[1:])).reduce(lambda x, y: np.add(x, y))/N + algoParam['RHO']*(z - u) 194 | return np.dot(inv(P), q) 195 | 196 | # HUBER & PSEUDO-HUBER: initialize with the least-squares solution 197 | if algoParam['LOSS'] in ['huber', 'pseudo_huber'] and algoParam['PROBLEM'] == 'regression': 198 | P = trndata.map(lambda x: np.outer(x[1:], x[1:])).reduce(lambda x, y: np.add(x, y))/N + algoParam['RHO']*np.identity(D) 199 | q = trndata.map(lambda x: np.dot(x[0], x[1:])).reduce(lambda x, y: np.add(x, y))/N + algoParam['RHO']*(z - u) 200 | w = np.dot(inv(P), q) 201 | mu_max = algoParam['MU_MAX'] # GRADUALLY OBTAIN FINAL SOLUTION 202 | else: 203 | w = np.zeros(D) 204 | mu_max = None 205 | 206 | # NEWTON UPDATES 207 | for j in range(algoParam['MAX_INNER_ITER']): 208 | if algoParam['LOSS'] in ['huber', 'pseudo_huber'] and algoParam['PROBLEM'] == 'regression': 209 | mu_max = max(mu_max, algoParam['MU']) 210 | 211 | H_v = trndata.map(lambda x: mappers.mapHv(algoParam, x, w, mu_max)).reduce(utils.combineHv) 212 | 213 | H = H_v[0]/N 214 | v = H_v[1]/N 215 | P = H + algoParam['RHO']*(np.identity(D)) 216 | Pinv = inv(P) 217 | q = v + algoParam['RHO']*(w-z+u) 218 | 219 | w_old = copy(w) 220 | w = w - np.dot(Pinv, q) 221 | in_residual = norm(w-w_old)/norm(w) 222 | 223 | if mu_max is not None: 224 | if in_residual < algoParam['INNER_TOL'] and mu_max-algoParam['MU'] <= 1e-6: 225 | break 226 | else: 227 | mu_max /= 2. 228 | 229 | elif in_residual < algoParam['INNER_TOL']: 230 | break 231 | 232 | return w 233 | 234 | # ADMM ALGORITHM 235 | D = algoParam['D'] 236 | z = u = np.zeros(D) 237 | W_k = z 238 | rel_norm_pri = [] 239 | rel_norm_dual = [] 240 | 241 | # INITIALIZE RHO 242 | algoParam = rho_initialize(algoParam) 243 | 244 | for k in range(algoParam['MAX_ITER']): 245 | z_old = copy(z) 246 | w = w_update(trndata, z, u, algoParam) 247 | z = z_update(w, u, algoParam) 248 | u = u+w-z 249 | norm_pri = norm(w-z) 250 | norm_dual = norm(z-z_old) 251 | W_k = np.vstack((W_k, z)) 252 | rel_norm_pri.append(norm_pri/norm(w)) 253 | rel_norm_dual.append(norm_dual/norm(z)) 254 | 255 | if algoParam['RHO_ADAPTIVE_FLAG']: 256 | algoParam['RHO'] = rho_adjustment(algoParam['RHO'], rel_norm_pri[k], rel_norm_dual[k]) 257 | 258 | converged = rel_norm_pri[k] < algoParam['PRIM_TOL'] and rel_norm_dual[k] < algoParam['DUAL_TOL'] 259 | if converged: 260 | break 261 | elif algoParam['VERBOSE'] == 1: 262 | # print the convergence results 263 | print("Iteration: {0} Current RHO : ({1}) Primal Residual (Rel.): {2}({3}) Dual Residual (Rel.): {4}({5})".format(k+1, algoParam['RHO'], norm_pri, rel_norm_pri[k], norm_dual, rel_norm_dual[k])) 264 | 265 | output = {'W_k': W_k, 266 | 'norm_pri': norm_pri, 267 | 'norm_dual': norm_dual, 268 | 'rel_norm_pri': rel_norm_pri, 269 | 'rel_norm_dual': rel_norm_dual} 270 | 271 | return z, output 272 | -------------------------------------------------------------------------------- /admml/examples.py: -------------------------------------------------------------------------------- 1 | """Basic Examples 2 | 3 | Copyright (c) 2017 The ADMML Authors. 4 | 5 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at : 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | """ 18 | 19 | 20 | import numpy as np 21 | 22 | from . import utils 23 | from . import mlalgs 24 | from . import admml 25 | 26 | 27 | def example(trndata, tstdata, example=1): 28 | """This module shows three basic examples to use the tool. 29 | 30 | Parameters 31 | ---------- 32 | trndata : RDD 33 | This is the training data on which the models are trained. 34 | This is an RDD of numbers only created by reading a comma separated file through ``sc.textFile()``. 35 | The 1st field is y-labels 36 | i.e. ``trndata = sc.textFile('\\trndata.csv')`` 37 | tstdata : RDD 38 | This is the test data on which the models are scored. 39 | This is an RDD of numbers only created by reading a comma separated file through ``sc.textFile()``. 40 | The 1st field is y-labels. 41 | i.e. ``trndata = sc.textFile('\\tstdata.csv')`` 42 | example : int {1,2,3} 43 | 1 = L2-Linear Regression, 2 = L2-Logistic Regression, 3 = Group - Linear Regression 44 | 45 | Returns 46 | ------- 47 | w : numpy.ndarray 48 | Weight vector [w,b] (bias term appended to end) 49 | 50 | """ 51 | trndata = trndata.map(utils.parse_vector) #(NEED DATA IN VSM) ARRAY of RDDS 52 | tstdata = tstdata.map(utils.parse_vector) 53 | 54 | if example == 1: #USE PREBUILT FUNCTIONS 55 | algoParam = mlalgs.setDefaultAlgoParams() 56 | algoParam['PROBLEM'] = 'regression' 57 | algoParam['VERBOSE'] = 1 58 | w, output, fval = mlalgs.ADMMLeastSquares(trndata, algoParam) 59 | 60 | test_err = mlalgs.predict(tstdata, w, algoParam) 61 | train_err = mlalgs.predict(trndata, w, algoParam) 62 | 63 | print('Test Error = {0}'.format(test_err)) 64 | print('Train Error = {0}'.format(train_err)) 65 | print('Minimized Function Value = {0}'.format(fval)) 66 | 67 | elif example == 2: 68 | algoParam = mlalgs.setDefaultAlgoParams() 69 | algoParam['PROBLEM'] = 'binary' 70 | algoParam['VERBOSE'] = 1 71 | w, output, fval = mlalgs.ADMMLogistic(trndata, algoParam) 72 | 73 | test_err = mlalgs.predict(tstdata, w, algoParam) 74 | train_err = mlalgs.predict(trndata, w, algoParam) 75 | 76 | print('Test Error = {0}'.format(test_err)) 77 | print('Train Error = {0}'.format(train_err)) 78 | print('Minimized Function Value = {0}'.format(fval)) 79 | 80 | elif example == 3: # PLUG AND PLAY 81 | 82 | algoParam = mlalgs.setDefaultAlgoParams() 83 | trn = trndata.map(utils.append_one) 84 | N = trn.count() 85 | D = trn.first().size-1 # Data format is [y,X,1] 86 | algoParam['D'] = D 87 | algoParam['N'] = N 88 | algoParam['PROBLEM'] = 'regression' 89 | 90 | # GROUP REGULARIZER 91 | algoParam['REG'] = 'group' 92 | algoParam['VERBOSE'] = 0 93 | # CHANGE DELTA and G for different data. CURRENT SETTING IS FOR DATA LINK: https://archive.ics.uci.edu/ml/datasets/Breast+Cancer (ONLY FOR ILLUSTRATION) 94 | algoParam['G'] = np.array([1.0, 1.0, 1.0, 0]/np.sqrt(3)) 95 | algoParam['DELTA'] = np.array([0, 1, 2, 0, 1, 2, 0, 1, 2, 3]) 96 | 97 | #LOGISTIC LOSS 98 | algoParam['LOSS'] = 'leastsq' 99 | algoParam['LAMBDA'] = 0.1 # REGULARIZATION PARAMETER 100 | algoParam['RHO_ADAPTIVE_FLAG'] = False 101 | 102 | w, output = admml.ADMM(trn, algoParam) 103 | train_err = mlalgs.predict(trndata, w, algoParam) 104 | 105 | print('Train Error = {0}'.format(train_err)) 106 | 107 | return w 108 | -------------------------------------------------------------------------------- /admml/mappers.py: -------------------------------------------------------------------------------- 1 | """This module contains the mappers to compute the Hessian/gradients in a distributed fashion 2 | 3 | Copyright (c) 2017 The ADMML Authors. 4 | 5 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at : 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | 18 | """ 19 | 20 | 21 | from math import exp 22 | 23 | import numpy as np 24 | 25 | 26 | def mapHv(algoParam, vector, w, mu): 27 | """Map function to compute the appropriate Hessian/Gradient based on 28 | ``algoParam['LOSS']`` and ``algoParam['PROBLEM']``. 29 | 30 | Parameters 31 | ---------- 32 | algoParam : dict 33 | This contains the algorithm parameters for ML/ADMM algorithm. 34 | The default can be set as: ``algoParam = setDefaultAlgoParams()``. 35 | Here ``algoParam['LOSS']`` and ``algoParam['PROBLEM']`` should be 36 | specified 37 | vector : numpy.ndarray 38 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 39 | w : numpy.ndarray 40 | weight vector at the current internal newtonian iteration. 41 | mu : float 42 | The :math:`\\mu` value only for Huber/Pseudo-Huber Loss. Else it's None. 43 | 44 | Returns 45 | ------- 46 | H_i : numpy.ndarray 47 | The i-th sample's contribution to the Hessian 48 | v_i : numpy.ndarray 49 | The i-th sample's contribution to the gradient 50 | 51 | """ 52 | if algoParam['LOSS'] == 'logistic' and algoParam['PROBLEM'] == 'binary': 53 | return _mapHv_logistic_binary(vector, w) 54 | 55 | elif algoParam['LOSS'] == 'hinge' and algoParam['PROBLEM'] == 'binary': # SHALL BE PROVIDED IN NEXT VERSION 56 | raise ValueError('ERROR: Currently Unsupported.') 57 | 58 | elif algoParam['LOSS'] == 'sq_hinge' and algoParam['PROBLEM'] == 'binary': 59 | return _mapHv_sq_hinge_binary(vector, w, algoParam['D']) 60 | 61 | elif algoParam['LOSS'] == 'smooth_hinge' and algoParam['PROBLEM'] == 'binary': 62 | return _mapHv_smooth_hinge_binary(vector, w, algoParam['D']) 63 | 64 | elif algoParam['LOSS'] == 'pseudo_huber' and algoParam['PROBLEM'] == 'regression': 65 | return _mapHv_pseudo_huber_regression(vector, w, mu) 66 | 67 | elif algoParam['LOSS'] == 'huber' and algoParam['PROBLEM'] == 'regression': 68 | return _mapHv_huber_regression(vector, w, mu) 69 | 70 | else: 71 | raise ValueError('ERROR: Unsupported Loss Function.') 72 | 73 | 74 | def _mapHv_logistic_binary(vector, w): 75 | """COMPUTE DISTRIBUTED HESSIAN/GRADIENT 76 | 77 | Parameters 78 | ---------- 79 | vector : numpy.ndarray 80 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 81 | w : numpy.ndarray 82 | weight vector at the current internal newtonian iteration. 83 | 84 | Returns 85 | ------- 86 | H_i : numpy.ndarray 87 | The i-th sample's contribution to the Hessian 88 | v_i : numpy.ndarray 89 | The i-th sample's contribution to the gradient 90 | 91 | """ 92 | y = vector[0] 93 | x = vector[1:] 94 | eta = y * (np.dot(x, w)) 95 | p = 1 / (1 + exp(-eta)) 96 | v_i = -y * (1 - p) * x 97 | H_i = (1 - p) * p * (np.outer(x, x)) 98 | return H_i, v_i 99 | 100 | 101 | def _mapHv_sq_hinge_binary(vector, w, D): 102 | """COMPUTE DISTRIBUTED HESSIAN/GRADIENT 103 | 104 | Parameters 105 | ---------- 106 | vector : numpy.ndarray 107 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 108 | w : numpy.ndarray 109 | weight vector at the current internal newtonian iteration. 110 | D : int 111 | the dimension of the sample 112 | 113 | Returns 114 | ------- 115 | H_i : numpy.ndarray 116 | The i-th sample's contribution to the Hessian 117 | v_i : numpy.ndarray 118 | The i-th sample's contribution to the gradient 119 | 120 | """ 121 | y = vector[0] 122 | x = vector[1:] 123 | z = y * (np.dot(w, x)) 124 | 125 | if z >= 1.0: 126 | H_i = np.zeros([D, D]) 127 | v_i = np.zeros(D) 128 | 129 | else: 130 | H_i = np.outer(x, x) 131 | v_i = (-y * (1.0 - z)) * x 132 | 133 | return H_i, v_i 134 | 135 | 136 | def _mapHv_smooth_hinge_binary(vector, w, D): 137 | """COMPUTE DISTRIBUTED HESSIAN/GRADIENT (DO NOT USE!!) 138 | 139 | Parameters 140 | ---------- 141 | vector : numpy.ndarray 142 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 143 | w : numpy.ndarray 144 | weight vector at the current internal newtonian iteration. 145 | D : int 146 | the dimension of the sample 147 | 148 | Returns 149 | ------- 150 | H_i : numpy.ndarray 151 | The i-th sample's contribution to the Hessian 152 | v_i : numpy.ndarray 153 | The i-th sample's contribution to the gradient 154 | 155 | """ 156 | y = vector[0] 157 | x = vector[1:] 158 | z = y * (np.dot(w, x)) 159 | 160 | if z >= 1.0: 161 | H_i = np.zeros([D, D]) 162 | v_i = np.zeros(D) 163 | 164 | elif 0.0 < z < 1.0: 165 | H_i = np.outer(x, x) 166 | v_i = (-y * (1.0 - z)) * x 167 | 168 | else: 169 | H_i = np.zeros([D, D]) 170 | v_i = -y * x 171 | 172 | return H_i, v_i 173 | 174 | 175 | def _mapHv_pseudo_huber_regression(vector, w, mu): 176 | """COMPUTE DISTRIBUTED HESSIAN/GRADIENT 177 | 178 | Parameters 179 | ---------- 180 | vector : numpy.ndarray 181 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 182 | w : numpy.ndarray 183 | weight vector at the current internal newtonian iteration. 184 | mu : float 185 | The :math:`\\mu` value only for Pseudo-Huber Loss. 186 | 187 | Returns 188 | ------- 189 | H_i : numpy.ndarray 190 | The i-th sample's contribution to the Hessian 191 | v_i : numpy.ndarray 192 | The i-th sample's contribution to the gradient 193 | 194 | """ 195 | y = vector[0] 196 | x = vector[1:] 197 | s = (y - np.dot(x, w)) 198 | v_i = -(s / np.sqrt(mu ** 2 + s ** 2)) * x 199 | H_i = ((mu ** 2) / np.sqrt(mu ** 2 + s ** 2) ** 3) * np.outer(x, x) 200 | return H_i, v_i 201 | 202 | 203 | def _mapHv_huber_regression(vector, w, mu): 204 | """COMPUTE DISTRIBUTED HESSIAN/GRADIENT 205 | 206 | Parameters 207 | ---------- 208 | vector : numpy.ndarray 209 | Data sample (a row of data matrix) which contributes to Hessian/Gradient 210 | w : numpy.ndarray 211 | weight vector at the current internal newtonian iteration. 212 | mu : float 213 | The :math:`\\mu` value only for Huber Loss. 214 | 215 | Returns 216 | ------- 217 | H_i : numpy.ndarray 218 | The i-th sample's contribution to the Hessian 219 | v_i : numpy.ndarray 220 | The i-th sample's contribution to the gradient 221 | 222 | """ 223 | 224 | def trimg(s, mu): 225 | return max(-mu, min(mu, s)) 226 | 227 | def trimH(s, mu): 228 | return float(abs(s) <= mu) 229 | 230 | y = vector[0] 231 | x = vector[1:] 232 | s = (y - np.dot(x, w)) 233 | v_i = -trimg(s, mu) * x 234 | H_i = trimH(s, mu) * np.outer(x, x) 235 | return H_i, v_i 236 | -------------------------------------------------------------------------------- /admml/mlalgs.py: -------------------------------------------------------------------------------- 1 | """ML Algorithms 2 | 3 | Copyright (c) 2017 The ADMML Authors. 4 | 5 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at : 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | """ 18 | 19 | 20 | import numpy as np 21 | from numpy import sign 22 | from numpy.linalg import norm 23 | 24 | from . import admml 25 | from . import utils 26 | 27 | 28 | def setDefaultAlgoParams(): 29 | """This module creates a default template of the algorithm parameters. 30 | 31 | Returns 32 | ------- 33 | algoParam : dict 34 | a dictionary with keys and values (default values are in bold): 35 | 36 | * **PROBLEM: 'binary'**,'regression' 37 | * **REG: 'elasticnet'**, 'group' 38 | * **LOSS: 'logistic'** (classification), 'sq_hinge' (classification), 'leastsq' (classification/regression), 39 | 'huber' (regression), 'pseudo_huber' (regression) 40 | * **LAMBDA: 1.0** , (Regularization parameter) 41 | * **ALPHA: 0.0**, (Elastic-Net parameter) 42 | * **MU: 0.1**, ((Pseudo)-Huber Threshold parameter) 43 | * **SCALE: 'Uniform'**, 'Normalize', 'None' 44 | * **RHO: 1.0**, (ADMM augmented lagrangian penalty term) 45 | * **RHO_INITIAL: 0**, 1 (0 = Constant (RHO = LAMBDA) , 1 = Goldstein (pending)) 46 | * **RHO_ADAPTIVE_FLAG: False**, True 47 | * **MAX_ITER: 100**, (Max. iterations for ADMM updates) 48 | * **PRIM_TOL: 1e-4**, (Error tolerance of relative primal residual) 49 | * **DUAL_TOL: 1e-4**, (Error tolerance of relative dual residual) 50 | * **MAX_INNER_ITER: 10**, (Max. iteration for internal newton updates) 51 | * **INNER_TOL: 1e-6**, (Relative error tolerance of internal iterations) 52 | * **VERBOSE: 0** (no print), 1 (print) 53 | 54 | """ 55 | algoParam = {'PROBLEM': 'binary', # 'binary'(default),'regression', multiclass (pending) 56 | 'REG': 'elasticnet', # 'elasticnet'(default), 'group' , 'scad (non-convex pending)' 57 | 'LOSS': 'logistic', # Classification :: 'logistic'(default),'sq_hinge','leastsq' 58 | # Regression :: 'leastsq','huber','pseudo_huber' 59 | 'LAMBDA': 1.0, # Regularization parameter 'lambda' 60 | 'ALPHA': 0.0, # Alpha (Elastic net param). Formulation:- (Alpha)*norm(w,1) + (1-Alpha)/2 * norm(w,2)^2 61 | 'SCALE': 'Uniform', # 'Uniform'(default), 'Normalize', 'None' 62 | 'MAX_ITER': 100, # Max outer iteration 63 | 'MAX_INNER_ITER': 10, # Max Inner iteration for Newton Updates:- Logistic , Huber, Pseudo-Huber 64 | 'RHO': 1.0, # RHO FOR ADMM 65 | 'RHO_INITIAL': 0, # 0 = Constant (RHO) , 1 = Goldstein 66 | 'RHO_ADAPTIVE_FLAG': False, # This Flag sets the RHO Adaptive per step. True= Adaptive RHO, False = Non-Adaptive RHO 67 | 'PRIM_TOL': 1e-4, # Relative Tolerance Primal Residual 68 | 'DUAL_TOL': 1e-4, # Relative Tolerance Dual Residual 69 | 'INNER_TOL': 1e-6, # Inner Newton update Tolerance Level 70 | 'N': 0, # No of Samples. Has to be set. 71 | 'D': 0, # No of Dimension. Has to be set 72 | 'K': 1, # No of classes (binary = 1, Multiclass > 1 (pending)) 73 | 'EIG_VALS_FLAG': 0, # 0 = SCIPY (exact), 1 = APPROX (pending) 74 | 'MU': 0.1, # Threshold for Huber loss 75 | 'MU_MAX': 1.0, # HUBER START FROM EASIER PROBLEM 76 | 'VERBOSE': 0 # 0 = No Prints, 1 = Prints 77 | } 78 | 79 | return algoParam 80 | 81 | 82 | def _ADMM_ML_Algorithm(trndata, algoParam, algorithm): 83 | """Generic internal function that calls ADMM to solve ML algorithms 84 | 85 | Parameters 86 | ---------- 87 | trndata : RDD 88 | RDD with each entry as numpy array [y,x] 89 | algoParam : dict 90 | This contains the algorithm parameters for ML/ADMM algorithm. 91 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 92 | algorithm : str 93 | the machine learning algorithm to be used. Currently supported ML 94 | Algorithms: 95 | 96 | * Classification : 'logistic', 'l2svm', 'lssvm' 97 | * Regression : 'leastsq','pseudo_huber','huber' 98 | 99 | Returns 100 | ------- 101 | w : numpy.ndarray 102 | Weight vector [w,b] (bias term appended to end) 103 | output : dict 104 | Dictionary of the algorithm outputs 105 | 106 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 107 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 108 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 109 | * ``rel_norm_pri``: relative norm of primal residual 110 | * ``rel_norm_dual``: relative norm of dual residual 111 | 112 | fval : numpy.float64 113 | Function Value at the optimal solution 114 | 115 | """ 116 | # APPEND ONES FOR BIAS TERM 117 | trndata = trndata.map(utils.append_one) # THIS TAKES CARE OF BIAS TERM. 118 | 119 | # DATA PROPERTIES 120 | N = trndata.count() 121 | D = trndata.first().size-1 # FIRST COLUMN IS y 122 | algoParam['D'] = D 123 | algoParam['N'] = N 124 | 125 | # LOSS FUNCTION 126 | if algorithm.lower() == 'logistic': 127 | algoParam['LOSS'] = 'logistic' 128 | elif algorithm.lower() == 'l2svm': 129 | algoParam['LOSS'] = 'sq_hinge' 130 | elif algorithm.lower() in ['lssvm', 'leastsq']: 131 | algoParam['LOSS'] = 'leastsq' 132 | elif algorithm.lower() == 'pseudo_huber': 133 | algoParam['LOSS'] = 'pseudo_huber' 134 | elif algorithm.lower() == 'huber': 135 | algoParam['LOSS'] = 'huber' 136 | 137 | #REGULARIZER 138 | if algoParam['REG'] == 'elasticnet': # AUTOMATICALLY TAKE CARE OF ELASTIC NET. GROUP REGULARIZER NEEDS DELTA, G TO BE SET BY USER 139 | algoParam['DELTA'] = np.ones(D-1) 140 | algoParam['DELTA'] = np.append(algoParam['DELTA'], 0.) # NO REGULARIZATION IN BIAS SPACE 141 | 142 | w, output = admml.ADMM(trndata, algoParam) 143 | fval = functionVals(trndata, w, algoParam) 144 | 145 | return w, output, fval 146 | 147 | 148 | ###################### BINARY LOG REG ########################### 149 | def ADMMLogistic(trndata, algoParam): 150 | """Solves the (Elastic-Net + Group) Logistic Regression problem 151 | 152 | Parameters 153 | ---------- 154 | trndata : RDD 155 | RDD with each entry as numpy array [y,x] 156 | algoParam : dict 157 | This contains the algorithm parameters for ML/ADMM algorithm. 158 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 159 | 160 | Returns 161 | ------- 162 | w : numpy.ndarray 163 | Weight vector [w,b] (bias term appended to end) 164 | output : dict 165 | Dictionary of the algorithm outputs 166 | 167 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 168 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 169 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 170 | * ``rel_norm_pri``: relative norm of primal residual 171 | * ``rel_norm_dual``: relative norm of dual residual 172 | 173 | fval : numpy.float64 174 | Function Value at the optimal solution 175 | 176 | """ 177 | return _ADMM_ML_Algorithm(trndata, algoParam, 'Logistic') 178 | 179 | 180 | ###################### L2-SVM (BINARY) ############################## 181 | def ADMML2SVM(trndata,algoParam): 182 | """Solves the (Elastic-Net + Group) L2-SVM classification problem 183 | 184 | Parameters 185 | ---------- 186 | trndata : RDD 187 | RDD with each entry as numpy array [y,x] 188 | algoParam : dict 189 | This contains the algorithm parameters for ML/ADMM algorithm. 190 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 191 | 192 | Returns 193 | ------- 194 | w : numpy.ndarray 195 | Weight vector [w,b] (bias term appended to end) 196 | output : dict 197 | Dictionary of the algorithm outputs 198 | 199 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 200 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 201 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 202 | * ``rel_norm_pri``: relative norm of primal residual 203 | * ``rel_norm_dual``: relative norm of dual residual 204 | 205 | fval : numpy.float64 206 | Function Value at the optimal solution 207 | 208 | """ 209 | return _ADMM_ML_Algorithm(trndata, algoParam, 'L2SVM') 210 | 211 | 212 | ###################### LS SVM (BINARY) ############################# 213 | def ADMMLSSVM(trndata,algoParam): 214 | """Solves the (Elastic-Net + Group) LS-SVM classification problem 215 | 216 | Parameters 217 | ---------- 218 | trndata : RDD 219 | RDD with each entry as numpy array [y,x] 220 | algoParam : dict 221 | This contains the algorithm parameters for ML/ADMM algorithm. 222 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 223 | 224 | Returns 225 | ------- 226 | w : numpy.ndarray 227 | Weight vector [w,b] (bias term appended to end) 228 | output : dict 229 | Dictionary of the algorithm outputs 230 | 231 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 232 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 233 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 234 | * ``rel_norm_pri``: relative norm of primal residual 235 | * ``rel_norm_dual``: relative norm of dual residual 236 | 237 | fval : numpy.float64 238 | Function Value at the optimal solution 239 | 240 | """ 241 | return _ADMM_ML_Algorithm(trndata, algoParam, 'LSSVM') 242 | 243 | 244 | ###################### LINEAR REGRESSION ############################# 245 | def ADMMLeastSquares(trndata,algoParam): 246 | """Solves the (Elastic-Net + Group) Linear Regression problem 247 | 248 | Parameters 249 | ---------- 250 | trndata : RDD 251 | RDD with each entry as numpy array [y,x] 252 | algoParam : dict 253 | This contains the algorithm parameters for ML/ADMM algorithm. 254 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 255 | 256 | Returns 257 | ------- 258 | w : numpy.ndarray 259 | Weight vector [w,b] (bias term appended to end) 260 | output : dict 261 | Dictionary of the algorithm outputs 262 | 263 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 264 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 265 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 266 | * ``rel_norm_pri``: relative norm of primal residual 267 | * ``rel_norm_dual``: relative norm of dual residual 268 | 269 | fval : numpy.float64 270 | Function Value at the optimal solution 271 | 272 | """ 273 | return _ADMM_ML_Algorithm(trndata, algoParam, 'leastsq') 274 | 275 | 276 | ###################### PSEUDO-HUBER REGRESSION ######################## 277 | def ADMMPseudoHuber(trndata,algoParam): 278 | """Solves the (Elastic-Net + Group) Pseudo-Huber Regression problem 279 | 280 | Parameters 281 | ---------- 282 | trndata : RDD 283 | RDD with each entry as numpy array [y,x] 284 | algoParam : dict 285 | This contains the algorithm parameters for ML/ADMM algorithm. 286 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 287 | 288 | Returns 289 | ------- 290 | w : numpy.ndarray 291 | Weight vector [w,b] (bias term appended to end) 292 | output : dict 293 | Dictionary of the algorithm outputs 294 | 295 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 296 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 297 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 298 | * ``rel_norm_pri``: relative norm of primal residual 299 | * ``rel_norm_dual``: relative norm of dual residual 300 | 301 | fval : numpy.float64 302 | Function Value at the optimal solution 303 | 304 | """ 305 | return _ADMM_ML_Algorithm(trndata, algoParam, 'pseudo_huber') 306 | 307 | 308 | ###################### HUBER REGRESSION ######################## 309 | def ADMMHuber(trndata,algoParam): 310 | """Solves the (Elastic-Net + Group) Huber Regression problem 311 | 312 | Parameters 313 | ---------- 314 | trndata : RDD 315 | RDD with each entry as numpy array [y,x] 316 | algoParam : dict 317 | This contains the algorithm parameters for ML/ADMM algorithm. 318 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 319 | 320 | Returns 321 | ------- 322 | w : numpy.ndarray 323 | Weight vector [w,b] (bias term appended to end) 324 | output : dict 325 | Dictionary of the algorithm outputs 326 | 327 | * ``W_k``: each row correspond to w vectors at k_th ADMM iteration 328 | * ``norm_pri``: :math:`\\ell^2`-norm of primal residual 329 | * ``norm_dual``: :math:`\\ell^2`-norm of dual residual 330 | * ``rel_norm_pri``: relative norm of primal residual 331 | * ``rel_norm_dual``: relative norm of dual residual 332 | 333 | fval : numpy.float64 334 | Function Value at the optimal solution 335 | 336 | """ 337 | return _ADMM_ML_Algorithm(trndata, algoParam, 'huber') 338 | 339 | 340 | ###################### ML FORMULATIONS ########################## 341 | def functionVals(trndata, w, algoParam): 342 | """Provides function values for the supported algorithms at specified w-values. 343 | 344 | Parameters 345 | ---------- 346 | trndata : RDD 347 | RDD with each entry as numpy array [y,x] 348 | w : numpy.ndarray 349 | Weight vector [w,b] (bias term appended to end) 350 | algoParam : dict 351 | This contains the algorithm parameters for ML/ADMM algorithm. 352 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 353 | 354 | Returns 355 | ------- 356 | fval :numpy.float64 357 | Function Value at the specified w-value 358 | 359 | """ 360 | loss = 1e6 361 | reg = 1e6 362 | 363 | def Huber(vector, w, mu): 364 | 365 | y = vector[0] 366 | x = vector[1:] 367 | z = y-np.dot(w, x) 368 | 369 | if np.abs(z) <= mu: 370 | val = 0.5*(z**2) 371 | else: 372 | val = mu*np.abs(z) - 0.5*(mu**2) 373 | 374 | return val 375 | 376 | # LOSS 377 | if algoParam['PROBLEM'] == 'binary': 378 | if algoParam['LOSS'] == 'logistic': 379 | loss = (1.0/algoParam['N'])*(trndata.map(lambda x: np.log1p(np.exp(-x[0]*np.dot(x[1:], w)))).reduce(lambda x, y: x+y)) 380 | elif algoParam['LOSS'] == 'sq_hinge': 381 | loss = (0.5/algoParam['N'])*(trndata.map(lambda x: (max(0,1-x[0]*(np.dot(x[1:], w))))**2).reduce(lambda x, y: x+y)) 382 | elif algoParam['LOSS'] == 'leastsq': 383 | loss = (0.5/algoParam['N'])*(trndata.map(lambda x: (x[0]-np.dot(x[1:], w))**2).reduce(lambda x, y: x+y)) 384 | else: 385 | raise ValueError('Inconsistent LOSS function.') 386 | 387 | elif algoParam['PROBLEM'] == 'regression': 388 | if algoParam['LOSS'] == 'leastsq': 389 | loss = (0.5/algoParam['N'])*(trndata.map(lambda x: (x[0]-np.dot(x[1:], w))**2).reduce(lambda x, y: x+y)) 390 | elif algoParam['LOSS'] == 'pseudo_huber': 391 | loss = (1.0/algoParam['N'])*(trndata.map(lambda x: np.sqrt(algoParam['MU']**2 + (x[0]-np.dot(x[1:], w))**2)-algoParam['MU']).reduce(lambda x, y: x+y)) 392 | elif algoParam['LOSS'] == 'huber': 393 | loss = (1.0/algoParam['N'])*(trndata.map(lambda x: Huber(x, w, algoParam['MU'])).reduce(lambda x, y: x+y)) 394 | else: 395 | raise ValueError('Inconsistent LOSS function.') 396 | 397 | else: 398 | raise ValueError('Inconsistent Problem Type.') 399 | 400 | if algoParam['REG'] == 'elasticnet': 401 | z = w*algoParam['DELTA'] 402 | reg = algoParam['LAMBDA']*(algoParam['ALPHA']*norm(z, ord=1) + (1-algoParam['ALPHA'])*((norm(z, ord=2))**2)/2) 403 | elif algoParam['REG'] == 'group': 404 | Gmax = len(algoParam['G']) 405 | w_sum = 0 406 | for j in range(Gmax): 407 | gind = np.where(algoParam['DELTA'] == j)[0] 408 | w_sum += (algoParam['G'][j])*norm(w[gind], 2) 409 | reg = algoParam['LAMBDA']*w_sum 410 | else: 411 | raise ValueError('Inconsistent Regularizer') 412 | 413 | fval = loss + reg 414 | 415 | return fval 416 | 417 | 418 | ###################### PREDICTION ROUTINE ####################### 419 | def predict(tstdata, w, algoParam): 420 | """ Predict on Future Test Data 421 | 422 | Parameters 423 | ---------- 424 | tstdata : RDD 425 | RDD with each entry as numpy array [y,x] 426 | w : numpy.ndarray 427 | Weight vector [w,b] (bias term appended to end) 428 | algoParam : dict 429 | This contains the algorithm parameters for ML/ADMM algorithm. 430 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 431 | 432 | Returns 433 | ------- 434 | error_rate : numpy.float64 435 | Misclassification Error Rate (binary classification) 436 | Mean Square Error (regression) 437 | 438 | """ 439 | tstdata = tstdata.map(utils.append_one) 440 | N = tstdata.count() 441 | 442 | if algoParam['PROBLEM'] == 'binary': 443 | error_rate = (1.0/N)*tstdata.map(lambda x: abs(x[0]-sign(np.dot(x[1:], w)))/2).reduce(lambda x, y: x+y) 444 | elif algoParam['PROBLEM'] == 'regression': 445 | error_rate = (1.0/N)*tstdata.map(lambda x: (x[0]-np.dot(x[1:], w))**2).reduce(lambda x, y: x+y) 446 | else: 447 | raise ValueError('Unsupported Problem type') 448 | 449 | return error_rate 450 | -------------------------------------------------------------------------------- /admml/utils.py: -------------------------------------------------------------------------------- 1 | """This module contains various helper functions used in ADMM 2 | 3 | Copyright (c) 2017 The ADMML Authors. 4 | 5 | All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 6 | you may not use this file except in compliance with the License. 7 | You may obtain a copy of the License at : 8 | 9 | http://www.apache.org/licenses/LICENSE-2.0 10 | 11 | Unless required by applicable law or agreed to in writing, software 12 | distributed under the License is distributed on an "AS IS" BASIS, 13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | See the License for the specific language governing permissions and 15 | limitations under the License. 16 | 17 | """ 18 | 19 | import numpy as np 20 | from pyspark.mllib.stat import Statistics 21 | from pyspark.ml.linalg import Vectors 22 | from pyspark.sql import Row 23 | 24 | 25 | 26 | def rdd_to_df(line): 27 | """Converts a numpy array to Row (pyspark.sql.types.Row) 28 | 29 | Parameters 30 | ---------- 31 | line : numpy.ndarray 32 | A numpy array where the first element is the label 33 | 34 | Returns 35 | ------- 36 | pyspark.sql.types.Row 37 | A ``Row`` with label and features attributes compatible with pyspark.ml libraries 38 | 39 | """ 40 | return Row(label=float(line[0]),features=Vectors.dense(line[1:])) 41 | 42 | 43 | 44 | def df_to_rdd(line): 45 | """Converts a pyspark ``Row`` element to numpy array 46 | 47 | Parameters 48 | ---------- 49 | line : pyspark.sql.types.Row 50 | A line dataframe.rdd 51 | 52 | .. note:: 53 | 54 | The dataframe should contain only numbers. Also the method can be invoked on ``dataframe.rdd`` as ``dataFrame`` objects have no attribute 'map' 55 | 56 | Returns 57 | ------- 58 | numpy.ndarray 59 | A numpy array representation of the data contained in ``line`` 60 | 61 | """ 62 | return np.append(line.label,np.array(line.features)) 63 | 64 | 65 | def parse_vector(line): 66 | """Read a line from a CSV file into a numpy array 67 | 68 | Parameters 69 | ---------- 70 | line : str 71 | A line from a CSV file. 72 | 73 | .. note:: 74 | 75 | The CSV file should contain only numbers 76 | 77 | Returns 78 | ------- 79 | numpy.ndarray 80 | A numpy array representation of the data contained in ``line`` 81 | 82 | """ 83 | return np.fromstring(line, sep=',') 84 | 85 | 86 | def uniform_scale(vector, col_min, col_max): 87 | """Scale the features uniformly in the range of [0,1] 88 | 89 | Parameters 90 | ---------- 91 | vector : numpy.ndarray 92 | A vector (numpy array) representation of a row of the data 93 | col_min : numpy.ndarray 94 | Min values over all the columns of data 95 | col_max : numpy.ndarray 96 | Max values over all the columns of data 97 | 98 | Returns 99 | ------- 100 | numpy.ndarray 101 | Uniformly scaled representation of the vector. 102 | 103 | """ 104 | # Scale only the features 105 | return np.append(vector[0], (vector[1:]-col_min[1:])/(col_max[1:]-col_min[1:])) 106 | 107 | 108 | def normalize_scale(vector, col_mean, col_var): 109 | """Scale the features to a normal distribution 110 | 111 | Parameters 112 | ---------- 113 | vector : numpy.ndarray 114 | A vector (numpy array) representation of a row of the data 115 | col_mean : numpy.ndarray 116 | Mean over all the columns of data 117 | col_var : numpy.ndarray 118 | Variance over all the columns of data 119 | 120 | Returns 121 | ------- 122 | numpy.ndarray 123 | Normally scaled representation of the vector. 124 | 125 | """ 126 | # Scale only the features 127 | return np.append(vector[0], (vector[1:]-col_mean[1:])/np.sqrt(col_var[1:])) 128 | 129 | 130 | def log1pexpx(x): 131 | """Transformation :math:`\\mathbf{x} \\mapsto \\log(\\mathbf{1} + \\mathbf{x})` 132 | 133 | Parameters 134 | ---------- 135 | x : numpy.ndarray 136 | input 137 | 138 | Returns 139 | ------- 140 | numpy.ndarray 141 | :math:`\\log(\\mathbf{1} + \\mathbf{x})` 142 | """ 143 | y = np.exp(x) 144 | return np.log1p(y) 145 | 146 | 147 | def sigmoid(x): 148 | """Transformation to :math:`\\mathbf{x} \\mapsto sigmoid(\\mathbf{x})` 149 | 150 | Parameters 151 | ---------- 152 | x : numpy.ndarray 153 | input 154 | 155 | Returns 156 | ------- 157 | numpy.ndarray 158 | :math:`sigmoid(\\mathbf{x})` 159 | """ 160 | return np.exp(-log1pexpx(-x)) 161 | 162 | 163 | def scale_data(trndata, tstdata, algoParam): 164 | """Scales the data as specified by the ``algoParam['SCALE']``. 165 | 166 | The ``tstdata`` is scaled in the same range as ``trndata``. 167 | 168 | Parameters 169 | ---------- 170 | trndata : RDD 171 | RDD with each entry as numpy array [y,x] 172 | tstdata : RDD 173 | RDD with each entry as numpy array [y,x] 174 | algoParam : dict 175 | This contains the algorithm parameters for ML/ADMM algorithm. 176 | The default can be set as: ``algoParam = setDefaultAlgoParams()`` 177 | Here ``algoParam['SCALE']`` is either ``'Uniform'`` or ``'Normalize'`` 178 | 179 | Returns 180 | ------- 181 | trndata : RDD 182 | the scaled training data 183 | tstdata : RDD 184 | the scaled test data 185 | 186 | """ 187 | # SCALE THE DATA 188 | if algoParam['SCALE'] == 'Uniform': 189 | # Uniformly Scale in [0,1] 190 | cStats = Statistics.colStats(trndata) 191 | c_min = cStats.min() 192 | c_max = cStats.max() 193 | trndata = trndata.map(lambda x: uniform_scale(x, c_min, c_max)) 194 | tstdata = tstdata.map(lambda x: uniform_scale(x, c_min, c_max)) 195 | 196 | elif algoParam['SCALE'] == 'Normalize': 197 | cStats = Statistics.colStats(trndata) 198 | c_mean = cStats.mean() 199 | c_var = cStats.variance() 200 | trndata = trndata.map(lambda x: normalize_scale(x, c_mean, c_var)) 201 | tstdata = tstdata.map(lambda x: normalize_scale(x, c_mean, c_var)) 202 | 203 | else: 204 | print('No Scaling selected, returning original data.') 205 | 206 | return trndata, tstdata 207 | 208 | 209 | def append_one(vector): 210 | """ Appends a column of ones to the end of the vector. This takes care of bias term. 211 | 212 | Parameters 213 | ---------- 214 | vector : numpy.ndarray 215 | input 216 | 217 | Returns 218 | ------- 219 | numpy.ndarray 220 | the input vector appended with one -- [input,1] 221 | 222 | """ 223 | return np.append(vector, 1.0) 224 | 225 | 226 | def combineHv(x1, x2): 227 | """ Combine/Reduce function for the mappers 228 | 229 | Parameters 230 | ---------- 231 | x1 : list 232 | element1 233 | x2 : list 234 | element2 235 | 236 | Returns 237 | ------- 238 | tuple 239 | ``(x1[0]+x2[0], x1[1]+x2[1])`` 240 | """ 241 | return (x1[0]+x2[0], x1[1]+x2[1]) 242 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 16 | 17 | 18 | .PHONY: help 19 | help: 20 | @echo "Please use \`make ' where is one of" 21 | @echo " html to make standalone HTML files" 22 | @echo " dirhtml to make HTML files named index.html in directories" 23 | @echo " singlehtml to make a single large HTML file" 24 | @echo " pickle to make pickle files" 25 | @echo " json to make JSON files" 26 | @echo " htmlhelp to make HTML files and a HTML help project" 27 | @echo " qthelp to make HTML files and a qthelp project" 28 | @echo " applehelp to make an Apple Help Book" 29 | @echo " devhelp to make HTML files and a Devhelp project" 30 | @echo " epub to make an epub" 31 | @echo " epub3 to make an epub3" 32 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 33 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 34 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 35 | @echo " text to make text files" 36 | @echo " man to make manual pages" 37 | @echo " texinfo to make Texinfo files" 38 | @echo " info to make Texinfo files and run them through makeinfo" 39 | @echo " gettext to make PO message catalogs" 40 | @echo " changes to make an overview of all changed/added/deprecated items" 41 | @echo " xml to make Docutils-native XML files" 42 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 43 | @echo " linkcheck to check all external links for integrity" 44 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 45 | @echo " coverage to run coverage check of the documentation (if enabled)" 46 | @echo " dummy to check syntax errors of document sources" 47 | 48 | .PHONY: clean 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | .PHONY: html 53 | html: 54 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 55 | @echo 56 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 57 | 58 | .PHONY: dirhtml 59 | dirhtml: 60 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 61 | @echo 62 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 63 | 64 | .PHONY: singlehtml 65 | singlehtml: 66 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 67 | @echo 68 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 69 | 70 | .PHONY: pickle 71 | pickle: 72 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 73 | @echo 74 | @echo "Build finished; now you can process the pickle files." 75 | 76 | .PHONY: json 77 | json: 78 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 79 | @echo 80 | @echo "Build finished; now you can process the JSON files." 81 | 82 | .PHONY: htmlhelp 83 | htmlhelp: 84 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 85 | @echo 86 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 87 | ".hhp project file in $(BUILDDIR)/htmlhelp." 88 | 89 | .PHONY: qthelp 90 | qthelp: 91 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 92 | @echo 93 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 94 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 95 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/ADMML.qhcp" 96 | @echo "To view the help file:" 97 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/ADMML.qhc" 98 | 99 | .PHONY: applehelp 100 | applehelp: 101 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 102 | @echo 103 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 104 | @echo "N.B. You won't be able to view it unless you put it in" \ 105 | "~/Library/Documentation/Help or install it in your application" \ 106 | "bundle." 107 | 108 | .PHONY: devhelp 109 | devhelp: 110 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 111 | @echo 112 | @echo "Build finished." 113 | @echo "To view the help file:" 114 | @echo "# mkdir -p $$HOME/.local/share/devhelp/ADMML" 115 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/ADMML" 116 | @echo "# devhelp" 117 | 118 | .PHONY: epub 119 | epub: 120 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 121 | @echo 122 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 123 | 124 | .PHONY: epub3 125 | epub3: 126 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 127 | @echo 128 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." 129 | 130 | .PHONY: latex 131 | latex: 132 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 133 | @echo 134 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 135 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 136 | "(use \`make latexpdf' here to do that automatically)." 137 | 138 | .PHONY: latexpdf 139 | latexpdf: 140 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 141 | @echo "Running LaTeX files through pdflatex..." 142 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 143 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 144 | 145 | .PHONY: latexpdfja 146 | latexpdfja: 147 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 148 | @echo "Running LaTeX files through platex and dvipdfmx..." 149 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 150 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 151 | 152 | .PHONY: text 153 | text: 154 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 155 | @echo 156 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 157 | 158 | .PHONY: man 159 | man: 160 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 161 | @echo 162 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 163 | 164 | .PHONY: texinfo 165 | texinfo: 166 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 167 | @echo 168 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 169 | @echo "Run \`make' in that directory to run these through makeinfo" \ 170 | "(use \`make info' here to do that automatically)." 171 | 172 | .PHONY: info 173 | info: 174 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 175 | @echo "Running Texinfo files through makeinfo..." 176 | make -C $(BUILDDIR)/texinfo info 177 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 178 | 179 | .PHONY: gettext 180 | gettext: 181 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 182 | @echo 183 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 184 | 185 | .PHONY: changes 186 | changes: 187 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 188 | @echo 189 | @echo "The overview file is in $(BUILDDIR)/changes." 190 | 191 | .PHONY: linkcheck 192 | linkcheck: 193 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 194 | @echo 195 | @echo "Link check complete; look for any errors in the above output " \ 196 | "or in $(BUILDDIR)/linkcheck/output.txt." 197 | 198 | .PHONY: doctest 199 | doctest: 200 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 201 | @echo "Testing of doctests in the sources finished, look at the " \ 202 | "results in $(BUILDDIR)/doctest/output.txt." 203 | 204 | .PHONY: coverage 205 | coverage: 206 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 207 | @echo "Testing of coverage in the sources finished, look at the " \ 208 | "results in $(BUILDDIR)/coverage/python.txt." 209 | 210 | .PHONY: xml 211 | xml: 212 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 213 | @echo 214 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 215 | 216 | .PHONY: pseudoxml 217 | pseudoxml: 218 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 219 | @echo 220 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 221 | 222 | .PHONY: dummy 223 | dummy: 224 | $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy 225 | @echo 226 | @echo "Build finished. Dummy builder generates no files." 227 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | set I18NSPHINXOPTS=%SPHINXOPTS% source 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. epub3 to make an epub3 31 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 32 | echo. text to make text files 33 | echo. man to make manual pages 34 | echo. texinfo to make Texinfo files 35 | echo. gettext to make PO message catalogs 36 | echo. changes to make an overview over all changed/added/deprecated items 37 | echo. xml to make Docutils-native XML files 38 | echo. pseudoxml to make pseudoxml-XML files for display purposes 39 | echo. linkcheck to check all external links for integrity 40 | echo. doctest to run all doctests embedded in the documentation if enabled 41 | echo. coverage to run coverage check of the documentation if enabled 42 | echo. dummy to check syntax errors of document sources 43 | goto end 44 | ) 45 | 46 | if "%1" == "clean" ( 47 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 48 | del /q /s %BUILDDIR%\* 49 | goto end 50 | ) 51 | 52 | 53 | REM Check if sphinx-build is available and fallback to Python version if any 54 | %SPHINXBUILD% 1>NUL 2>NUL 55 | if errorlevel 9009 goto sphinx_python 56 | goto sphinx_ok 57 | 58 | :sphinx_python 59 | 60 | set SPHINXBUILD=python -m sphinx.__init__ 61 | %SPHINXBUILD% 2> nul 62 | if errorlevel 9009 ( 63 | echo. 64 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 65 | echo.installed, then set the SPHINXBUILD environment variable to point 66 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 67 | echo.may add the Sphinx directory to PATH. 68 | echo. 69 | echo.If you don't have Sphinx installed, grab it from 70 | echo.http://sphinx-doc.org/ 71 | exit /b 1 72 | ) 73 | 74 | :sphinx_ok 75 | 76 | 77 | if "%1" == "html" ( 78 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 79 | if errorlevel 1 exit /b 1 80 | echo. 81 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 82 | goto end 83 | ) 84 | 85 | if "%1" == "dirhtml" ( 86 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 87 | if errorlevel 1 exit /b 1 88 | echo. 89 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 90 | goto end 91 | ) 92 | 93 | if "%1" == "singlehtml" ( 94 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 95 | if errorlevel 1 exit /b 1 96 | echo. 97 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 98 | goto end 99 | ) 100 | 101 | if "%1" == "pickle" ( 102 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 103 | if errorlevel 1 exit /b 1 104 | echo. 105 | echo.Build finished; now you can process the pickle files. 106 | goto end 107 | ) 108 | 109 | if "%1" == "json" ( 110 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 111 | if errorlevel 1 exit /b 1 112 | echo. 113 | echo.Build finished; now you can process the JSON files. 114 | goto end 115 | ) 116 | 117 | if "%1" == "htmlhelp" ( 118 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 119 | if errorlevel 1 exit /b 1 120 | echo. 121 | echo.Build finished; now you can run HTML Help Workshop with the ^ 122 | .hhp project file in %BUILDDIR%/htmlhelp. 123 | goto end 124 | ) 125 | 126 | if "%1" == "qthelp" ( 127 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 128 | if errorlevel 1 exit /b 1 129 | echo. 130 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 131 | .qhcp project file in %BUILDDIR%/qthelp, like this: 132 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\ADMML.qhcp 133 | echo.To view the help file: 134 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\ADMML.ghc 135 | goto end 136 | ) 137 | 138 | if "%1" == "devhelp" ( 139 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 140 | if errorlevel 1 exit /b 1 141 | echo. 142 | echo.Build finished. 143 | goto end 144 | ) 145 | 146 | if "%1" == "epub" ( 147 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 148 | if errorlevel 1 exit /b 1 149 | echo. 150 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 151 | goto end 152 | ) 153 | 154 | if "%1" == "epub3" ( 155 | %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 156 | if errorlevel 1 exit /b 1 157 | echo. 158 | echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. 159 | goto end 160 | ) 161 | 162 | if "%1" == "latex" ( 163 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 164 | if errorlevel 1 exit /b 1 165 | echo. 166 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdf" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "latexpdfja" ( 181 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 182 | cd %BUILDDIR%/latex 183 | make all-pdf-ja 184 | cd %~dp0 185 | echo. 186 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 187 | goto end 188 | ) 189 | 190 | if "%1" == "text" ( 191 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 192 | if errorlevel 1 exit /b 1 193 | echo. 194 | echo.Build finished. The text files are in %BUILDDIR%/text. 195 | goto end 196 | ) 197 | 198 | if "%1" == "man" ( 199 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 200 | if errorlevel 1 exit /b 1 201 | echo. 202 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 203 | goto end 204 | ) 205 | 206 | if "%1" == "texinfo" ( 207 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 208 | if errorlevel 1 exit /b 1 209 | echo. 210 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 211 | goto end 212 | ) 213 | 214 | if "%1" == "gettext" ( 215 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 216 | if errorlevel 1 exit /b 1 217 | echo. 218 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 219 | goto end 220 | ) 221 | 222 | if "%1" == "changes" ( 223 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 224 | if errorlevel 1 exit /b 1 225 | echo. 226 | echo.The overview file is in %BUILDDIR%/changes. 227 | goto end 228 | ) 229 | 230 | if "%1" == "linkcheck" ( 231 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 232 | if errorlevel 1 exit /b 1 233 | echo. 234 | echo.Link check complete; look for any errors in the above output ^ 235 | or in %BUILDDIR%/linkcheck/output.txt. 236 | goto end 237 | ) 238 | 239 | if "%1" == "doctest" ( 240 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 241 | if errorlevel 1 exit /b 1 242 | echo. 243 | echo.Testing of doctests in the sources finished, look at the ^ 244 | results in %BUILDDIR%/doctest/output.txt. 245 | goto end 246 | ) 247 | 248 | if "%1" == "coverage" ( 249 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 250 | if errorlevel 1 exit /b 1 251 | echo. 252 | echo.Testing of coverage in the sources finished, look at the ^ 253 | results in %BUILDDIR%/coverage/python.txt. 254 | goto end 255 | ) 256 | 257 | if "%1" == "xml" ( 258 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 259 | if errorlevel 1 exit /b 1 260 | echo. 261 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 262 | goto end 263 | ) 264 | 265 | if "%1" == "pseudoxml" ( 266 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 267 | if errorlevel 1 exit /b 1 268 | echo. 269 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 270 | goto end 271 | ) 272 | 273 | if "%1" == "dummy" ( 274 | %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy 275 | if errorlevel 1 exit /b 1 276 | echo. 277 | echo.Build finished. Dummy builder generates no files. 278 | goto end 279 | ) 280 | 281 | :end 282 | -------------------------------------------------------------------------------- /docs/source/_static/ADMML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DL-Benchmarks/ADMML/041c259d493cbd4b31018d002b311dfb0382eea0/docs/source/_static/ADMML.png -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # ADMML documentation build configuration file, created by 4 | # sphinx-quickstart on Mon Apr 10 18:12:50 2017. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | # If extensions (or modules to document with autodoc) are in another directory, 16 | # add these directories to sys.path here. If the directory is relative to the 17 | # documentation root, use os.path.abspath to make it absolute, like shown here. 18 | # 19 | import os 20 | import sys 21 | import mock 22 | 23 | sys.path.insert(0, os.path.abspath('../..')) 24 | 25 | # modules to be mocked because the user may not have them installed 26 | MOCK_MODULES = ['pyspark', 'pyspark.ml', 'pyspark.ml.linalg', 'pyspark.mllib', 'pyspark.mllib.stat', 'pyspark.sql'] 27 | for mod_name in MOCK_MODULES: 28 | sys.modules[mod_name] = mock.Mock() 29 | 30 | # -- General configuration ------------------------------------------------ 31 | 32 | # If your documentation needs a minimal Sphinx version, state it here. 33 | # 34 | # needs_sphinx = '1.0' 35 | 36 | # Add any Sphinx extension module names here, as strings. They can be 37 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 38 | # ones. 39 | extensions = [ 40 | 'sphinx.ext.autodoc', 'numpydoc', 'sphinx.ext.autosummary', 'sphinx.ext.mathjax'] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # The suffix(es) of source filenames. 46 | # You can specify multiple suffix as a list of string: 47 | # 48 | # source_suffix = ['.rst', '.md'] 49 | source_suffix = '.rst' 50 | 51 | # The encoding of source files. 52 | # 53 | # source_encoding = 'utf-8-sig' 54 | 55 | # The master toctree document. 56 | master_doc = 'index' 57 | 58 | # General information about the project. 59 | project = u'ADMML' 60 | copyright = u'BOSCH LLC' 61 | author = u'None' 62 | 63 | # The version info for the project you're documenting, acts as replacement for 64 | # |version| and |release|, also used in various other places throughout the 65 | # built documents. 66 | # 67 | # The short X.Y version. 68 | version = u'0.1' 69 | # The full version, including alpha/beta/rc tags. 70 | release = u'0.1' 71 | 72 | # The language for content autogenerated by Sphinx. Refer to documentation 73 | # for a list of supported languages. 74 | # 75 | # This is also used if you do content translation via gettext catalogs. 76 | # Usually you set "language" from the command line for these cases. 77 | language = None 78 | 79 | # There are two options for replacing |today|: either, you set today to some 80 | # non-false value, then it is used: 81 | # 82 | # today = '' 83 | # 84 | # Else, today_fmt is used as the format for a strftime call. 85 | # 86 | # today_fmt = '%B %d, %Y' 87 | 88 | # List of patterns, relative to source directory, that match files and 89 | # directories to ignore when looking for source files. 90 | # This patterns also effect to html_static_path and html_extra_path 91 | exclude_patterns = [] 92 | 93 | # The reST default role (used for this markup: `text`) to use for all 94 | # documents. 95 | # 96 | # default_role = None 97 | 98 | # If true, '()' will be appended to :func: etc. cross-reference text. 99 | # 100 | # add_function_parentheses = True 101 | 102 | # If true, the current module name will be prepended to all description 103 | # unit titles (such as .. function::). 104 | # 105 | # add_module_names = True 106 | 107 | # If true, sectionauthor and moduleauthor directives will be shown in the 108 | # output. They are ignored by default. 109 | # 110 | # show_authors = False 111 | 112 | # The name of the Pygments (syntax highlighting) style to use. 113 | pygments_style = 'sphinx' 114 | 115 | # A list of ignored prefixes for module index sorting. 116 | # modindex_common_prefix = [] 117 | 118 | # If true, keep warnings as "system message" paragraphs in the built documents. 119 | # keep_warnings = False 120 | 121 | # If true, `todo` and `todoList` produce output, else they produce nothing. 122 | todo_include_todos = False 123 | 124 | 125 | # -- Options for HTML output ---------------------------------------------- 126 | 127 | # The theme to use for HTML and HTML Help pages. See the documentation for 128 | # a list of builtin themes. 129 | # 130 | #html_theme = 'alabaster' 131 | import sphinx_rtd_theme 132 | html_theme = "sphinx_rtd_theme" 133 | 134 | # Theme options are theme-specific and customize the look and feel of a theme 135 | # further. For a list of options available for each theme, see the 136 | # documentation. 137 | # 138 | # html_theme_options = {} 139 | 140 | # Add any paths that contain custom themes here, relative to this directory. 141 | # html_theme_path = [] 142 | 143 | # The name for this set of Sphinx documents. 144 | # " v documentation" by default. 145 | # 146 | # html_title = u'ADMML v0.1' 147 | 148 | # A shorter title for the navigation bar. Default is the same as html_title. 149 | # 150 | # html_short_title = None 151 | 152 | # The name of an image file (relative to this directory) to place at the top 153 | # of the sidebar. 154 | # 155 | html_logo = './_static/ADMML.png' 156 | 157 | # The name of an image file (relative to this directory) to use as a favicon of 158 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 159 | # pixels large. 160 | # 161 | # html_favicon = None 162 | 163 | # Add any paths that contain custom static files (such as style sheets) here, 164 | # relative to this directory. They are copied after the builtin static files, 165 | # so a file named "default.css" will overwrite the builtin "default.css". 166 | html_static_path = ['_static'] 167 | 168 | # Add any extra paths that contain custom files (such as robots.txt or 169 | # .htaccess) here, relative to this directory. These files are copied 170 | # directly to the root of the documentation. 171 | # 172 | # html_extra_path = [] 173 | 174 | # If not None, a 'Last updated on:' timestamp is inserted at every page 175 | # bottom, using the given strftime format. 176 | # The empty string is equivalent to '%b %d, %Y'. 177 | # 178 | # html_last_updated_fmt = None 179 | 180 | # If true, SmartyPants will be used to convert quotes and dashes to 181 | # typographically correct entities. 182 | # 183 | # html_use_smartypants = True 184 | 185 | # Custom sidebar templates, maps document names to template names. 186 | # 187 | # html_sidebars = {} 188 | 189 | # Additional templates that should be rendered to pages, maps page names to 190 | # template names. 191 | # 192 | # html_additional_pages = {} 193 | 194 | # If false, no module index is generated. 195 | # 196 | # html_domain_indices = True 197 | 198 | # If false, no index is generated. 199 | # 200 | # html_use_index = True 201 | 202 | # If true, the index is split into individual pages for each letter. 203 | # 204 | # html_split_index = False 205 | 206 | # If true, links to the reST sources are added to the pages. 207 | # 208 | # html_show_sourcelink = True 209 | 210 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 211 | # 212 | # html_show_sphinx = True 213 | 214 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 215 | # 216 | # html_show_copyright = True 217 | 218 | # If true, an OpenSearch description file will be output, and all pages will 219 | # contain a tag referring to it. The value of this option must be the 220 | # base URL from which the finished HTML is served. 221 | # 222 | # html_use_opensearch = '' 223 | 224 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 225 | # html_file_suffix = None 226 | 227 | # Language to be used for generating the HTML full-text search index. 228 | # Sphinx supports the following languages: 229 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 230 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' 231 | # 232 | # html_search_language = 'en' 233 | 234 | # A dictionary with options for the search language support, empty by default. 235 | # 'ja' uses this config value. 236 | # 'zh' user can custom change `jieba` dictionary path. 237 | # 238 | # html_search_options = {'type': 'default'} 239 | 240 | # The name of a javascript file (relative to the configuration directory) that 241 | # implements a search results scorer. If empty, the default will be used. 242 | # 243 | # html_search_scorer = 'scorer.js' 244 | 245 | # Output file base name for HTML help builder. 246 | htmlhelp_basename = 'ADMMLdoc' 247 | 248 | # -- Options for LaTeX output --------------------------------------------- 249 | 250 | latex_elements = { 251 | # The paper size ('letterpaper' or 'a4paper'). 252 | # 253 | # 'papersize': 'letterpaper', 254 | 255 | # The font size ('10pt', '11pt' or '12pt'). 256 | # 257 | # 'pointsize': '10pt', 258 | 259 | # Additional stuff for the LaTeX preamble. 260 | # 261 | # 'preamble': '', 262 | 263 | # Latex figure (float) alignment 264 | # 265 | # 'figure_align': 'htbp', 266 | } 267 | 268 | # Grouping the document tree into LaTeX files. List of tuples 269 | # (source start file, target name, title, 270 | # author, documentclass [howto, manual, or own class]). 271 | latex_documents = [ 272 | (master_doc, 'ADMML.tex', u'ADMML Documentation', 273 | u'Sauptik Dhar', 'manual'), 274 | ] 275 | 276 | # The name of an image file (relative to this directory) to place at the top of 277 | # the title page. 278 | # 279 | # latex_logo = None 280 | 281 | # For "manual" documents, if this is true, then toplevel headings are parts, 282 | # not chapters. 283 | # 284 | # latex_use_parts = False 285 | 286 | # If true, show page references after internal links. 287 | # 288 | # latex_show_pagerefs = False 289 | 290 | # If true, show URL addresses after external links. 291 | # 292 | # latex_show_urls = False 293 | 294 | # Documents to append as an appendix to all manuals. 295 | # 296 | # latex_appendices = [] 297 | 298 | # It false, will not define \strong, \code, itleref, \crossref ... but only 299 | # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added 300 | # packages. 301 | # 302 | # latex_keep_old_macro_names = True 303 | 304 | # If false, no module index is generated. 305 | # 306 | # latex_domain_indices = True 307 | 308 | 309 | # -- Options for manual page output --------------------------------------- 310 | 311 | # One entry per manual page. List of tuples 312 | # (source start file, name, description, authors, manual section). 313 | man_pages = [ 314 | (master_doc, 'admml', u'ADMML Documentation', 315 | [author], 1) 316 | ] 317 | 318 | # If true, show URL addresses after external links. 319 | # 320 | # man_show_urls = False 321 | 322 | 323 | # -- Options for Texinfo output ------------------------------------------- 324 | 325 | # Grouping the document tree into Texinfo files. List of tuples 326 | # (source start file, target name, title, author, 327 | # dir menu entry, description, category) 328 | texinfo_documents = [ 329 | (master_doc, 'ADMML', u'ADMML Documentation', 330 | author, 'ADMML', 'One line description of project.', 331 | 'Miscellaneous'), 332 | ] 333 | 334 | # Documents to append as an appendix to all manuals. 335 | # 336 | # texinfo_appendices = [] 337 | 338 | # If false, no module index is generated. 339 | # 340 | # texinfo_domain_indices = True 341 | 342 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 343 | # 344 | # texinfo_show_urls = 'footnote' 345 | 346 | # If true, do not generate a @detailmenu in the "Top" node's menu. 347 | # 348 | # texinfo_no_detailmenu = False 349 | -------------------------------------------------------------------------------- /docs/source/include_readme.rst: -------------------------------------------------------------------------------- 1 | .. _readme: 2 | 3 | .. include:: ../../README.rst 4 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. ADMML documentation master file, created by 2 | sphinx-quickstart on Mon Apr 10 18:12:50 2017. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | 7 | ADMML documentation 8 | =================== 9 | 10 | .. toctree:: 11 | :hidden: 12 | 13 | self 14 | 15 | 16 | 17 | ***************** 18 | Table of Contents 19 | ***************** 20 | 21 | .. toctree:: 22 | :maxdepth: 1 23 | 24 | include_readme.rst 25 | admml.rst 26 | 27 | 28 | 29 | Indices and tables 30 | ================== 31 | 32 | * :ref:`genindex` 33 | * :ref:`modindex` 34 | * :ref:`search` 35 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from setuptools import setup 4 | 5 | 6 | if __name__ == '__main__': 7 | setup( 8 | name="admml", 9 | version="0.1", 10 | description=("ADMML"), 11 | license="Apache 2.0", 12 | url="https://github.com/DL-Benchmarks/ADMML", 13 | packages=['admml'], 14 | ) 15 | --------------------------------------------------------------------------------